| /* 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; |
| } |