Commit | Line | Data |
---|---|---|
6ca833f5 C |
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 header { | |
27 | int pid; | |
28 | int nbytes; | |
29 | char buf[512]; | |
30 | } header; | |
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 |