/[path-sandbox]/trunk/src/sandbox.c
Gentoo

Diff of /trunk/src/sandbox.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 132 Revision 133
37 char sandbox_log[SB_PATH_MAX]; 37 char sandbox_log[SB_PATH_MAX];
38 char sandbox_debug_log[SB_PATH_MAX]; 38 char sandbox_debug_log[SB_PATH_MAX];
39 char sandbox_dir[SB_PATH_MAX]; 39 char sandbox_dir[SB_PATH_MAX];
40 char sandbox_lib[SB_PATH_MAX]; 40 char sandbox_lib[SB_PATH_MAX];
41 char sandbox_rc[SB_PATH_MAX]; 41 char sandbox_rc[SB_PATH_MAX];
42 char *sandbox_pids_file;
43 char portage_tmp_dir[SB_PATH_MAX]; 42 char portage_tmp_dir[SB_PATH_MAX];
44 char var_tmp_dir[SB_PATH_MAX]; 43 char var_tmp_dir[SB_PATH_MAX];
45 char tmp_dir[SB_PATH_MAX]; 44 char tmp_dir[SB_PATH_MAX];
46 char *home_dir; 45 char *home_dir;
47} sandbox_info_t; 46} sandbox_info_t;
48 47
49static char *tmp_dir; 48static char *tmp_dir;
50 49
51static int cleaned_up = 0;
52static int print_debug = 0; 50static int print_debug = 0;
53static int stop_called = 0; 51static int stop_called = 0;
54
55/* Read pids file, and load active pids into an array. Return number of pids in array */
56int load_active_pids(int fd, int **pids)
57{
58 char *data = NULL;
59 char *ptr = NULL, *ptr2 = NULL;
60 int my_pid;
61 int num_pids = 0;
62 long len;
63
64 pids[0] = NULL;
65
66 len = file_length(fd);
67
68 /* Allocate and zero datablock to read pids file */
69 data = (char *)malloc((len + 1) * sizeof(char));
70 memset(data, 0, len + 1);
71
72 /* Start at beginning of file */
73 lseek(fd, 0L, SEEK_SET);
74
75 /* read entire file into a buffer */
76 read(fd, data, len);
77
78 ptr = data;
79
80 /* Loop and read all pids */
81 while (1) {
82 /* Find new line */
83 ptr2 = strchr(ptr, '\n');
84 if (ptr2 == NULL)
85 break; /* No more PIDs */
86
87 /* Clear the \n. And ptr should have a null-terminated decimal string */
88 ptr2[0] = 0;
89
90 my_pid = atoi(ptr);
91
92 /* If the PID is still alive, add it to our array */
93 if ((0 != my_pid) && (0 == kill(my_pid, 0))) {
94 pids[0] = (int *)realloc(pids[0], (num_pids + 1) * sizeof(int));
95 pids[0][num_pids] = my_pid;
96 num_pids++;
97 }
98
99 /* Put ptr past the NULL we just wrote */
100 ptr = ptr2 + 1;
101 }
102
103 if (data)
104 free(data);
105 data = NULL;
106
107 return num_pids;
108}
109
110int write_pids_file(struct sandbox_info_t *sandbox_info)
111{
112 int pids_file = -1;
113 int *pids_array = NULL;
114 int num_of_pids = 0;
115 int i = 0, success = 1;
116
117 char pid_string[SB_BUF_LEN];
118
119 if (file_exist(sandbox_info->sandbox_pids_file, 1) < 0) {
120 fprintf(stderr, ">>> %s is not a regular file\n",
121 sandbox_info->sandbox_pids_file);
122 return -1;
123 } else {
124 pids_file = file_open(sandbox_info->sandbox_pids_file,
125 "r+", 1, 0664, "portage");
126 if (-1 == pids_file)
127 return -1;
128 }
129
130 /* Grab still active pids */
131 num_of_pids = load_active_pids(pids_file, &pids_array);
132
133 /* Zero out file */
134 file_truncate(pids_file);
135
136 /* Output active pids, and append our pid */
137 for (i = 0; i < num_of_pids + 1; i++) {
138 /* Time for our entry */
139 if (i == num_of_pids)
140 sprintf(pid_string, "%d\n", getpid());
141 else
142 sprintf(pid_string, "%d\n", pids_array[i]);
143
144 if (write(pids_file, pid_string, strlen(pid_string)) != strlen(pid_string)) {
145 success = 0;
146 break;
147 }
148 }
149
150 /* Clean pids_array */
151 if (pids_array)
152 free(pids_array);
153
154 /* We're done with the pids file */
155 file_close(pids_file);
156
157 if (!success)
158 return -1;
159
160 return 0;
161}
162 52
163int sandbox_setup(char *argv[], struct sandbox_info_t *sandbox_info) 53int sandbox_setup(char *argv[], struct sandbox_info_t *sandbox_info)
164{ 54{
165 if (NULL == realpath(getenv(ENV_PORTAGE_TMPDIR) ? getenv(ENV_PORTAGE_TMPDIR) 55 if (NULL == realpath(getenv(ENV_PORTAGE_TMPDIR) ? getenv(ENV_PORTAGE_TMPDIR)
166 : PORTAGE_TMPDIR, 56 : PORTAGE_TMPDIR,
194 84
195 /* Generate sandbox lib path */ 85 /* Generate sandbox lib path */
196 snprintf(sandbox_info->sandbox_lib, SB_PATH_MAX, "%s", 86 snprintf(sandbox_info->sandbox_lib, SB_PATH_MAX, "%s",
197 get_sandbox_lib(sandbox_info->sandbox_dir)); 87 get_sandbox_lib(sandbox_info->sandbox_dir));
198 88
199 /* Generate sandbox pids-file path */
200 sandbox_info->sandbox_pids_file = get_sandbox_pids_file(tmp_dir);
201
202 /* Generate sandbox bashrc path */ 89 /* Generate sandbox bashrc path */
203 snprintf(sandbox_info->sandbox_rc, SB_PATH_MAX, "%s", 90 snprintf(sandbox_info->sandbox_rc, SB_PATH_MAX, "%s",
204 get_sandbox_rc(sandbox_info->sandbox_dir)); 91 get_sandbox_rc(sandbox_info->sandbox_dir));
205 92
206 /* Generate sandbox log full path */ 93 /* Generate sandbox log full path */
210 /* Generate sandbox debug log full path */ 97 /* Generate sandbox debug log full path */
211 snprintf(sandbox_info->sandbox_debug_log, SB_PATH_MAX, "%s", 98 snprintf(sandbox_info->sandbox_debug_log, SB_PATH_MAX, "%s",
212 get_sandbox_debug_log(tmp_dir)); 99 get_sandbox_debug_log(tmp_dir));
213 100
214 return 0; 101 return 0;
215}
216
217void sandbox_cleanup()
218{
219 int i = 0;
220 int success = 1;
221 int pids_file = -1, num_of_pids = 0;
222 int *pids_array = NULL;
223 char pid_string[SB_BUF_LEN];
224 char *sandbox_pids_file;
225
226 /* Generate sandbox pids-file path */
227 sandbox_pids_file = get_sandbox_pids_file(tmp_dir);
228
229 /* Remove this sandbox's bash pid from the global pids
230 * file if we have not already done so */
231 if (0 == cleaned_up) {
232 cleaned_up = 1;
233 success = 1;
234
235 if (print_debug)
236 printf("Cleaning up pids file.\n");
237
238 /* Stat the PIDs file, make sure it exists and is a regular file */
239 if (file_exist(sandbox_pids_file, 1) <= 0) {
240 fprintf(stderr, ">>> pids file is not a regular file\n");
241 success = 0;
242 /* We should really not fail if the pidsfile is missing here, but
243 * rather just exit cleanly, as there is still some cleanup to do */
244 return;
245 }
246
247 pids_file = file_open(sandbox_pids_file, "r+", 1, 0664, "portage");
248 if (-1 == pids_file) {
249 success = 0;
250 /* Nothing more to do here */
251 return;
252 }
253
254 /* Load "still active" pids into an array */
255 num_of_pids = load_active_pids(pids_file, &pids_array);
256 //printf("pids: %d\r\n", num_of_pids);
257
258
259 file_truncate(pids_file);
260
261 /* if pids are still running, write only the running pids back to the file */
262 if (num_of_pids > 1) {
263 for (i = 0; i < num_of_pids; i++) {
264 if (pids_array[i] != getpid()) {
265 sprintf(pid_string, "%d\n", pids_array[i]);
266
267 if (write(pids_file, pid_string, strlen(pid_string)) != strlen(pid_string)) {
268 perror(">>> pids file write");
269 success = 0;
270 break;
271 }
272 }
273 }
274
275 file_close(pids_file);
276 pids_file = -1;
277 } else {
278
279 file_close(pids_file);
280 pids_file = -1;
281
282 /* remove the pidsfile, as this was the last sandbox */
283 unlink(sandbox_pids_file);
284 }
285
286 if (pids_array != NULL)
287 free(pids_array);
288 pids_array = NULL;
289 }
290
291 free(sandbox_pids_file);
292} 102}
293 103
294int print_sandbox_log(char *sandbox_log) 104int print_sandbox_log(char *sandbox_log)
295{ 105{
296 int sandbox_log_file = -1; 106 int sandbox_log_file = -1;
345void stop(int signum) 155void stop(int signum)
346{ 156{
347 if (stop_called == 0) { 157 if (stop_called == 0) {
348 stop_called = 1; 158 stop_called = 1;
349 printf("Caught signal %d in pid %d\r\n", signum, getpid()); 159 printf("Caught signal %d in pid %d\r\n", signum, getpid());
350 sandbox_cleanup();
351 } else { 160 } else {
352 fprintf(stderr, "Pid %d alreadly caught signal and is still cleaning up\n", getpid()); 161 fprintf(stderr, "Pid %d alreadly caught signal and is still cleaning up\n", getpid());
353 } 162 }
354} 163}
355 164
674 signal(SIGHUP, &stop); 483 signal(SIGHUP, &stop);
675 signal(SIGINT, &stop); 484 signal(SIGINT, &stop);
676 signal(SIGQUIT, &stop); 485 signal(SIGQUIT, &stop);
677 signal(SIGTERM, &stop); 486 signal(SIGTERM, &stop);
678 487
679 /* Load our PID into PIDs file */
680 if (-1 == write_pids_file(&sandbox_info)) {
681 perror(">>> pids file write");
682 exit(1);
683 }
684
685 /* STARTING PROTECTED ENVIRONMENT */ 488 /* STARTING PROTECTED ENVIRONMENT */
686 if (print_debug) { 489 if (print_debug) {
687 printf("The protected environment has been started.\n"); 490 printf("The protected environment has been started.\n");
688 printf("--------------------------------------------------------------------------------\n"); 491 printf("--------------------------------------------------------------------------------\n");
689 } 492 }
709 argv_bash = NULL; 512 argv_bash = NULL;
710 513
711 if (print_debug) 514 if (print_debug)
712 printf("Cleaning up sandbox process\n"); 515 printf("Cleaning up sandbox process\n");
713 516
714 sandbox_cleanup();
715
716 if (print_debug) { 517 if (print_debug) {
717 printf("========================== Gentoo linux path sandbox ===========================\n"); 518 printf("========================== Gentoo linux path sandbox ===========================\n");
718 printf("The protected environment has been shut down.\n"); 519 printf("The protected environment has been shut down.\n");
719 } 520 }
720 521
723 print_sandbox_log(sandbox_info.sandbox_log); 524 print_sandbox_log(sandbox_info.sandbox_log);
724 } else if (print_debug) { 525 } else if (print_debug) {
725 printf("--------------------------------------------------------------------------------\n"); 526 printf("--------------------------------------------------------------------------------\n");
726 } 527 }
727 528
728 free(sandbox_info.sandbox_pids_file);
729
730 if ((sandbox_log_presence) || (!success)) 529 if ((sandbox_log_presence) || (!success))
731 return 1; 530 return 1;
732 else 531 else
733 return 0; 532 return 0;
734 } 533 }

Legend:
Removed from v.132  
changed lines
  Added in v.133

  ViewVC Help
Powered by ViewVC 1.1.20