Glib docs recommend using the slice API if you know you won't need to realloc.
[metze/wireshark/wip.git] / capture_sync.c
index d7afd422d107dbc290da4b3a026dfb3ce1fb4d68..51c74bc13b4f632a76d9f98945b09622efd8a3c0 100644 (file)
@@ -115,7 +115,7 @@ static const char *sync_pipe_signame(int);
 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
-static int pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
+static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
                            char **err_msg);
 
 
@@ -129,7 +129,7 @@ sync_pipe_add_arg(const char **args, int *argc, const char *arg)
        pointers, *not* counting the NULL pointer at the end, so we have
        to add 2 in order to get the new size of the array, including the
        new pointer and the terminating NULL pointer. */
-    args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
+    args = (const char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
 
     /* Stuff the pointer into the penultimate element of the array, which
        is the one at the index specified by "*argc". */
@@ -302,7 +302,7 @@ init_pipe_args(int *argc) {
     /* Allocate the string pointer array with enough space for the
        terminating NULL pointer. */
     *argc = 0;
-    argv = g_malloc(sizeof (char *));
+    argv = (const char **)g_malloc(sizeof (char *));
     *argv = NULL;
 
     /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
@@ -430,6 +430,10 @@ sync_pipe_start(capture_options *capture_opts) {
         argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
     }
 
+    if (capture_opts->group_read_access) {
+        argv = sync_pipe_add_arg(argv, &argc, "-g");
+    }
+
     for (j = 0; j < capture_opts->ifaces->len; j++) {
         interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
 
@@ -457,7 +461,7 @@ sync_pipe_start(capture_options *capture_opts) {
         }
 
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        if (interface_opts.buffer_size != 1) {
+        if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
             argv = sync_pipe_add_arg(argv, &argc, "-B");
             g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
             argv = sync_pipe_add_arg(argv, &argc, buffer_size);
@@ -620,7 +624,7 @@ sync_pipe_start(capture_options *capture_opts) {
          */
         dup2(sync_pipe[PIPE_WRITE], 2);
         ws_close(sync_pipe[PIPE_READ]);
-        execv(argv[0], (gpointer)argv);
+        execv(argv[0], (char * const*)argv);
         g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
                    argv[0], g_strerror(errno));
         sync_pipe_errmsg_to_parent(2, errmsg, "");
@@ -846,7 +850,7 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
         dup2(sync_pipe[PIPE_WRITE], 2);
         ws_close(sync_pipe[PIPE_READ]);
         ws_close(sync_pipe[PIPE_WRITE]);
-        execv(argv[0], (gpointer)argv);
+        execv(argv[0], (char * const*)argv);
         g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
                    argv[0], g_strerror(errno));
         sync_pipe_errmsg_to_parent(2, errmsg, "");
@@ -945,7 +949,7 @@ sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
     int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
     char *wait_msg;
     gchar buffer[PIPE_BUF_SIZE+1];
-    int  nread;
+    ssize_t nread;
     char indicator;
     int  primary_msg_len;
     char *primary_msg_text;
@@ -953,7 +957,7 @@ sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
     char *secondary_msg_text;
     char *combined_msg;
     GString *data_buf = NULL;
-    int count;
+    ssize_t count;
 
     ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
                                  &fork_child, &msg);
@@ -1017,10 +1021,10 @@ sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
          */
 
         /* convert primary message */
-        pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
+        pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
         primary_msg_text = buffer+4;
         /* convert secondary message */
-        pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
+        pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
                             &secondary_msg_len);
         secondary_msg_text = primary_msg_text + primary_msg_len + 4;
         /* the capture child will close the sync_pipe, nothing to do */
@@ -1111,7 +1115,7 @@ sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
 }
 
 int
-sync_interface_set_80211_chan(gchar *iface, char *freq, gchar *type,
+sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
                               gchar **data, gchar **primary_msg,
                               gchar **secondary_msg)
 {
@@ -1258,7 +1262,7 @@ sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
     int message_read_fd, ret;
     char *wait_msg;
     gchar buffer[PIPE_BUF_SIZE+1];
-    int  nread;
+    ssize_t nread;
     char indicator;
     int  primary_msg_len;
     char *primary_msg_text;
@@ -1339,10 +1343,10 @@ sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
          */
 
         /* convert primary message */
-        pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
+        pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
         primary_msg_text = buffer+4;
         /* convert secondary message */
-        pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
+        pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
                             &secondary_msg_len);
         /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
         /* the capture child will close the sync_pipe, nothing to do */
@@ -1400,16 +1404,23 @@ sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
 int
 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
 {
+#ifndef _WIN32
+    /*
+     * Don't bother waiting for the child. sync_pipe_close_command
+     * does this for us on Windows.
+     */
+    sync_pipe_kill(*fork_child);
+#endif
     return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
 }
 
 /* read a number of bytes from a pipe */
 /* (blocks until enough bytes read or an error occurs) */
-static int
+static ssize_t
 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
 {
-    int newly;
-    int offset = 0;
+    ssize_t newly;
+    ssize_t offset = 0;
     int error;
 
     while(required) {
@@ -1432,7 +1443,7 @@ pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
             return newly;
         }
 
-        required -= newly;
+        required -= (int)newly;
         offset += newly;
     }
 
@@ -1473,7 +1484,7 @@ static gboolean pipe_data_available(int pipe_fd) {
 /* Read a line from a pipe, similar to fgets */
 int
 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
-    int newly;
+    ssize_t newly;
     int offset = -1;
 
     while(offset < max - 1) {
@@ -1484,11 +1495,11 @@ sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
         if (newly == 0) {
             /* EOF - not necessarily an error */
             break;
-        } else if (newly < 0) {
+        } else if (newly == -1) {
             /* error */
             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
                   "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
-            return newly;
+            return -1;
         } else if (bytes[offset] == '\n') {
             break;
         }
@@ -1509,19 +1520,19 @@ pipe_convert_header(const guchar *header, int header_len, char *indicator, int *
 
     /* convert header values */
     *indicator = header[0];
-    *block_len = header[1]<<16 | header[2]<<8 | header[3];
+    *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
 }
 
 /* read a message from the sending pipe in the standard format
    (1-byte message indicator, 3-byte message length (excluding length
    and indicator field), and the rest is the message) */
-static int
+static ssize_t
 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
                 char **err_msg)
 {
     int required;
-    int newly;
-    guchar header[4];
+    ssize_t newly;
+    gchar header[4];
 
     /* read header (indicator and 3-byte length) */
     newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
@@ -1537,19 +1548,19 @@ pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
             return 0;
         }
         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
-              "read %d failed to read header: %u", pipe_fd, newly);
+              "read %d failed to read header: %lu", pipe_fd, (long)newly);
         if (newly != -1) {
             /*
              * Short read, but not an immediate EOF.
              */
-            *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
-                                       newly);
+            *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
+                                       (long)newly);
         }
         return -1;
     }
 
     /* convert header values */
-    pipe_convert_header(header, 4, indicator, &required);
+    pipe_convert_header((guchar*)header, 4, indicator, &required);
 
     /* only indicator with no value? */
     if(required == 0) {
@@ -1568,6 +1579,10 @@ pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
         /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
         memcpy(msg, header, sizeof(header));
         newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
+       if (newly < 0) { /* error */
+           g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
+                 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
+       }
         *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
                                    msg);
         return -1;
@@ -1602,13 +1617,14 @@ sync_pipe_input_cb(gint source, gpointer user_data)
     capture_options *capture_opts = (capture_options *)user_data;
     int  ret;
     char buffer[SP_MAX_MSG_LEN+1];
-    int  nread;
+    ssize_t nread;
     char indicator;
     int  primary_len;
     char *primary_msg;
     int  secondary_len;
     char *secondary_msg;
     char *wait_msg, *combined_msg;
+    int npackets;
 
     nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
                             &primary_msg);
@@ -1686,16 +1702,16 @@ sync_pipe_input_cb(gint source, gpointer user_data)
         }
         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);
-        capture_input_new_packets(capture_opts, nread);
+        npackets = atoi(buffer);
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
+        capture_input_new_packets(capture_opts, npackets);
         break;
     case SP_ERROR_MSG:
         /* convert primary message */
-        pipe_convert_header(buffer, 4, &indicator, &primary_len);
+        pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
         primary_msg = buffer+4;
         /* convert secondary message */
-        pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
+        pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
         secondary_msg = primary_msg + primary_len + 4;
         /* message output */
         capture_input_error_message(capture_opts, primary_msg, secondary_msg);
@@ -1704,12 +1720,12 @@ sync_pipe_input_cb(gint source, gpointer user_data)
         break;
     case SP_BAD_FILTER: {
         char *ch;
-        int index;
+        int indx;
 
         ch = strtok(buffer, ":");
-        index = (int)strtol(ch, NULL, 10);
+        indx = (int)strtol(ch, NULL, 10);
         ch = strtok(NULL, ":");
-        capture_input_cfilter_error_message(capture_opts, index, ch);
+        capture_input_cfilter_error_message(capture_opts, indx, ch);
          /* the capture child will close the sync_pipe, nothing to do for now */
          break;
         }
@@ -1738,6 +1754,15 @@ sync_pipe_wait_for_child(int fork_child, gchar **msgp)
 {
     int fork_child_status;
     int ret;
+    GTimeVal start_time;
+    GTimeVal end_time;
+    float elapsed;
+
+    /*
+     * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
+     * replace this
+     */
+    g_get_current_time(&start_time);
 
     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
     g_assert(fork_child != -1);
@@ -1792,7 +1817,10 @@ sync_pipe_wait_for_child(int fork_child, gchar **msgp)
     }
 #endif
 
-    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
+    g_get_current_time(&end_time);
+    elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
+                       ((end_time.tv_usec - start_time.tv_usec) / 1e6));
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
     return ret;
 }