blob: 9f6c7ff70c8d508abec3ffe5849c69c41b743381 [file] [log] [blame]
Scott James Remnant8092e792008-04-29 23:36:16 +01001/* upstart
2 *
3 * system.c - core system functions
4 *
5 * Copyright © 2008 Canonical Ltd.
6 * Author: Scott James Remnant <scott@netsplit.com>.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifdef HAVE_CONFIG_H
24# include <config.h>
25#endif /* HAVE_CONFIG_H */
26
27#include <sys/types.h>
28#include <sys/ioctl.h>
29#include <sys/stat.h>
30
31#include <fcntl.h>
32#include <signal.h>
33#include <unistd.h>
34#include <termios.h>
35
36#include <nih/macros.h>
37#include <nih/error.h>
38#include <nih/logging.h>
39
40#include "paths.h"
41#include "system.h"
42#include "job_class.h"
43
44
45/**
46 * system_kill:
47 * @pid: process id of process,
48 * @force: force the death.
49 *
50 * Kill all processes in the same process group as @pid, which may not
51 * necessarily be the group leader.
52 *
53 * When @force is FALSE, the TERM signal is sent; when it is TRUE, KILL
54 * is sent instead.
55 *
56 * Returns: zero on success, negative value on raised error.
57 **/
58int
59system_kill (pid_t pid,
60 int force)
61{
62 int signal;
63 pid_t pgid;
64
65 nih_assert (pid > 0);
66
67 signal = (force ? SIGKILL : SIGTERM);
68
69 pgid = getpgid (pid);
70
71 if (kill (pgid > 0 ? -pgid : pid, signal) < 0)
72 nih_return_system_error (-1);
73
74 return 0;
75}
76
77
78/**
79 * system_setup_console:
80 * @type: console type,
81 * @reset: reset console to sane defaults.
82 *
83 * Set up the standard input, output and error file descriptors for the
84 * current process based on the console @type given. If @reset is TRUE then
85 * the console device will be reset to sane defaults.
86 *
87 * Returns: zero on success, negative value on raised error.
88 **/
89int
90system_setup_console (ConsoleType type,
91 int reset)
92{
93 int fd = -1, i;
94
95 /* Close the standard file descriptors since we're about to re-open
96 * them; it may be that some of these aren't already open, we get
97 * called in some very strange ways.
98 */
99 for (i = 0; i < 3; i++)
100 close (i);
101
102 /* Open the new first file descriptor, which should always become
103 * file zero.
104 */
105 switch (type) {
106 case CONSOLE_OUTPUT:
107 case CONSOLE_OWNER:
108 /* Ordinary console input and output */
109 fd = open (CONSOLE, O_RDWR | O_NOCTTY);
110 if (fd < 0)
111 nih_return_system_error (-1);
112
113 if (type == CONSOLE_OWNER)
114 ioctl (fd, TIOCSCTTY, 1);
115 break;
116 case CONSOLE_NONE:
117 /* No console really means /dev/null */
118 fd = open (DEV_NULL, O_RDWR | O_NOCTTY);
119 if (fd < 0)
120 nih_return_system_error (-1);
121 break;
122 }
123
124 /* Reset to sane defaults, cribbed from sysvinit, initng, etc. */
125 if (reset) {
126 struct termios tty;
127
128 tcgetattr (0, &tty);
129
130 tty.c_cflag &= (CBAUD | CBAUDEX | CSIZE | CSTOPB
131 | PARENB | PARODD);
132 tty.c_cflag |= (HUPCL | CLOCAL | CREAD);
133
134 /* Set up usual keys */
135 tty.c_cc[VINTR] = 3; /* ^C */
136 tty.c_cc[VQUIT] = 28; /* ^\ */
137 tty.c_cc[VERASE] = 127;
138 tty.c_cc[VKILL] = 24; /* ^X */
139 tty.c_cc[VEOF] = 4; /* ^D */
140 tty.c_cc[VTIME] = 0;
141 tty.c_cc[VMIN] = 1;
142 tty.c_cc[VSTART] = 17; /* ^Q */
143 tty.c_cc[VSTOP] = 19; /* ^S */
144 tty.c_cc[VSUSP] = 26; /* ^Z */
145
146 /* Pre and post processing */
147 tty.c_iflag = (IGNPAR | ICRNL | IXON | IXANY);
148 tty.c_oflag = (OPOST | ONLCR);
149 tty.c_lflag = (ISIG | ICANON | ECHO | ECHOCTL
150 | ECHOPRT | ECHOKE);
151
152 /* Set the terminal line and flush it */
153 tcsetattr (0, TCSANOW, &tty);
154 tcflush (0, TCIOFLUSH);
155 }
156
157 /* Copy to standard output and standard error */
158 while (dup (fd) < 2)
159 ;
160
161 return 0;
162}