+static void
+handle_filter_stderr(
+ void *cookie)
+{
+ filter_t *filter = cookie;
+ ssize_t nread;
+ char *b, *p;
+ gint64 len;
+
+ event_release(filter->event);
+
+ if (filter->buffer == NULL) {
+ /* allocate initial buffer */
+ filter->buffer = g_malloc(2048);
+ filter->first = 0;
+ filter->size = 0;
+ filter->allocated_size = 2048;
+ } else if (filter->first > 0) {
+ if (filter->allocated_size - filter->size - filter->first < 1024) {
+ memmove(filter->buffer, filter->buffer + filter->first,
+ filter->size);
+ filter->first = 0;
+ }
+ } else if (filter->allocated_size - filter->size < 1024) {
+ /* double the size of the buffer */
+ filter->allocated_size *= 2;
+ filter->buffer = g_realloc(filter->buffer, filter->allocated_size);
+ }
+
+ nread = read(filter->fd, filter->buffer + filter->first + filter->size,
+ filter->allocated_size - filter->first - filter->size - 2);
+
+ if (nread != 0) {
+ dump_result = max(dump_result, 2);
+ }
+
+ if (nread <= 0) {
+ aclose(filter->fd);
+ if (filter->size > 0 && filter->buffer[filter->first + filter->size - 1] != '\n') {
+ /* Add a '\n' at end of buffer */
+ filter->buffer[filter->first + filter->size] = '\n';
+ filter->size++;
+ }
+ } else {
+ filter->size += nread;
+ }
+
+ /* process all complete lines */
+ b = filter->buffer + filter->first;
+ filter->buffer[filter->first + filter->size] = '\0';
+ while (b < filter->buffer + filter->first + filter->size &&
+ (p = strchr(b, '\n')) != NULL) {
+ *p = '\0';
+ g_fprintf(errf, _("? %s: %s\n"), filter->name, b);
+ if (errstr == NULL) {
+ errstr = stralloc(b);
+ }
+ len = p - b + 1;
+ filter->first += len;
+ filter->size -= len;
+ b = p + 1;
+ }
+
+ if (nread <= 0) {
+ g_free(filter->buffer);
+ g_free(filter);
+ } else {
+ filter->event = event_register((event_id_t)filter->fd, EV_READFD,
+ handle_filter_stderr, filter);
+ }
+}
+