Path: blob/master/src/java.base/unix/native/libjava/posix_spawn.c
41119 views
// From https://android.googlesource.com/platform/external/dhcpcd-6.8.2/+/refs/heads/pie-dr1-release/compat/posix_spawn.c1/*2* dhcpcd - DHCP client daemon3* Copyright (c) 2006-2012 Roy Marples <[email protected]>4* All rights reserved5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/2627/* This implementation of posix_spawn is only suitable for the needs of dhcpcd28* but it could easily be extended to other applications. */2930#include <sys/types.h>31#include <sys/wait.h>32#include <errno.h>33#include <signal.h>34#include <stdlib.h>35#include <string.h>36#include <unistd.h>3738#include "posix_spawn.h"3940#ifndef _NSIG41#ifdef _SIG_MAXSIG42#define _NSIG _SIG_MAXSIG + 143#else44/* Guess */45#define _NSIG SIGPWR + 146#endif47#endif4849extern char **environ;5051static int52posix_spawnattr_handle(const posix_spawnattr_t *attrp)53{54struct sigaction sa;55int i;56if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK)57sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL);58if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGDEF) {59memset(&sa, 0, sizeof(sa));60sa.sa_handler = SIG_DFL;61for (i = 1; i < _NSIG; i++) {62if (sigismember(&attrp->posix_attr_sigdefault, i)) {63if (sigaction(i, &sa, NULL) == -1)64return -1;65}66}67}68return 0;69}7071inline static int72is_vfork_safe(short int flags)73{74return !(flags & (POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK));75}7677int78posix_spawn(pid_t *pid, const char *path,79const posix_spawn_file_actions_t *file_actions,80const posix_spawnattr_t *attrp,81char *const argv[], char *const envp[])82{83short int flags;84pid_t p;85volatile int error;86error = 0;87flags = attrp ? attrp->posix_attr_flags : 0;88if (file_actions == NULL && is_vfork_safe(flags))89p = vfork();90else91#ifdef THERE_IS_NO_FORK92return ENOSYS;93#else94p = fork();95#endif96switch (p) {97case -1:98return errno;99case 0:100if (attrp) {101error = posix_spawnattr_handle(attrp);102if (error)103_exit(127);104}105execve(path, argv, envp);106error = errno;107_exit(127);108default:109if (error != 0)110waitpid(p, NULL, WNOHANG);111else if (pid != NULL)112*pid = p;113return error;114}115}116117int118posix_spawnattr_init(posix_spawnattr_t *attr)119{120memset(attr, 0, sizeof(*attr));121attr->posix_attr_flags = 0;122sigprocmask(0, NULL, &attr->posix_attr_sigmask);123sigemptyset(&attr->posix_attr_sigdefault);124return 0;125}126127int128posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags)129{130attr->posix_attr_flags = flags;131return 0;132}133134int135posix_spawnattr_setsigmask(posix_spawnattr_t *attr, const sigset_t *sigmask)136{137attr->posix_attr_sigmask = *sigmask;138return 0;139}140141int142posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, const sigset_t *sigmask)143{144attr->posix_attr_sigdefault = *sigmask;145return 0;146}147148149