logwrapper.c revision 9e5e0ce62e88ddf9a09798eda51b0c270d354c8e
1d18304287dbabc7835be771400b85d4ae8b63de6San Mehat/* 2d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Copyright (C) 2008 The Android Open Source Project 3d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * 4d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * you may not use this file except in compliance with the License. 6d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * You may obtain a copy of the License at 7d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * 8d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * 10d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Unless required by applicable law or agreed to in writing, software 11d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * See the License for the specific language governing permissions and 14d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * limitations under the License. 15d18304287dbabc7835be771400b85d4ae8b63de6San Mehat */ 16d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 17d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <string.h> 18d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/types.h> 19d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/wait.h> 20d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <stdio.h> 21d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <stdlib.h> 22d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <unistd.h> 23d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <errno.h> 24d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <fcntl.h> 25d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 26d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "private/android_filesystem_config.h" 27d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "cutils/log.h" 28d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 29d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint parent(const char *tag, int parent_read) { 30d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int status; 31d18304287dbabc7835be771400b85d4ae8b63de6San Mehat char buffer[4096]; 32d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 33d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int a = 0; // start index of unprocessed data 34d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int b = 0; // end index of unprocessed data 35d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int sz; 36d18304287dbabc7835be771400b85d4ae8b63de6San Mehat while ((sz = read(parent_read, &buffer[b], sizeof(buffer) - 1 - b)) > 0) { 37d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 38d18304287dbabc7835be771400b85d4ae8b63de6San Mehat sz += b; 39d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // Log one line at a time 40d18304287dbabc7835be771400b85d4ae8b63de6San Mehat for (b = 0; b < sz; b++) { 41d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (buffer[b] == '\r') { 42d18304287dbabc7835be771400b85d4ae8b63de6San Mehat buffer[b] = '\0'; 43d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (buffer[b] == '\n') { 44d18304287dbabc7835be771400b85d4ae8b63de6San Mehat buffer[b] = '\0'; 45d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 46d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_INFO, tag, "%s", &buffer[a]); 47d18304287dbabc7835be771400b85d4ae8b63de6San Mehat a = b + 1; 48d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 49d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 50d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 51d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (a == 0 && b == sizeof(buffer) - 1) { 52d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // buffer is full, flush 53d18304287dbabc7835be771400b85d4ae8b63de6San Mehat buffer[b] = '\0'; 54a783390cc37cc8321fe695ba95ffaa5b6a2ed05bNick Kralevich LOG(LOG_INFO, tag, "%s", &buffer[a]); 55d18304287dbabc7835be771400b85d4ae8b63de6San Mehat b = 0; 56d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (a != b) { 57d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // Keep left-overs 58d18304287dbabc7835be771400b85d4ae8b63de6San Mehat b -= a; 59d18304287dbabc7835be771400b85d4ae8b63de6San Mehat memmove(buffer, &buffer[a], b); 60d18304287dbabc7835be771400b85d4ae8b63de6San Mehat a = 0; 61d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else { 62d18304287dbabc7835be771400b85d4ae8b63de6San Mehat a = 0; 63d18304287dbabc7835be771400b85d4ae8b63de6San Mehat b = 0; 64d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 65d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 66d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 67d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // Flush remaining data 68d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (a != b) { 69d18304287dbabc7835be771400b85d4ae8b63de6San Mehat buffer[b] = '\0'; 70a783390cc37cc8321fe695ba95ffaa5b6a2ed05bNick Kralevich LOG(LOG_INFO, tag, "%s", &buffer[a]); 71d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 72d18304287dbabc7835be771400b85d4ae8b63de6San Mehat status = 0xAAAA; 73d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (wait(&status) != -1) { // Wait for child 74d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (WIFEXITED(status)) { 75a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat if (WEXITSTATUS(status) != 0) { 76a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat LOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", tag, 77a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat WEXITSTATUS(status)); 78a1992c9ff3e0d180c1f3042658ab9671d61a2fb8San Mehat } 79d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return WEXITSTATUS(status); 80d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (WIFSIGNALED(status)) 81d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", tag, 82d18304287dbabc7835be771400b85d4ae8b63de6San Mehat WTERMSIG(status)); 83d18304287dbabc7835be771400b85d4ae8b63de6San Mehat else if (WIFSTOPPED(status)) 84d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", tag, 85d18304287dbabc7835be771400b85d4ae8b63de6San Mehat WSTOPSIG(status)); 86d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else 87d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_INFO, "logwrapper", "%s wait() failed: %s (%d)", tag, 88d18304287dbabc7835be771400b85d4ae8b63de6San Mehat strerror(errno), errno); 89d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return -EAGAIN; 90d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 91d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 92d18304287dbabc7835be771400b85d4ae8b63de6San Mehatvoid child(int argc, const char**argv) { 93d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // create null terminated argv_child array 94d18304287dbabc7835be771400b85d4ae8b63de6San Mehat char* argv_child[argc + 1]; 95d18304287dbabc7835be771400b85d4ae8b63de6San Mehat memcpy(argv_child, argv, argc * sizeof(char *)); 96d18304287dbabc7835be771400b85d4ae8b63de6San Mehat argv_child[argc] = NULL; 97d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 98d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // XXX: PROTECT FROM VIKING KILLER 99d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (execv(argv_child[0], argv_child)) { 100d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_ERROR, "logwrapper", 101d18304287dbabc7835be771400b85d4ae8b63de6San Mehat "executing %s failed: %s", argv_child[0], strerror(errno)); 102d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 103e7732280e7af281d35f90d7794a31a7f6e10f185Brad Fitzpatrick _exit(1); 104d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 105d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 106d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint logwrap(int argc, const char* argv[], int background) 107d18304287dbabc7835be771400b85d4ae8b63de6San Mehat{ 108d18304287dbabc7835be771400b85d4ae8b63de6San Mehat pid_t pid; 109d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 110d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int parent_ptty; 111d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int child_ptty; 112e7732280e7af281d35f90d7794a31a7f6e10f185Brad Fitzpatrick char child_devname[64]; // same size as libc/unistd/ptsname_r.c 113d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 114d18304287dbabc7835be771400b85d4ae8b63de6San Mehat /* Use ptty instead of socketpair so that STDOUT is not buffered */ 115d18304287dbabc7835be771400b85d4ae8b63de6San Mehat parent_ptty = open("/dev/ptmx", O_RDWR); 116d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (parent_ptty < 0) { 117d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_ERROR, "logwrapper", "Cannot create parent ptty"); 118d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return -errno; 119d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 120d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 121d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (grantpt(parent_ptty) || unlockpt(parent_ptty) || 122e7732280e7af281d35f90d7794a31a7f6e10f185Brad Fitzpatrick ptsname_r(parent_ptty, child_devname, sizeof(child_devname))) { 12337dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt close(parent_ptty); 124d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_ERROR, "logwrapper", "Problem with /dev/ptmx"); 125d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return -1; 126d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 127d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 128d18304287dbabc7835be771400b85d4ae8b63de6San Mehat pid = fork(); 129d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (pid < 0) { 13037dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt close(parent_ptty); 131d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_ERROR, "logwrapper", "Failed to fork"); 132d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return -errno; 133d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (pid == 0) { 134faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick /* 135faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick * Child 136faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick */ 137d18304287dbabc7835be771400b85d4ae8b63de6San Mehat child_ptty = open(child_devname, O_RDWR); 138d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (child_ptty < 0) { 13937dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt close(parent_ptty); 140d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_ERROR, "logwrapper", "Problem with child ptty"); 141e7732280e7af281d35f90d7794a31a7f6e10f185Brad Fitzpatrick _exit(errno < 128 ? errno : 1); // XXX lame 142d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 143faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick 144d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // redirect stdout and stderr 145d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(parent_ptty); 146d18304287dbabc7835be771400b85d4ae8b63de6San Mehat dup2(child_ptty, 1); 147d18304287dbabc7835be771400b85d4ae8b63de6San Mehat dup2(child_ptty, 2); 148d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(child_ptty); 149d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 150d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (background) { 151d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int fd = open("/dev/cpuctl/bg_non_interactive/tasks", O_WRONLY); 152faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick if (fd >= 0) { 153d18304287dbabc7835be771400b85d4ae8b63de6San Mehat char text[64]; 154d18304287dbabc7835be771400b85d4ae8b63de6San Mehat sprintf(text, "%d", getpid()); 155d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (write(fd, text, strlen(text)) < 0) { 156d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_WARN, "logwrapper", 157d18304287dbabc7835be771400b85d4ae8b63de6San Mehat "Unable to background process (%s)", strerror(errno)); 158d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 159d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(fd); 160d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else { 161d18304287dbabc7835be771400b85d4ae8b63de6San Mehat LOG(LOG_WARN, "logwrapper", 162d18304287dbabc7835be771400b85d4ae8b63de6San Mehat "Unable to background process (%s)", strerror(errno)); 163d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 164d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 165faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick 166d18304287dbabc7835be771400b85d4ae8b63de6San Mehat child(argc, argv); 167d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else { 168faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick /* 169faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick * Parent 170faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick */ 171faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick int rc = parent(argv[0], parent_ptty); 17237dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt close(parent_ptty); 173faabd3d839d1503aa4ed82442fbff29ba0c70897Brad Fitzpatrick return rc; 174d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 175d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 176d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 177d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 1789e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 1799e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall/* 1809e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall * The following is based off of bionic/libc/unistd/system.c with 1819e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall * modifications to avoid calling /system/bin/sh -c 1829e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall */ 1839e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrallextern char **environ; 1849e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrallint system_nosh(const char *command) 1859e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall{ 1869e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall pid_t pid; 1879e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sig_t intsave, quitsave; 1889e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigset_t mask, omask; 1899e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall int pstat; 1909e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall char buffer[255]; 1919e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall char *argp[32]; 1929e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall char *next = buffer; 1939e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall char *tmp; 1949e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall int i = 0; 1959e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 1969e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall if (!command) /* just checking... */ 1979e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall return(1); 1989e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 1999e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall /* 2009e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall * The command to argp splitting is from code that was 2019e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall * reverted in Change: 11b4e9b2 2029e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall */ 2039e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall if (strnlen(buffer, sizeof(buffer) - 1) == sizeof(buffer) - 1) { 2049e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall LOGE("command line too long while processing: %s", command); 2059e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall errno = E2BIG; 2069e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall return -1; 2079e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall } 2089e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall strcpy(buffer, command); // Command len is already checked. 2099e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall while ((tmp = strsep(&next, " "))) { 2109e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall argp[i++] = tmp; 2119e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall if (i == 32) { 2129e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall LOGE("argument overflow while processing: %s", command); 2139e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall errno = E2BIG; 2149e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall return -1; 2159e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall } 2169e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall } 2179e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall argp[i] = NULL; 2189e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 2199e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 2209e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigemptyset(&mask); 2219e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigaddset(&mask, SIGCHLD); 2229e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigprocmask(SIG_BLOCK, &mask, &omask); 2239e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall switch (pid = vfork()) { 2249e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall case -1: /* error */ 2259e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigprocmask(SIG_SETMASK, &omask, NULL); 2269e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall return(-1); 2279e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall case 0: /* child */ 2289e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigprocmask(SIG_SETMASK, &omask, NULL); 2299e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall execve(argp[0], argp, environ); 2309e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall _exit(127); 2319e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall } 2329e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall 2339e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN); 2349e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN); 2359e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall pid = waitpid(pid, (int *)&pstat, 0); 2369e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall sigprocmask(SIG_SETMASK, &omask, NULL); 2379e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall (void)bsd_signal(SIGINT, intsave); 2389e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall (void)bsd_signal(SIGQUIT, quitsave); 2399e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall return (pid == -1 ? -1 : pstat); 2409e5e0ce62e88ddf9a09798eda51b0c270d354c8eJP Abgrall} 241