Clean up RCS ids
[projects/cmucl/cmucl.git] / src / lisp / runprog.c
1 /*
2  * Support for run-program.
3  *
4  */
5
6 #include <sys/ioctl.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <signal.h>
10 #include <stdlib.h>
11 #include <termios.h>
12 #include <unistd.h>
13
14 pid_t
15 spawn(char *program, char *argv[], char *envp[], char *pty_name,
16       int stdin, int stdout, int stderr)
17 {
18     pid_t pid;
19     sigset_t set;
20     int fd;
21
22     pid = fork();
23     if (pid != 0)
24         return pid;
25
26     /* Put us in our own process group. */
27     setsid();
28
29     /* Unblock all signals. */
30     sigemptyset(&set);
31     sigprocmask(SIG_SETMASK, &set, NULL);
32
33     /* If we are supposed to be part of some other pty, go for it. */
34     if (pty_name) {
35 #ifdef TIOCNOTTY
36         fd = open("/dev/tty", O_RDWR, 0);
37         if (fd >= 0) {
38             ioctl(fd, TIOCNOTTY, 0);
39             close(fd);
40         }
41 #endif
42
43         fd = open(pty_name, O_RDWR, 0);
44         dup2(fd, 0);
45         dup2(fd, 1);
46         dup2(fd, 2);
47         close(fd);
48     }
49
50     /* Set up stdin, stdout, and stderr. */
51     if (stdin >= 0)
52         dup2(stdin, 0);
53     if (stdout >= 0)
54         dup2(stdout, 1);
55     if (stderr >= 0)
56         dup2(stderr, 2);
57
58     /* Close all other fds. */
59     for (fd = sysconf(_SC_OPEN_MAX) - 1; fd >= 3; fd--)
60         close(fd);
61
62     /* Exec the program. */
63     execve(program, argv, envp);
64
65     /* It didn't work, so try /bin/sh. */
66     argv[0] = program;
67     argv[-1] = "sh";
68     execve("/bin/sh", argv - 1, envp);
69
70     /* The exec didn't work, flame out. */
71     exit(1);
72 }