--- projects/pjob/pjob.c 2006/01/23 11:16:32 1.1 +++ projects/pjob/pjob.c 2006/01/25 19:57:12 1.4 @@ -19,9 +19,14 @@ */ #include -#include +#include #include +#include +#include +#include #include +#include +#include #define DEFNUMTHREAD 10 #define DEFTIMEOUT 60 @@ -32,6 +37,7 @@ struct _process_t{ gchar *jobname; GTimer *timer; GPid pid; + gint stat_loc; gchar *file_stdout; gchar *file_stderr; @@ -51,7 +57,6 @@ static gchar *command = NULL; static gchar *outdir = NULL; static gchar *infile = NULL; static gchar *arglist = NULL; -static gchar *stdindata = NULL; /* Command line options */ static GOptionEntry options[] = @@ -83,10 +88,8 @@ void process_child(gpointer data, gpointer user_data){ struct pollfd fds[3]; gint fdssize=2; - /*if((pipe(outpipes)) != 0){ - g_printerr("Failed to create pipe\n"); - return ; - }*/ + proc->timer = g_timer_new(); + g_timer_start(proc->timer); /* Setup files in output dir if requested to do so */ if(outdir != NULL){ @@ -124,12 +127,12 @@ void process_child(gpointer data, gpointer user_data){ /* Exec the job */ if (infile == NULL){ - if( ! g_spawn_async_with_pipes(NULL, execargv, NULL, 0, NULL, NULL, &(proc->pid), NULL, &(outpipes[0]), &(outpipes[1]), &err)){ + if( ! g_spawn_async_with_pipes(NULL, execargv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &(proc->pid), NULL, &(outpipes[0]), &(outpipes[1]), &err)){ g_printerr("Failed to execute job %s: %s\n", proc->jobname, err->message); return; } }else{ - if( ! g_spawn_async_with_pipes(NULL, execargv, NULL, 0, NULL, NULL, &(proc->pid), &(inpipes[1]), &(outpipes[0]), &(outpipes[1]), &err)){ + if( ! g_spawn_async_with_pipes(NULL, execargv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &(proc->pid), &(inpipes[1]), &(outpipes[0]), &(outpipes[1]), &err)){ g_printerr("Failed to execute job %s: %s\n", proc->jobname, err->message); return; } @@ -165,7 +168,7 @@ void process_child(gpointer data, gpointer user_data){ poll(fds, fdssize, -1); /* For stdout and stderr see if there is any data, and read it */ for(x=0; x<2; x++){ - if(fds[x].revents|POLLIN == fds[x].revents){ + if((fds[x].revents & POLLIN) == 0){ /* We have data to read */ g_io_channel_read_line(sout[x], &readbuf, &rdatasize, NULL, NULL); if(rdatasize > 0){ @@ -183,7 +186,7 @@ void process_child(gpointer data, gpointer user_data){ } } /* See if we need to pump more data down stdin */ - if(fds[2].revents|POLLOUT == fds[2].revents){ + if((fds[2].revents & POLLOUT) != 0){ /* We have data we can write */ gchar *nextline; gint nextlinesize; @@ -193,12 +196,11 @@ void process_child(gpointer data, gpointer user_data){ /* Get the next line, and write it down the stream */ s = g_io_channel_read_line(sinfile, &nextline, &nextlinesize, NULL, NULL); if (nextlinesize > 0){ - printf("Going to write '%s'\n", nextline); g_io_channel_write_chars(sin, nextline, nextlinesize, &nextlinewritesize, NULL); } if (s == G_IO_STATUS_EOF){ g_io_channel_shutdown(sin, TRUE, NULL); - sin == NULL; + sin = NULL; fdssize=2; } @@ -206,20 +208,30 @@ void process_child(gpointer data, gpointer user_data){ /* Even if we did get a hangup - lets make sure there is no more data to read first by looping again */ if (readdata) continue; - if((fds[0].revents|POLLHUP == fds[0].revents) && (fds[1].revents|POLLHUP == fds[1].revents)) break; + if(((fds[0].revents & POLLHUP) != 0) && ((fds[1].revents & POLLHUP) != 0)) break; } - /* For some batty reason, it starts with a ref count of 1. Lets decrement it so we can shut it */ - /*g_io_channel_unref(sout[0]); - g_io_channel_unref(sout[1]);*/ + while((waitpid(proc->pid, &(proc->stat_loc), 0)) != proc->pid); + g_timer_stop(proc->timer); + /* If process exited cleanly */ + if (WIFEXITED(proc->stat_loc)){ + /* Get the exit code */ + if (verbose) g_fprintf(stderr, "Job '%s' exited with code %d. Exec time: %.2f\n", proc->jobname, WEXITSTATUS(proc->stat_loc), g_timer_elapsed(proc->timer, 0)); + }else{ + /* Otherwise - find out what it died with */ + /* TODO - this doesn't work quite right.. Mainly because its looking at the shell process, so the + * child of the /bin/sh which does get a signal, this isn't passed up. Although, it handly tells + * us if the /bin/sh gets a SEGV etc ;) + */ + g_fprintf(stderr, "Job %s exited with signal %d. Exec time: %.2f\n", proc->jobname, (WTERMSIG(proc->stat_loc)), g_timer_elapsed(proc->timer, 0)); + } + + g_io_channel_shutdown(sout[0], TRUE, NULL); g_io_channel_shutdown(sout[1], TRUE, NULL); - /*close(outpipes[0]); - close(outpipes[1]);*/ - /* BUG - Causes glib error saying its already closed */ if((infile != NULL) && (sin != NULL)){ g_io_channel_shutdown(sin, TRUE, NULL); } @@ -230,7 +242,6 @@ void process_child(gpointer data, gpointer user_data){ g_spawn_close_pid(proc->pid); - if (verbose) g_fprintf(stderr, "Ending job '%s'\n", proc->jobname); } @@ -270,7 +281,6 @@ gchar *strrep(gchar *str, gchar *find, gchar *replace) * and a line for doign the substitution with. Fills in jobname */ gchar *genexeccmd(gchar *cmd, gchar *fmt, gchar *line, gchar **jobname){ - gchar **fmttok; gchar *newexec, *ptr; int x; gchar *linesep = " "; @@ -402,7 +412,7 @@ int main(int argc, char **argv){ /* Wait for the jobs to finish */ /* TODO - Kill jobs that don't finish in time */ while(g_thread_pool_get_num_threads(procpool) > 0){ - sleep(1); + g_usleep(1000); } return 0;