File: ctar_load.c

package info (click to toggle)
contest 0.61-5
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 228 kB
  • ctags: 217
  • sloc: ansic: 2,121; makefile: 98; sh: 3
file content (111 lines) | stat: -rw-r--r-- 2,723 bytes parent folder | download | duplicates (2)
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;
}