2 * Pipe input routines. Declared in pipe_input.h
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "pipe_input.h"
40 typedef struct pipe_input_tag {
44 pipe_input_cb_t input_cb;
54 /* The timer has expired, see if there's stuff to read from the pipe,
55 if so, do the callback */
57 pipe_timer_cb(gpointer data)
61 gboolean result, result1;
63 pipe_input_t *pipe_input = data;
67 /* try to read data from the pipe only 5 times, to avoid blocking */
68 while(iterations < 5) {
69 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: new iteration");*/
71 /* Oddly enough although Named pipes don't work on win9x,
72 PeekNamedPipe does !!! */
73 handle = (HANDLE) _get_osfhandle (pipe_input->source);
74 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
76 /* Get the child process exit status */
77 result1 = GetExitCodeProcess((HANDLE)*(pipe_input->child_process),
80 /* If the Peek returned an error, or there are bytes to be read
81 or the childwatcher thread has terminated then call the normal
83 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
85 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: data avail");*/
87 if(pipe_input->pipe_input_id != 0) {
88 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: stop timer");*/
89 /* avoid reentrancy problems and stack overflow */
90 g_source_remove(pipe_input->pipe_input_id);
91 pipe_input->pipe_input_id = 0;
94 /* And call the real handler */
95 if (!pipe_input->input_cb(pipe_input->source, pipe_input->user_data)) {
96 g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
97 /* pipe closed, return false so that the old timer is not run again */
102 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: no data avail");*/
103 /* No data, stop now */
110 if(pipe_input->pipe_input_id == 0) {
111 /* restore pipe handler */
112 pipe_input->pipe_input_id = g_timeout_add(200, pipe_timer_cb, data);
113 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: finished with iterations: %u, new timer", iterations);*/
115 /* Return false so that the old timer is not run again */
118 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: finished with iterations: %u, old timer", iterations);*/
120 /* we didn't stopped the old timer, so let it run */
127 /* There's stuff to read from the sync pipe, meaning the child has sent
128 us a message, or the sync pipe has closed, meaning the child has
129 closed it (perhaps because it exited). */
131 pipe_input_cb(GIOChannel *source _U_, GIOCondition condition _U_,
134 pipe_input_t *pipe_input = data;
137 /* avoid reentrancy problems and stack overflow */
138 g_source_remove(pipe_input->pipe_input_id);
140 if (pipe_input->input_cb(pipe_input->source, pipe_input->user_data)) {
141 /* restore pipe handler */
142 pipe_input->pipe_input_id = g_io_add_watch_full (pipe_input->channel,
144 G_IO_IN|G_IO_ERR|G_IO_HUP,
153 void pipe_input_set_handler(gint source, gpointer user_data, int *child_process, pipe_input_cb_t input_cb)
155 static pipe_input_t pipe_input;
157 pipe_input.source = source;
158 pipe_input.child_process = child_process;
159 pipe_input.user_data = user_data;
160 pipe_input.input_cb = input_cb;
163 /* Tricky to use pipes in win9x, as no concept of wait. NT can
164 do this but that doesn't cover all win32 platforms. GTK can do
165 this but doesn't seem to work over processes. Attempt to do
166 something similar here, start a timer and check for data on every
168 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_input_set_handler: new");*/
169 pipe_input.pipe_input_id = g_timeout_add(200, pipe_timer_cb, &pipe_input);
171 pipe_input.channel = g_io_channel_unix_new(source);
172 g_io_channel_set_encoding(pipe_input.channel, NULL, NULL);
173 pipe_input.pipe_input_id = g_io_add_watch_full(pipe_input.channel,
175 G_IO_IN|G_IO_ERR|G_IO_HUP,
182 #endif /* HAVE_LIBPCAP */