popen.c (40188) | popen.c (74769) |
---|---|
1/* 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint | 1/* 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint |
35#if 0 |
|
35static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93"; | 36static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93"; |
37#endif 38static const char rcsid[] = 39 "$FreeBSD: head/usr.bin/mail/popen.c 74769 2001-03-25 04:57:05Z mikeh $"; |
|
36#endif /* not lint */ 37 38#include "rcv.h" 39#include <sys/wait.h> 40#include <fcntl.h> 41#include "extern.h" 42 43#define READ 0 --- 6 unchanged lines hidden (view full) --- 50 struct fp *link; 51}; 52static struct fp *fp_head; 53 54struct child { 55 int pid; 56 char done; 57 char free; | 40#endif /* not lint */ 41 42#include "rcv.h" 43#include <sys/wait.h> 44#include <fcntl.h> 45#include "extern.h" 46 47#define READ 0 --- 6 unchanged lines hidden (view full) --- 54 struct fp *link; 55}; 56static struct fp *fp_head; 57 58struct child { 59 int pid; 60 char done; 61 char free; |
58 union wait status; | 62 int status; |
59 struct child *link; 60}; 61static struct child *child; 62static struct child *findchild __P((int)); 63static void delchild __P((struct child *)); | 63 struct child *link; 64}; 65static struct child *child; 66static struct child *findchild __P((int)); 67static void delchild __P((struct child *)); |
68static int file_pid __P((FILE *)); |
|
64 65FILE * 66Fopen(file, mode) 67 char *file, *mode; 68{ 69 FILE *fp; 70 71 if ((fp = fopen(file, mode)) != NULL) { --- 89 unchanged lines hidden (view full) --- 161void 162register_file(fp, pipe, pid) 163 FILE *fp; 164 int pipe, pid; 165{ 166 struct fp *fpp; 167 168 if ((fpp = (struct fp *) malloc(sizeof *fpp)) == NULL) | 69 70FILE * 71Fopen(file, mode) 72 char *file, *mode; 73{ 74 FILE *fp; 75 76 if ((fp = fopen(file, mode)) != NULL) { --- 89 unchanged lines hidden (view full) --- 166void 167register_file(fp, pipe, pid) 168 FILE *fp; 169 int pipe, pid; 170{ 171 struct fp *fpp; 172 173 if ((fpp = (struct fp *) malloc(sizeof *fpp)) == NULL) |
169 panic("Out of memory"); | 174 err(1, "Out of memory"); |
170 fpp->fp = fp; 171 fpp->pipe = pipe; 172 fpp->pid = pid; 173 fpp->link = fp_head; 174 fp_head = fpp; 175} 176 177void 178unregister_file(fp) 179 FILE *fp; 180{ 181 struct fp **pp, *p; 182 183 for (pp = &fp_head; p = *pp; pp = &p->link) 184 if (p->fp == fp) { 185 *pp = p->link; 186 free((char *) p); 187 return; 188 } | 175 fpp->fp = fp; 176 fpp->pipe = pipe; 177 fpp->pid = pid; 178 fpp->link = fp_head; 179 fp_head = fpp; 180} 181 182void 183unregister_file(fp) 184 FILE *fp; 185{ 186 struct fp **pp, *p; 187 188 for (pp = &fp_head; p = *pp; pp = &p->link) 189 if (p->fp == fp) { 190 *pp = p->link; 191 free((char *) p); 192 return; 193 } |
189 panic("Invalid file pointer"); | 194 errx(1, "Invalid file pointer"); 195 /*NOTREACHED*/ |
190} 191 | 196} 197 |
198int |
|
192file_pid(fp) 193 FILE *fp; 194{ 195 struct fp *p; 196 197 for (p = fp_head; p; p = p->link) 198 if (p->fp == fp) 199 return (p->pid); | 199file_pid(fp) 200 FILE *fp; 201{ 202 struct fp *p; 203 204 for (p = fp_head; p; p = p->link) 205 if (p->fp == fp) 206 return (p->pid); |
200 panic("Invalid file pointer"); | 207 errx(1, "Invalid file pointer"); |
201 /*NOTREACHED*/ 202} 203 204/* 205 * Run a command without a shell, with optional arguments and splicing 206 * of stdin and stdout. The command name can be a sequence of words. 207 * Signals must be handled by the caller. 208 * "Mask" contains the signals to ignore in the new process. --- 18 unchanged lines hidden (view full) --- 227start_command(cmd, mask, infd, outfd, a0, a1, a2) 228 char *cmd; 229 int mask, infd, outfd; 230 char *a0, *a1, *a2; 231{ 232 int pid; 233 234 if ((pid = fork()) < 0) { | 208 /*NOTREACHED*/ 209} 210 211/* 212 * Run a command without a shell, with optional arguments and splicing 213 * of stdin and stdout. The command name can be a sequence of words. 214 * Signals must be handled by the caller. 215 * "Mask" contains the signals to ignore in the new process. --- 18 unchanged lines hidden (view full) --- 234start_command(cmd, mask, infd, outfd, a0, a1, a2) 235 char *cmd; 236 int mask, infd, outfd; 237 char *a0, *a1, *a2; 238{ 239 int pid; 240 241 if ((pid = fork()) < 0) { |
235 perror("fork"); | 242 warn("fork"); |
236 return -1; 237 } 238 if (pid == 0) { 239 char *argv[100]; 240 int i = getrawlist(cmd, argv, sizeof argv / sizeof *argv); 241 242 if ((argv[i++] = a0) != NOSTR && 243 (argv[i++] = a1) != NOSTR && 244 (argv[i++] = a2) != NOSTR) 245 argv[i] = NOSTR; 246 prepare_child(mask, infd, outfd); 247 execvp(argv[0], argv); | 243 return -1; 244 } 245 if (pid == 0) { 246 char *argv[100]; 247 int i = getrawlist(cmd, argv, sizeof argv / sizeof *argv); 248 249 if ((argv[i++] = a0) != NOSTR && 250 (argv[i++] = a1) != NOSTR && 251 (argv[i++] = a2) != NOSTR) 252 argv[i] = NOSTR; 253 prepare_child(mask, infd, outfd); 254 execvp(argv[0], argv); |
248 perror(argv[0]); | 255 warn("%s", argv[0]); |
249 _exit(1); 250 } 251 return pid; 252} 253 254void 255prepare_child(mask, infd, outfd) 256 int mask, infd, outfd; --- 34 unchanged lines hidden (view full) --- 291{ 292 register struct child **cpp; 293 294 for (cpp = &child; *cpp != NULL && (*cpp)->pid != pid; 295 cpp = &(*cpp)->link) 296 ; 297 if (*cpp == NULL) { 298 *cpp = (struct child *) malloc(sizeof (struct child)); | 256 _exit(1); 257 } 258 return pid; 259} 260 261void 262prepare_child(mask, infd, outfd) 263 int mask, infd, outfd; --- 34 unchanged lines hidden (view full) --- 298{ 299 register struct child **cpp; 300 301 for (cpp = &child; *cpp != NULL && (*cpp)->pid != pid; 302 cpp = &(*cpp)->link) 303 ; 304 if (*cpp == NULL) { 305 *cpp = (struct child *) malloc(sizeof (struct child)); |
306 if (*cpp == NULL) 307 err(1, "Out of memory"); |
|
299 (*cpp)->pid = pid; 300 (*cpp)->done = (*cpp)->free = 0; 301 (*cpp)->link = NULL; 302 } 303 return *cpp; 304} 305 306static void --- 8 unchanged lines hidden (view full) --- 315 free((char *) cp); 316} 317 318void 319sigchild(signo) 320 int signo; 321{ 322 int pid; | 308 (*cpp)->pid = pid; 309 (*cpp)->done = (*cpp)->free = 0; 310 (*cpp)->link = NULL; 311 } 312 return *cpp; 313} 314 315static void --- 8 unchanged lines hidden (view full) --- 324 free((char *) cp); 325} 326 327void 328sigchild(signo) 329 int signo; 330{ 331 int pid; |
323 union wait status; | 332 int status; |
324 register struct child *cp; 325 | 333 register struct child *cp; 334 |
326 while ((pid = 327 wait3((int *)&status, WNOHANG, (struct rusage *)0)) > 0) { | 335 while ((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0) { |
328 cp = findchild(pid); 329 if (cp->free) 330 delchild(cp); 331 else { 332 cp->done = 1; 333 cp->status = status; 334 } 335 } 336} 337 | 336 cp = findchild(pid); 337 if (cp->free) 338 delchild(cp); 339 else { 340 cp->done = 1; 341 cp->status = status; 342 } 343 } 344} 345 |
338union wait wait_status; | 346int wait_status; |
339 340/* 341 * Wait for a specific child to die. 342 */ 343int 344wait_child(pid) 345 int pid; 346{ 347 int mask = sigblock(sigmask(SIGCHLD)); 348 register struct child *cp = findchild(pid); 349 350 while (!cp->done) 351 sigpause(mask); 352 wait_status = cp->status; 353 delchild(cp); 354 sigsetmask(mask); | 347 348/* 349 * Wait for a specific child to die. 350 */ 351int 352wait_child(pid) 353 int pid; 354{ 355 int mask = sigblock(sigmask(SIGCHLD)); 356 register struct child *cp = findchild(pid); 357 358 while (!cp->done) 359 sigpause(mask); 360 wait_status = cp->status; 361 delchild(cp); 362 sigsetmask(mask); |
355 return wait_status.w_status ? -1 : 0; | 363 return((WIFEXITED(wait_status) && WEXITSTATUS(wait_status)) ? -1 : 0); |
356} 357 358/* 359 * Mark a child as don't care. 360 */ 361void 362free_child(pid) 363 int pid; 364{ 365 int mask = sigblock(sigmask(SIGCHLD)); 366 register struct child *cp = findchild(pid); 367 368 if (cp->done) 369 delchild(cp); 370 else 371 cp->free = 1; 372 sigsetmask(mask); 373} | 364} 365 366/* 367 * Mark a child as don't care. 368 */ 369void 370free_child(pid) 371 int pid; 372{ 373 int mask = sigblock(sigmask(SIGCHLD)); 374 register struct child *cp = findchild(pid); 375 376 if (cp->done) 377 delchild(cp); 378 else 379 cp->free = 1; 380 sigsetmask(mask); 381} |