blob: a0f7a6b8988e5182234e3b3b7dd48407346a4b97 [file] [log] [blame]
Scott James Remnant8092e792008-04-29 23:36:16 +01001/* upstart
2 *
3 * system.c - core system functions
4 *
Scott James Remnantd69c1da2010-02-26 15:29:07 +00005 * Copyright © 2010 Canonical Ltd.
Scott James Remnant7d5b2ea2009-05-22 15:20:12 +02006 * Author: Scott James Remnant <scott@netsplit.com>.
Scott James Remnant8092e792008-04-29 23:36:16 +01007 *
Scott James Remnant0c0c5a52009-06-23 10:29:35 +01008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2, as
Scott James Remnant75123022009-05-22 13:27:56 +020010 * published by the Free Software Foundation.
Scott James Remnant8092e792008-04-29 23:36:16 +010011 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
Scott James Remnant0c0c5a52009-06-23 10:29:35 +010017 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Scott James Remnant8092e792008-04-29 23:36:16 +010020 */
Scott James Remnant8092e792008-04-29 23:36:16 +010021
22#ifdef HAVE_CONFIG_H
23# include <config.h>
24#endif /* HAVE_CONFIG_H */
25
26#include <sys/types.h>
27#include <sys/ioctl.h>
28#include <sys/stat.h>
Scott James Remnantd69c1da2010-02-26 15:29:07 +000029#include <sys/mount.h>
Scott James Remnant8092e792008-04-29 23:36:16 +010030
31#include <fcntl.h>
32#include <signal.h>
Scott James Remnantd69c1da2010-02-26 15:29:07 +000033#include <string.h>
Scott James Remnant8092e792008-04-29 23:36:16 +010034#include <unistd.h>
35#include <termios.h>
36
37#include <nih/macros.h>
Scott James Remnantd69c1da2010-02-26 15:29:07 +000038#include <nih/alloc.h>
39#include <nih/string.h>
Scott James Remnant8092e792008-04-29 23:36:16 +010040#include <nih/error.h>
41#include <nih/logging.h>
42
43#include "paths.h"
44#include "system.h"
45#include "job_class.h"
46
47
48/**
Scott James Remnant2e9ff7e2011-05-12 13:42:28 -070049 * system_kill:
Scott James Remnant8092e792008-04-29 23:36:16 +010050 * @pid: process id of process,
Marc A. Dahlhaus48ea1fe2011-05-05 11:04:21 +020051 * @signal: signal to send.
Scott James Remnant8092e792008-04-29 23:36:16 +010052 *
Marc A. Dahlhaus48ea1fe2011-05-05 11:04:21 +020053 * Send all processes in the same process group as @pid, which may not
54 * necessarily be the group leader the @signal.
Scott James Remnant8092e792008-04-29 23:36:16 +010055 *
56 * Returns: zero on success, negative value on raised error.
57 **/
58int
Scott James Remnant2e9ff7e2011-05-12 13:42:28 -070059system_kill (pid_t pid,
60 int signal)
Scott James Remnant8092e792008-04-29 23:36:16 +010061{
Scott James Remnant8092e792008-04-29 23:36:16 +010062 pid_t pgid;
63
64 nih_assert (pid > 0);
65
Scott James Remnant8092e792008-04-29 23:36:16 +010066 pgid = getpgid (pid);
67
68 if (kill (pgid > 0 ? -pgid : pid, signal) < 0)
69 nih_return_system_error (-1);
70
71 return 0;
72}
73
74
75/**
76 * system_setup_console:
77 * @type: console type,
78 * @reset: reset console to sane defaults.
79 *
80 * Set up the standard input, output and error file descriptors for the
81 * current process based on the console @type given. If @reset is TRUE then
82 * the console device will be reset to sane defaults.
83 *
84 * Returns: zero on success, negative value on raised error.
85 **/
86int
87system_setup_console (ConsoleType type,
88 int reset)
89{
90 int fd = -1, i;
91
92 /* Close the standard file descriptors since we're about to re-open
93 * them; it may be that some of these aren't already open, we get
94 * called in some very strange ways.
95 */
96 for (i = 0; i < 3; i++)
97 close (i);
98
99 /* Open the new first file descriptor, which should always become
100 * file zero.
101 */
102 switch (type) {
103 case CONSOLE_OUTPUT:
104 case CONSOLE_OWNER:
105 /* Ordinary console input and output */
106 fd = open (CONSOLE, O_RDWR | O_NOCTTY);
107 if (fd < 0)
108 nih_return_system_error (-1);
109
110 if (type == CONSOLE_OWNER)
111 ioctl (fd, TIOCSCTTY, 1);
112 break;
113 case CONSOLE_NONE:
114 /* No console really means /dev/null */
115 fd = open (DEV_NULL, O_RDWR | O_NOCTTY);
116 if (fd < 0)
117 nih_return_system_error (-1);
118 break;
119 }
120
121 /* Reset to sane defaults, cribbed from sysvinit, initng, etc. */
122 if (reset) {
123 struct termios tty;
124
125 tcgetattr (0, &tty);
126
127 tty.c_cflag &= (CBAUD | CBAUDEX | CSIZE | CSTOPB
128 | PARENB | PARODD);
129 tty.c_cflag |= (HUPCL | CLOCAL | CREAD);
130
131 /* Set up usual keys */
132 tty.c_cc[VINTR] = 3; /* ^C */
133 tty.c_cc[VQUIT] = 28; /* ^\ */
134 tty.c_cc[VERASE] = 127;
135 tty.c_cc[VKILL] = 24; /* ^X */
136 tty.c_cc[VEOF] = 4; /* ^D */
137 tty.c_cc[VTIME] = 0;
138 tty.c_cc[VMIN] = 1;
139 tty.c_cc[VSTART] = 17; /* ^Q */
140 tty.c_cc[VSTOP] = 19; /* ^S */
141 tty.c_cc[VSUSP] = 26; /* ^Z */
142
143 /* Pre and post processing */
144 tty.c_iflag = (IGNPAR | ICRNL | IXON | IXANY);
145 tty.c_oflag = (OPOST | ONLCR);
146 tty.c_lflag = (ISIG | ICANON | ECHO | ECHOCTL
147 | ECHOPRT | ECHOKE);
148
149 /* Set the terminal line and flush it */
150 tcsetattr (0, TCSANOW, &tty);
151 tcflush (0, TCIOFLUSH);
152 }
153
154 /* Copy to standard output and standard error */
155 while (dup (fd) < 2)
156 ;
157
158 return 0;
159}
Scott James Remnantd69c1da2010-02-26 15:29:07 +0000160
161
162/**
163 * system_mount:
164 * @type: filesystem type,
165 * @dir: mountpoint.
166 *
167 * Mount the kernel filesystem @type at @dir, if not already mounted. This
168 * is used to ensure that the proc and sysfs filesystems are always
169 * available.
170 *
171 * Filesystems are always mounted with the MS_NODEV, MS_NOEXEC and MS_NOSUID
172 * mount options, which are sensible for /proc and /sys.
173 *
174 * Returns: zero on success, negative value on raised error.
175 **/
176int
177system_mount (const char *type,
Dmitry Torokhov164e5352016-06-08 16:16:35 -0700178 const char *dir,
Mike Frysinger7506b642020-11-17 18:58:12 -0500179 unsigned int opts,
180 const char *options)
Scott James Remnantd69c1da2010-02-26 15:29:07 +0000181{
182 nih_local char *parent = NULL;
183 char * ptr;
184 struct stat parent_stat;
185 struct stat dir_stat;
186
187 nih_assert (type != NULL);
188 nih_assert (dir != NULL);
189
190 /* Stat the parent directory of the mountpoint to obtain the dev_t */
191 ptr = strrchr (dir, '/');
192 nih_assert (ptr != NULL);
193
194 parent = NIH_MUST (nih_strndup (NULL, dir, ptr == dir ? 1 : ptr - dir));
195 if (stat (parent, &parent_stat) < 0)
196 nih_return_system_error (-1);
197
198 /* Also stat the mountpoint to obtain the dev_t */
199 if (stat (dir, &dir_stat) < 0)
200 nih_return_system_error (-1);
201
202 /* If the two dev_ts do not match, then there is already a filesystem
203 * mounted and we needn't do anything.
204 */
205 if (parent_stat.st_dev != dir_stat.st_dev)
206 return 0;
207
208 /* Mount the filesystem */
Mike Frysinger7506b642020-11-17 18:58:12 -0500209 if (mount (type, dir, type, opts, options) < 0)
Scott James Remnantd69c1da2010-02-26 15:29:07 +0000210 nih_return_system_error (-1);
211
212 return 0;
213}