blob: 94906890e39b3ab87ff31f107c62e6e6488e54a4 [file] [log] [blame]
/* upstart
*
* system.c - core system functions
*
* Copyright © 2009 Canonical Ltd.
* Author: Scott James Remnant <scott@netsplit.com>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <termios.h>
#include <nih/macros.h>
#include <nih/error.h>
#include <nih/logging.h>
#include "paths.h"
#include "system.h"
#include "job_class.h"
/**
* system_kill:
* @pid: process id of process,
* @force: force the death.
*
* Kill all processes in the same process group as @pid, which may not
* necessarily be the group leader.
*
* When @force is FALSE, the TERM signal is sent; when it is TRUE, KILL
* is sent instead.
*
* Returns: zero on success, negative value on raised error.
**/
int
system_kill (pid_t pid,
int force)
{
int signal;
pid_t pgid;
nih_assert (pid > 0);
signal = (force ? SIGKILL : SIGTERM);
pgid = getpgid (pid);
if (kill (pgid > 0 ? -pgid : pid, signal) < 0)
nih_return_system_error (-1);
return 0;
}
/**
* system_setup_console:
* @type: console type,
* @reset: reset console to sane defaults.
*
* Set up the standard input, output and error file descriptors for the
* current process based on the console @type given. If @reset is TRUE then
* the console device will be reset to sane defaults.
*
* Returns: zero on success, negative value on raised error.
**/
int
system_setup_console (ConsoleType type,
int reset)
{
int fd = -1, i;
/* Close the standard file descriptors since we're about to re-open
* them; it may be that some of these aren't already open, we get
* called in some very strange ways.
*/
for (i = 0; i < 3; i++)
close (i);
/* Open the new first file descriptor, which should always become
* file zero.
*/
switch (type) {
case CONSOLE_OUTPUT:
case CONSOLE_OWNER:
/* Ordinary console input and output */
fd = open (CONSOLE, O_RDWR | O_NOCTTY);
if (fd < 0)
nih_return_system_error (-1);
if (type == CONSOLE_OWNER)
ioctl (fd, TIOCSCTTY, 1);
break;
case CONSOLE_NONE:
/* No console really means /dev/null */
fd = open (DEV_NULL, O_RDWR | O_NOCTTY);
if (fd < 0)
nih_return_system_error (-1);
break;
}
/* Reset to sane defaults, cribbed from sysvinit, initng, etc. */
if (reset) {
struct termios tty;
tcgetattr (0, &tty);
tty.c_cflag &= (CBAUD | CBAUDEX | CSIZE | CSTOPB
| PARENB | PARODD);
tty.c_cflag |= (HUPCL | CLOCAL | CREAD);
/* Set up usual keys */
tty.c_cc[VINTR] = 3; /* ^C */
tty.c_cc[VQUIT] = 28; /* ^\ */
tty.c_cc[VERASE] = 127;
tty.c_cc[VKILL] = 24; /* ^X */
tty.c_cc[VEOF] = 4; /* ^D */
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 1;
tty.c_cc[VSTART] = 17; /* ^Q */
tty.c_cc[VSTOP] = 19; /* ^S */
tty.c_cc[VSUSP] = 26; /* ^Z */
/* Pre and post processing */
tty.c_iflag = (IGNPAR | ICRNL | IXON | IXANY);
tty.c_oflag = (OPOST | ONLCR);
tty.c_lflag = (ISIG | ICANON | ECHO | ECHOCTL
| ECHOPRT | ECHOKE);
/* Set the terminal line and flush it */
tcsetattr (0, TCSANOW, &tty);
tcflush (0, TCIOFLUSH);
}
/* Copy to standard output and standard error */
while (dup (fd) < 2)
;
return 0;
}