Skip to content
Newer
Older
100644 171 lines (148 sloc) 3.58 KB
7cb2d7a @jjelinek HEAD-1017 prompt-config has no controlling terminal so some control c…
jjelinek authored Apr 25, 2012
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2012, Joyent, Inc. All rights reserved.
24 */
25
26 /*
27 * This utility uses its parameters as a command (with options) and runs that
28 * command on each tty specified by the -d option(s). Each tty is setup as
29 * the controlling terminal for the command so that it can receive control
30 * characters (such as SIGINT) properly. The utility then waits for one of
fa1dcf1 @wesolows smartos-live#2 Fixed identation, spaces should be tabs
wesolows authored May 15, 2012
31 * the processes to exit and terminates the remaining processes running on the
7cb2d7a @jjelinek HEAD-1017 prompt-config has no controlling terminal so some control c…
jjelinek authored Apr 25, 2012
32 * other ttys.
33 *
34 * Example usage:
35 * sdc-on-tty -d /dev/console -d /dev/ttya -d /dev/ttyb config-sys foo bar
36 */
37
38 #include <stdio.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <errno.h>
45 #include <signal.h>
46 #include <stdlib.h>
47 #include <sys/wait.h>
48 #include <stropts.h>
49 #include <limits.h>
50
51 #define MAXDEVS 10
52
53 int
54 run_cmd(char *dev, char *cmd[])
55 {
56 struct stat buf;
57 int std_in, std_out, std_err;
58 int id;
59
60 if (stat(dev, &buf) < 0)
61 return (-1);
62
63 if ((buf.st_mode & S_IFMT) != S_IFCHR)
64 return (-1);
65
66 switch (id = fork()) {
67 case 0:
68 /* child */
69 closefrom(0);
70
71 /* Create a new session and process group */
72 if (setsid() < 0)
73 exit(1);
74
75 if ((std_in = open(dev, O_RDONLY)) < 0)
76 exit(1);
77 if ((std_out = open(dev, O_WRONLY)) < 0)
78 exit(1);
79 if ((std_err = open(dev, O_WRONLY)) < 0)
80 exit(1);
81
82 if (execv(cmd[0], cmd))
83 exit(1);
84 /*NOTREACHED*/
85 break;
86 case -1:
87 return (-1);
88 default:
89 /* parent */
90 return (id);
91 }
fa1dcf1 @wesolows smartos-live#2 Fixed identation, spaces should be tabs
wesolows authored May 15, 2012
92
93 /*NOTREACHED*/
94 return (-1);
7cb2d7a @jjelinek HEAD-1017 prompt-config has no controlling terminal so some control c…
jjelinek authored Apr 25, 2012
95 }
96
97 int
98 main(int argc, char **argv)
99 {
100 int arg;
101 int nprocs = 0, ndevs = 0;
102 int i;
103 int pid;
104 int stat;
105 pid_t procs[MAXDEVS];
106 char *devs[MAXDEVS];
107 char *args[ARG_MAX];
108 extern char *optarg;
109 extern int optind;
110
111 while ((arg = getopt(argc, argv, "d:")) != EOF) {
fa1dcf1 @wesolows smartos-live#2 Fixed identation, spaces should be tabs
wesolows authored May 15, 2012
112 switch (arg) {
7cb2d7a @jjelinek HEAD-1017 prompt-config has no controlling terminal so some control c…
jjelinek authored Apr 25, 2012
113 case 'd':
114 if (ndevs == MAXDEVS) {
115 fprintf(stderr, "too many tty devices\n");
116 exit(1);
117 }
118 devs[ndevs++] = optarg;
119 break;
120 default:
121 fprintf(stderr, "unknown option\n");
122 exit(1);
123 }
124 }
125
126 if (ndevs == 0) {
127 fprintf(stderr, "a tty device is required\n");
128 exit(1);
129 }
130
131 if (optind >= argc) {
132 fprintf(stderr, "missing command\n");
133 exit(1);
134 }
135
136 for (i = 0 ; optind < argc; i++, optind++)
137 args[i] = argv[optind];
138 args[i] = NULL;
139
140 for (i = 0; i < ndevs; i++) {
141 pid = run_cmd(devs[i], args);
142 if (pid != -1)
143 procs[nprocs++] = (pid_t)pid;
144 else
145 fprintf(stderr, "unable to run %s on %s\n",
146 args[0], devs[i]);
147 }
148
149 if (nprocs == 0) {
150 fprintf(stderr, "unable to run any processes\n");
151 exit(1);
152 }
153
154 signal(SIGHUP, SIG_IGN);
155 signal(SIGINT, SIG_IGN);
156 signal(SIGSTOP, SIG_IGN);
157 signal(SIGTSTP, SIG_IGN);
158 signal(SIGTTIN, SIG_IGN);
159 signal(SIGTTOU, SIG_IGN);
160
161 pid = wait(&stat);
162 for (i = 0; i < nprocs; i++) {
163 if (procs[i] != pid) {
164 (void) kill(procs[i], SIGKILL);
165 (void) wait(&stat);
166 }
167 }
168
169 return (0);
170 }
Something went wrong with that request. Please try again.