add copyright
[unix-history] / usr / src / lib / libc / gen / popen.c
CommitLineData
b8f253e8
KM
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
2ce81398
DS
7#if defined(LIBC_SCCS) && !defined(lint)
8static char sccsid[] = "@(#)popen.c 5.3 (Berkeley) %G%";
9#endif LIBC_SCCS and not lint
99756664 10
01a56307
BJ
11#include <stdio.h>
12#include <signal.h>
43d12555 13#include <sys/param.h>
99756664 14
01a56307
BJ
15#define tst(a,b) (*mode == 'r'? (b) : (a))
16#define RDR 0
17#define WTR 1
99756664 18
fec6f225
S
19extern char *malloc();
20
21static int *popen_pid;
22static int nfiles;
01a56307
BJ
23
24FILE *
25popen(cmd,mode)
99756664
SL
26 char *cmd;
27 char *mode;
01a56307
BJ
28{
29 int p[2];
99756664 30 int myside, hisside, pid;
01a56307 31
fec6f225
S
32 if (nfiles <= 0)
33 nfiles = getdtablesize();
34 if (popen_pid == NULL) {
35 popen_pid = (int *)malloc(nfiles * sizeof *popen_pid);
36 if (popen_pid == NULL)
37 return (NULL);
38 for (pid = 0; pid < nfiles; pid++)
39 popen_pid[pid] = -1;
40 }
99756664
SL
41 if (pipe(p) < 0)
42 return (NULL);
01a56307
BJ
43 myside = tst(p[WTR], p[RDR]);
44 hisside = tst(p[RDR], p[WTR]);
fec6f225 45 if ((pid = vfork()) == 0) {
01a56307
BJ
46 /* myside and hisside reverse roles in child */
47 close(myside);
482b978e
SL
48 if (hisside != tst(0, 1)) {
49 dup2(hisside, tst(0, 1));
50 close(hisside);
51 }
fec6f225
S
52 execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
53 _exit(127);
01a56307 54 }
99756664 55 if (pid == -1) {
2337e291
MK
56 close(myside);
57 close(hisside);
99756664 58 return (NULL);
2337e291 59 }
01a56307
BJ
60 popen_pid[myside] = pid;
61 close(hisside);
99756664 62 return (fdopen(myside, mode));
01a56307
BJ
63}
64
65pclose(ptr)
99756664 66 FILE *ptr;
01a56307 67{
99756664 68 int child, pid, status, omask;
01a56307 69
99756664 70 child = popen_pid[fileno(ptr)];
fec6f225 71 popen_pid[fileno(ptr)] = -1;
01a56307 72 fclose(ptr);
fec6f225
S
73 if (child == -1)
74 return (-1);
75 omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
99756664 76 while ((pid = wait(&status)) != child && pid != -1)
01a56307 77 ;
99756664
SL
78 (void) sigsetmask(omask);
79 return (pid == -1 ? -1 : status);
01a56307 80}