|
|
1.1 root 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. By the time we get here, our
9: standard output goes to jove's process input. */
10:
11: #include "jove.h"
12:
13: #if defined(IPROCS) && defined(PIPEPROCS) /* the whole file! */
14:
15: #include <signal.h>
16: #include <sys/ioctl.h>
17: #include "wait.h"
18:
19: private struct header {
20: int pid;
21: int nbytes;
22: char buf[512];
23: } header;
24:
25: private int tty_fd;
26:
27: #define HEADSIZE ((sizeof header.pid) + sizeof (header.nbytes))
28:
29: private void
30: proc_write(ptr, n)
31: UnivConstPtr ptr;
32: size_t n;
33: {
34: (void) write(1, ptr, n);
35: }
36:
37: private void
38: read_pipe(fd)
39: int fd;
40: {
41: register size_t n;
42:
43: while ((header.nbytes = read(fd, header.buf, sizeof header.buf)) > 0) {
44: n = HEADSIZE + header.nbytes;
45: proc_write((UnivConstPtr) &header, n);
46: }
47: }
48:
49: private void
50: proc_error(str)
51: char *str;
52: {
53: header.pid = getpid();
54: header.nbytes = strlen(str);
55: strcpy(header.buf, str);
56: proc_write((UnivConstPtr) &header, header.nbytes + HEADSIZE);
57: write(tty_fd, str, strlen(str));
58: exit(-2);
59: }
60:
61: /* ARGSUSED */
62: int
63: main(argc, argv)
64: int argc;
65: char *argv[];
66: {
67: int p[2];
68: int pid;
69:
70: if (pipe(p) == -1)
71: proc_error("Cannot pipe jove portsrv.\n");
72:
73: switch (pid = fork()) {
74: case -1:
75: proc_error("portsrv: cannot fork.\n");
76: /*NOTREACHED*/
77:
78: case 0:
79: /* We'll intercept childs output in p[0] */
80: (void) dup2(p[1], 1);
81: (void) dup2(p[1], 2);
82: (void) close(p[0]);
83: (void) close(p[1]);
84:
85: (void) setpgrp(getpid(), getpid());
86: execv(argv[1], (const char **) &argv[2]);
87: _exit(-4);
88: /*NOTREACHED*/
89:
90: default:
91: (void) close(0);
92: tty_fd = open("/dev/tty", 1);
93:
94: #ifdef NEVER
95: {
96: int i;
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: #endif /* NEVER */
104:
105: (void) signal(SIGINT, SIG_IGN);
106: (void) signal(SIGQUIT, SIG_IGN);
107: (void) close(p[1]);
108:
109: /* tell jove the pid of the real child as opposed to us */
110: header.pid = getpid();
111: header.nbytes = sizeof (int);
112: *(int *) header.buf = pid;
113: (void) write(1, (char *) &header, sizeof pid + HEADSIZE);
114:
115: /* read proc's output and send it to jove */
116: read_pipe(p[0]);
117:
118: /* received EOF - wait for child to die and then exit
119: ourself in the same way so that JOVE knows how the
120: child died. This is sort of a kludge, but the alternative
121: is to write the childs status to JOVE, which seems sorta
122: yucky, too.
123:
124: Actually, 4 or 5 years later I like that idea much better,
125: so remind me to implement it that way when I get a chance.
126:
127: 7-23-89 Gee thanks, whoever implemented this for me! */
128:
129: (void) close(p[0]);
130: header.pid = getpid();
131: header.nbytes = EOF; /* tell jove we are finished */
132: /* try to exit like our child did ... */
133: {
134: union wait status;
135:
136: while (wait(&status) != pid)
137: ;
138: *(int *) header.buf = status.w_status;
139: }
140: (void) write(1, (UnivConstPtr) &header, HEADSIZE + sizeof (int));
141: }
142: return 0;
143: }
144:
145: #else /* IPROCS && PIPEPROCS */
146: int
147: main()
148: {
149: return 0;
150: }
151: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.