new->pid = pid;
new->callback = func;
new->data = data;
- new->finished = 0;
new->prev = NULL;
new->next = children;
if(children != NULL)
static void handler(int signum)
{
- pid_t pid;
- int status;
- struct child *child;
FILE *dumpfile;
extern int numfnetnodes, numtransfers, numdcpeers;
running = 0;
break;
case SIGCHLD:
- while((pid = waitpid(-1, &status, WNOHANG)) > 0)
- {
- for(child = children; child != NULL; child = child->next)
- {
- if(child->pid == pid)
- {
- child->finished = 1;
- child->status = status;
- }
- }
- childrendone = 1;
- }
+ childrendone = 1;
break;
case SIGUSR1:
flog(LOG_NOTICE, "forking and dumping core upon SIGUSR1");
}
}
+static void checkchildren(void)
+{
+ pid_t pid;
+ int status;
+ struct child *child;
+
+ while((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ for(child = children; child != NULL; child = child->next)
+ {
+ if(child->pid == pid)
+ {
+ child->callback(pid, status, child->data);
+ if(child == children)
+ children = child->next;
+ if(child->prev != NULL)
+ child->prev->next = child->next;
+ if(child->next != NULL)
+ child->next->prev = child->prev;
+ free(child);
+ break;
+ }
+ }
+ }
+}
+
pid_t forksess(uid_t user, struct authhandle *auth, void (*ccbfunc)(pid_t, int, void *), void *data, ...)
{
int i, o;
int delay, immsyslog;
struct module *mod;
struct timer *timer;
- struct child *child;
double now;
now = ntime();
delay = (int)((timer->at - now) * 1000.0);
}
}
+ /* Of course, there's a race condition here that should be
+ * solved with pselect, but it doesn't matter a lot. */
if(childrendone)
- {
delay = 0;
- childrendone = 0;
- }
pollsocks(delay);
now = ntime();
do
break;
}
} while(timer != NULL);
- do
+ if(childrendone)
{
- for(child = children; child != NULL; child = child->next)
- {
- if(child->finished)
- {
- child->callback(child->pid, child->status, child->data);
- if(child == children)
- children = child->next;
- if(child->prev != NULL)
- child->prev->next = child->next;
- if(child->next != NULL)
- child->next->prev = child->prev;
- free(child);
- break;
- }
- }
- } while(child != NULL);
+ childrendone = 0;
+ checkchildren();
+ }
}
flog(LOG_INFO, "terminating...");
terminate();