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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
/* ctar_load.c */
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "trivial.h"
#include "programs.h"
#include "ctar_load.h"
static pid_t pid;
static volatile sig_atomic_t can_exit=0;
static void sig_term(int whatever gcc_unused);
int do_ctar_load(void)
{
struct sigaction sa;
sa.sa_handler=&sig_term;
sigfillset(&sa.sa_mask);
sa.sa_flags=SA_RESTART;
printd("pid=%d\n", getpid());
for(;;){
if((pid=fork())<0){
printsys("fork error\n");
} else if(!pid){ /* child */
int dev_null;
printd("executing tar etc\n");
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("tar", "tar", "cf", "linux.tar", "temp/linux-for-contest", NULL)){
printsys("error executing tar\n");
}
} else { /* parent */
sigaction(SIGTERM, &sa, NULL);
printd("waiting for pid %d\n", pid);
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("process %d (ppid=%d): in sig term, pid=%d\n", getpid(),
getppid(), pid);
printd("killing process %d\n", pid);
if(kill(pid, SIGTERM) && (errno!=ESRCH)){
printsys("could not kill pid %d\n", pid);
}
can_exit=1;
exit(0);
}
int prep_ctar_load(void)
{
int ret;
if((ret=system("mkdir -p temp/linux-for-contest"))){
printsys("error executing \"mkdir -p temp/linux-for-contest\","
" exit status=%d\n", ret);
}
printf("Creating new source tree for ctar_load\n");
if((ret=system("tar cf - --exclude temp --exclude dump "
"--exclude linux.tar --exclude linux-for-contest.tar "
"./ | (cd temp/linux-for-contest; tar xf - --exclude "
"temp --exclude dump)"))){
printsys("error executing command \"tar cf - ./ | (cd "
"temp/linux-for-contest; tar xf -)\", shell "
"exit status is %d\n", ret);
}
return 0;
}
int cleanup_ctar_load(void)
{
/*
* these actions should never fail unless the user is touching
* the file/directory behind our back
*/
if(unlink("linux.tar")){
printe("unable to unlink \"linux.tar\" - this is not fatal "
"but it's definitely unexpected\n");
return 1;
}
if(system("rm -rf temp/linux-for-contest")){
printe("could not delete \"temp/linux-for-contest\" - wtf?\n");
return 1;
}
return 0;
}
|