summaryrefslogtreecommitdiff
path: root/capture_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'capture_sync.c')
-rw-r--r--capture_sync.c89
1 files changed, 59 insertions, 30 deletions
diff --git a/capture_sync.c b/capture_sync.c
index 2a34f79375..45dc5ff7d4 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -120,25 +120,42 @@ static void sync_pipe_wait_for_child(capture_options *capture_opts);
#define SP_MAX_MSG_LEN 4096
- /* write a message to the recipient pipe in the standard format
+/* write a message to the recipient pipe in the standard format
(3 digit message length (excluding length and indicator field),
- 1 byte message indicator and the rest is the message) */
+ 1 byte message indicator and the rest is the message).
+ If msg is NULL, the message has only a length and indicator.
+ Otherwise, if secondary_msg isn't NULL, send both msg and
+ secondary_msg as null-terminated strings, otherwise just send
+ msg as a null-terminated string and follow it with an empty string. */
static void
-pipe_write_block(int pipe, char indicator, int len, const char *msg)
+pipe_write_block(int pipe, char indicator, const char *msg,
+ const char *secondary_msg)
{
guchar header[3+1]; /* indicator + 3-byte len */
int ret;
+ size_t len, secondary_len, total_len;
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d enter", pipe);
+ len = 0;
+ secondary_len = 0;
+ total_len = 0;
+ if(msg != NULL) {
+ len = strlen(msg) + 1; /* include the terminating '\0' */
+ total_len = len;
+ if(secondary_msg == NULL)
+ secondary_msg = ""; /* default to an empty string */
+ secondary_len = strlen(secondary_msg) + 1;
+ total_len += secondary_len;
+ }
g_assert(indicator < '0' || indicator > '9');
- g_assert(len <= SP_MAX_MSG_LEN);
+ g_assert(total_len <= SP_MAX_MSG_LEN);
/* write header (indicator + 3-byte len) */
header[0] = indicator;
- header[1] = (len >> 16) & 0xFF;
- header[2] = (len >> 8) & 0xFF;
- header[3] = (len >> 0) & 0xFF;
+ header[1] = (total_len >> 16) & 0xFF;
+ header[2] = (total_len >> 8) & 0xFF;
+ header[3] = (total_len >> 0) & 0xFF;
ret = write(pipe, header, sizeof header);
if(ret == -1) {
@@ -150,14 +167,21 @@ pipe_write_block(int pipe, char indicator, int len, const char *msg)
/* write value (if we have one) */
if(len) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
- "write %d indicator: %c value len: %u msg: %s", pipe, indicator,
- len, msg);
+ "write %d indicator: %c value len: %lu msg: \"%s\" secondary len: %lu secondary msg: \"%s\"", pipe, indicator,
+ (unsigned long)len, msg, (unsigned long)secondary_len,
+ secondary_msg);
ret = write(pipe, msg, len);
if(ret == -1) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
"write %d value: error %s", pipe, strerror(errno));
return;
}
+ ret = write(pipe, msg, secondary_len);
+ if(ret == -1) {
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
+ "write %d value: error %s", pipe, strerror(errno));
+ return;
+ }
} else {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
"write %d indicator: %c no value", pipe, indicator);
@@ -169,11 +193,12 @@ pipe_write_block(int pipe, char indicator, int len, const char *msg)
#ifndef _WIN32
void
-sync_pipe_errmsg_to_parent(const char *errmsg)
+sync_pipe_errmsg_to_parent(const char *error_msg,
+ const char *secondary_error_msg)
{
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", error_msg);
- pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
+ pipe_write_block(1, SP_ERROR_MSG, error_msg, secondary_error_msg);
}
#endif
@@ -185,7 +210,7 @@ signal_pipe_capquit_to_child(capture_options *capture_opts)
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
- pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, 0, NULL);
+ pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, NULL, NULL);
}
#endif
@@ -602,7 +627,7 @@ sync_pipe_start(capture_options *capture_opts) {
execv(exename, argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
exename, strerror(errno));
- sync_pipe_errmsg_to_parent(errmsg);
+ sync_pipe_errmsg_to_parent(errmsg, NULL);
/* Exit with "_exit()", so that we don't close the connection
to the X server (and cause stuff buffered up by our parent but
@@ -694,21 +719,21 @@ sync_pipe_input_cb(gint source, gpointer user_data)
switch(indicator) {
case SP_FILE:
- if(!capture_input_new_file(capture_opts, buffer)) {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
-
- /* We weren't able to open the new capture file; user has been
- alerted. Close the sync pipe. */
- eth_close(source);
-
- /* the child has send us a filename which we couldn't open.
- this probably means, the child is creating files faster than we can handle it.
- this should only be the case for very fast file switches
- we can't do much more than telling the child to stop
- (this is the "emergency brake" if user e.g. wants to switch files every second) */
- sync_pipe_stop(capture_opts);
- }
- break;
+ if(!capture_input_new_file(capture_opts, buffer)) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
+
+ /* We weren't able to open the new capture file; user has been
+ alerted. Close the sync pipe. */
+ eth_close(source);
+
+ /* the child has send us a filename which we couldn't open.
+ this probably means, the child is creating files faster than we can handle it.
+ this should only be the case for very fast file switches
+ we can't do much more than telling the child to stop
+ (this is the "emergency brake" if user e.g. wants to switch files every second) */
+ sync_pipe_stop(capture_opts);
+ }
+ break;
case SP_PACKET_COUNT:
nread = atoi(buffer);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
@@ -718,11 +743,15 @@ sync_pipe_input_cb(gint source, gpointer user_data)
capture_input_error_message(capture_opts, buffer);
/* the capture child will close the sync_pipe, nothing to do for now */
break;
+ case SP_BAD_FILTER:
+ capture_input_cfilter_error_message(capture_opts, buffer);
+ /* the capture child will close the sync_pipe, nothing to do for now */
+ break;
case SP_DROPS:
capture_input_drops(capture_opts, atoi(buffer));
break;
default:
- g_assert_not_reached();
+ g_assert_not_reached();
}
return TRUE;