+ FD_ZERO( &fdset );
+ FD_SET(fd, &fdset);
+ FD_SET(fd_err, &fdset);
+
+ /* Determine the highest file descriptor */
+ highest_fd = (fd > fd_err) ? fd : fd_err;
+
+ /* We use a copy of fdset, as select modifies it */
+ copy = fdset;
+
+ while (select(highest_fd + 1, ©, NULL, NULL, NULL ) > 0)
+ {
+ int len;
+
+ if (FD_ISSET(fd, ©))
+ {
+ char *pnl;
+
+ len = read(fd, pbuffer, sizeof(buffer) - 1 - (pbuffer - buffer));
+
+ if (len < 0)
+ {
+ if (errno == EAGAIN || errno == EINTR) continue;
+ break;
+ }
+ else if (len == 0) break; /* We've reached EOF */
+
+ pbuffer[len] = '\0';
+
+ len += pbuffer - buffer;
+ pbuffer = buffer;
+
+ while ((pnl = strchr(pbuffer, '\n')))
+ {
+ *pnl = '\0';
+ if (*(pnl-1) == '\r' ) *(pnl-1) = '\0';
+
+ parse_line (pbuffer);
+
+ pbuffer = ++pnl;
+ }
+ /* not completely read ? */
+ if (pbuffer - buffer < len)
+ {
+ len -= pbuffer - buffer;
+ memmove(buffer, pbuffer, len);
+ pbuffer = buffer + len;
+ }
+ else
+ pbuffer = buffer;
+ }
+ else if (FD_ISSET(fd_err, ©))
+ {
+ char *pnl;
+
+ len = read(fd_err, pbuffer_err, sizeof(buffer_err) - 1 - (pbuffer_err - buffer_err));
+
+ if (len < 0)
+ {
+ if (errno == EAGAIN || errno == EINTR) continue;
+ break;
+ }
+ else if (len == 0) break; /* We've reached EOF */
+
+ pbuffer_err[len] = '\0';
+
+ len += pbuffer_err - buffer_err;
+ pbuffer_err = buffer_err;
+
+ while ((pnl = strchr(pbuffer_err, '\n')))
+ {
+ *pnl = '\0';
+ if (*(pnl-1) == '\r' ) *(pnl-1) = '\0';
+
+ ERROR ("exec plugin: exec_read_one: error = %s", pbuffer_err);
+
+ pbuffer_err = ++pnl;
+ }
+ /* not completely read ? */
+ if (pbuffer_err - buffer_err < len)
+ {
+ len -= pbuffer_err - buffer_err;
+ memmove(buffer_err, pbuffer_err, len);
+ pbuffer_err = buffer_err + len;
+ }
+ else
+ pbuffer_err = buffer_err;
+ }
+ /* reset copy */
+ copy = fdset;
+ }
+
+ if (waitpid (pl->pid, &status, 0) > 0)
+ pl->status = status;
+
+ DEBUG ("exec plugin: Child %i exited with status %i.",
+ (int) pl->pid, pl->status);
+
+ pl->pid = 0;
+
+ pthread_mutex_lock (&pl_lock);
+ pl->flags &= ~PL_RUNNING;
+ pthread_mutex_unlock (&pl_lock);
+
+ close (fd);
+ close (fd_err);
+
+ pthread_exit ((void *) 0);
+ return (NULL);
+} /* void *exec_read_one }}} */
+
+static void *exec_notification_one (void *arg) /* {{{ */
+{
+ program_list_t *pl = ((program_list_and_notification_t *) arg)->pl;
+ const notification_t *n = &((program_list_and_notification_t *) arg)->n;
+ int fd;
+ FILE *fh;
+ int pid;
+ int status;
+ const char *severity;
+
+ pid = fork_child (pl, &fd, NULL, NULL);
+ if (pid < 0) {
+ sfree (arg);
+ pthread_exit ((void *) 1);
+ }
+
+ fh = fdopen (fd, "w");