1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
/* list_load.c */
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "trivial.h"
#include "programs.h"
#include "list_load.h"
static pid_t pid;
static volatile sig_atomic_t can_exit=0;
static void sig_term(int whatever gcc_unused);
int do_list_load(void)
{
struct sigaction sa;
sa.sa_handler=&sig_term;
sigfillset(&sa.sa_mask);
sa.sa_flags=SA_RESTART;
for(;;){
if((pid=fork())<0){
printsys("fork error\n");
} else if(!pid){ /* child */
int dev_null;
if((dev_null=open("/dev/null", O_WRONLY))==-1){
printsys("could not open /dev/null for writing\n");
}
if(dup2(dev_null, STDOUT_FILENO)==-1){
printsys("error redirecting stdout to /dev/null\n");
}
if(dup2(dev_null, STDERR_FILENO)==-1){
printsys("error redirecting stderr to /dev/null\n");
}
if(execlp("ls", "ls", "-lRa", "/", NULL)){
printsys("error executing \"ls -lRa /\"\n");
}
} else { /* parent */
sigaction(SIGTERM, &sa, NULL);
if(wait4(pid, NULL, 0, NULL)!=pid){
printsys("error waiting for pid %d\n", pid);
}
if(can_exit){
printd("exiting\n");
exit(0);
}
report_progress();
}
}
return 0;
}
static void sig_term(int whatever gcc_unused)
{
printd("killing process %d\n", pid);
/*
* if errno==ESRCH we probably got sigterm
* after wait() but before the next fork()
*/
if(kill(pid, SIGTERM) && (errno!=ESRCH)){
printsys("could not kill pid %d\n", pid);
}
can_exit=1;
return;
}
|