source: trunk/minix/commands/simple/intr.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 2.7 KB
Line 
1/* intr 1.4 - run a command with interrupts enabled
2 * Author: Kees J. Bot
3 * 17 Dec 1992
4 */
5#define nil 0
6#ifndef _POSIX_SOURCE
7#define _POSIX_SOURCE 1
8#endif
9#include <sys/types.h>
10#include <errno.h>
11#include <fcntl.h>
12#include <signal.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17
18#if __minix
19static char DEV_LOG[]= "/dev/log";
20#else
21static char DEV_LOG[]= "/dev/console";
22#endif
23
24static void say(const char *s)
25{
26 write(2, s, strlen(s));
27}
28
29static void fatal(const char *label)
30{
31 int err= errno;
32
33 say("intr: ");
34 say(label);
35 say(": ");
36 say(strerror(err));
37 say("\n");
38 exit(1);
39}
40
41static void usage(void)
42{
43 say("Usage: intr [-d] [-t seconds] command [arg ...]\n");
44 exit(1);
45}
46
47int main(int argc, char **argv)
48{
49 int fd;
50 unsigned n= 0;
51 int daemonize= 0;
52 int i;
53
54 i= 1;
55 while (i < argc && argv[i][0] == '-') {
56 char *opt= argv[i++]+1, *end;
57 unsigned long sec;
58
59 if (opt[0] == '-' && opt[1] == 0) break;
60
61 while (*opt != 0) switch (*opt++) {
62 case 'd':
63 /* -d */
64 daemonize= 1;
65 break;
66 case 't':
67 /* -t n: alarm in n seconds. */
68 if (*opt == 0) {
69 if (i == argc) usage();
70 opt= argv[i++];
71 }
72 sec= strtoul(opt, &end, 10);
73 if (end == opt || *end != 0 || (n= sec) != sec)
74 usage();
75 opt= "";
76 break;
77 default:
78 usage();
79 }
80 }
81
82 if ((argc - i) < 1) usage();
83
84 /* Try to open the controlling tty. */
85 if ((fd= open("/dev/tty", O_RDWR)) < 0) {
86 if (errno != ENXIO) fatal("/dev/tty");
87 }
88
89 if (!daemonize) {
90 /* Bring to the foreground. If we already have a controlling
91 * tty then use it. Otherwise try to allocate the console as
92 * controlling tty and begin a process group.
93 */
94 if (fd < 0) {
95 if (setsid() < 0) fatal("setsid()");
96
97 fd= open("/dev/console", O_RDWR);
98 }
99
100 if (fd >= 0) {
101 if (fd != 0) {
102 dup2(fd, 0);
103 close(fd);
104 }
105 dup2(0, 1);
106 dup2(0, 2);
107 }
108
109 /* Set the usual signals back to the default. */
110 signal(SIGHUP, SIG_DFL);
111 signal(SIGINT, SIG_DFL);
112 signal(SIGQUIT, SIG_DFL);
113 signal(SIGTERM, SIG_DFL);
114 } else {
115 /* Send to the background. Redirect input to /dev/null, and
116 * output to the log device. Detach from the process group.
117 */
118 if (fd >= 0) {
119 close(fd);
120
121 if (setsid() < 0) fatal("setsid()");
122 }
123 if ((fd= open("/dev/null", O_RDWR)) < 0) fatal("/dev/null");
124 if (fd != 0) {
125 dup2(fd, 0);
126 close(fd);
127 }
128 if ((fd= open(DEV_LOG, O_WRONLY)) < 0) fatal(DEV_LOG);
129 if (fd != 1) {
130 dup2(fd, 1);
131 close(fd);
132 }
133 dup2(1, 2);
134
135 /* Move to the root directory. */
136 (void) chdir("/");
137 }
138
139 /* Schedule the alarm. (It is inherited over execve.) */
140 if (n != 0) alarm(n);
141
142 /* Call program. */
143 execvp(argv[i], argv + i);
144
145 /* Complain. */
146 fatal(argv[i]);
147 return 0;
148}
Note: See TracBrowser for help on using the repository browser.