1: /***************************************************************************
2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
3: * is provided to you without charge, and with no warranty. You may give *
4: * away copies of JOVE, including sources, provided that this notice is *
5: * included in all the files. *
6: ***************************************************************************/
7:
8: /* This is a server for jove sub processes. It runs the command and
9: signals jove when there is some output ready to send to jove. By the
10: time we get here, out standard output goes to jove's process input. */
11:
12: #include "tune.h"
13:
14: #ifdef PIPEPROCS /* the whole file! */
15:
16: #include "jove.h"
17:
18: #include <signal.h>
19: #include <sys/ioctl.h>
20: #ifdef BSD4_2
21: # include <sys/wait.h>
22: #else
23: # include <wait.h>
24: #endif
25:
26: struct {
27: int pid;
28: int nbytes;
29: char buf[512];
30: } ;
31:
32: #define HEADSIZE ((sizeof header.pid) + sizeof (header.nbytes))
33:
34: error(str)
35: char *str;
36: {
37: header.pid = getpid();
38: header.nbytes = strlen(str);
39: strcpy(header.buf, str);
40: proc_write(&header, header.nbytes + HEADSIZE);
41: exit(-2);
42: }
43:
44: int ppid,
45: InputFD,
46: JovesInput;
47:
48: p_inform()
49: {
50: long nbytes;
51:
52: ioctl(JovesInput, FIONREAD, (char *) &nbytes);
53: if (nbytes > 0)
54: kill(ppid, INPUT_SIG);
55: }
56:
57: proc_write(ptr, n)
58: char *ptr;
59: {
60: long nbytes;
61:
62: ioctl(1, FIONREAD, (char *) &nbytes);
63:
64: if (nbytes == 0)
65: kill(ppid, INPUT_SIG);
66:
67: (void) write(1, ptr, n);
68: alarm(1);
69: }
70:
71: read_pipe()
72: {
73: register int n;
74:
75: (void) signal(SIGALRM, p_inform);
76:
77: while ((header.nbytes = read(InputFD, header.buf, sizeof header.buf)) > 0) {
78: n = HEADSIZE + header.nbytes;
79: proc_write(&header, n);
80: }
81: }
82:
83: /* ARGSUSED */
84: main(argc, argv)
85: char *argv[];
86: {
87: int p[2];
88: int pid;
89: int tty_fd,
90: i;
91:
92: /* tty_fd = open("/dev/tty", 1); */
93:
94: if (pipe(p) == -1)
95: error("Cannot pipe jove portsrv.\n");
96:
97: /* for (i = 0; i < argc; i++) {
98: write(tty_fd, "*argv++ = ", 10);
99: write(tty_fd, argv[i], strlen(argv[i]));
100: write(tty_fd, "\n", 1);
101: } */
102:
103: ppid = getppid();
104: switch (pid = fork()) {
105: case -1:
106: error("portsrv: cannot fork.\n");
107:
108: case 0:
109: /* We'll intercept childs output in p[0] */
110: (void) dup2(p[1], 1);
111: (void) dup2(p[1], 2);
112: (void) close(p[0]);
113: (void) close(p[1]);
114:
115: (void) setpgrp(getpid(), getpid());
116: execv(argv[2], &argv[3]);
117: _exit(-4);
118:
119: default:
120: (void) close(0);
121:
122: /* don't want this guy to read anything jove sends to
123: our soon to be created child */
124:
125: JovesInput = atoi(argv[1]);
126: (void) signal(SIGINT, SIG_IGN);
127: (void) signal(SIGQUIT, SIG_IGN);
128: (void) close(p[1]);
129:
130: /* tell jove the pid of the real child as opposed to us */
131: header.pid = getpid();
132: header.nbytes = sizeof (int);
133: *(int *) header.buf = pid;
134: (void) write(1, (char *) &header, sizeof pid + HEADSIZE);
135: p_inform(); /* Inform jove */
136:
137: /* read proc's output and send it to jove */
138: InputFD = p[0];
139: read_pipe();
140: (void) close(p[0]);
141: header.pid = getpid();
142: header.nbytes = EOF; /* tell jove we are finished */
143: (void) write(1, (char *) &header, HEADSIZE);
144: p_inform();
145: /* try to exit like our child did ... */
146: {
147: union wait w;
148:
149: #ifndef BSD4_2
150: while (wait2(&w.w_status, 0) != pid)
151: #else
152: while (wait3(&w.w_status, 0, 0) != pid)
153: #endif
154: ;
155: if (WIFEXITED(w))
156: exit(w.w_retcode);
157: else if (WIFSIGNALED(w))
158: kill(getpid(), w.w_termsig);
159: }
160: }
161: }
162:
163: #else /* PIPEPROCS */
164: main()
165: {
166: }
167: #endif