src/java.base/unix/native/libjava/ProcessImpl_md.c
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 55403 8d50ff464ae5
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
52364
750b500ef4de 8212828: (process) Provide a way for Runtime.exec to use posix_spawn on linux
stuefe
parents: 47216
diff changeset
     2
 * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#undef  _LARGEFILE64_SOURCE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#define _LARGEFILE64_SOURCE 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include "jni.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include "jvm.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "jvm_md.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "jni_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
#include "io_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * Platform-specific support for java.lang.Process
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
#include <assert.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
#include <stddef.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
#include <sys/types.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
#include <ctype.h>
11691
ff8aec7600fe 7133301: (process) UNIXProcess_md.c should include sys/wait.h rather than wait.h
ngmr
parents: 5506
diff changeset
    43
#include <sys/wait.h>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
#include <signal.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    47
#include <spawn.h>
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 11691
diff changeset
    48
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    49
#include "childproc.h"
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    50
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
    51
/*
53722
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    52
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    53
 * When starting a child on Unix, we need to do three things:
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    54
 * - fork off
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    55
 * - in the child process, do some pre-exec work: duping/closing file
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    56
 *   descriptors to set up stdio-redirection, setting environment variables,
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    57
 *   changing paths...
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    58
 * - then exec(2) the target binary
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    59
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    60
 * There are three ways to fork off:
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    61
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    62
 * A) fork(2). Portable and safe (no side effects) but may fail with ENOMEM on
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    63
 *    all Unices when invoked from a VM with a high memory footprint. On Unices
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    64
 *    with strict no-overcommit policy this problem is most visible.
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    65
 *
53722
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    66
 *    This is because forking the VM will first create a child process with
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    67
 *    theoretically the same memory footprint as the parent - even if you plan
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    68
 *    to follow up with exec'ing a tiny binary. In reality techniques like
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    69
 *    copy-on-write etc mitigate the problem somewhat but we still run the risk
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    70
 *    of hitting system limits.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    71
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    72
 *    For a Linux centric description of this problem, see the documentation on
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    73
 *    /proc/sys/vm/overcommit_memory in Linux proc(5).
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    74
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    75
 * B) vfork(2): Portable and fast but very unsafe. It bypasses the memory
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    76
 *    problems related to fork(2) by starting the child in the memory image of
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    77
 *    the parent. Things that can go wrong include:
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    78
 *    - Programming errors in the child process before the exec(2) call may
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    79
 *      trash memory in the parent process, most commonly the stack of the
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    80
 *      thread invoking vfork.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    81
 *    - Signals received by the child before the exec(2) call may be at best
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    82
 *      misdirected to the parent, at worst immediately kill child and parent.
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    83
 *
53722
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    84
 *    This is mitigated by very strict rules about what one is allowed to do in
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    85
 *    the child process between vfork(2) and exec(2), which is basically nothing.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    86
 *    However, we always broke this rule by doing the pre-exec work between
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    87
 *    vfork(2) and exec(2).
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    88
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    89
 *    Also note that vfork(2) has been deprecated by the OpenGroup, presumably
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    90
 *    because of its many dangers.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    91
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    92
 * C) clone(2): This is a Linux specific call which gives the caller fine
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    93
 *    grained control about how exactly the process fork is executed. It is
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    94
 *    powerful, but Linux-specific.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    95
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    96
 * Aside from these three possibilities there is a forth option:  posix_spawn(3).
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    97
 * Where fork/vfork/clone all fork off the process and leave pre-exec work and
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    98
 * calling exec(2) to the user, posix_spawn(3) offers the user fork+exec-like
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
    99
 * functionality in one package, similar to CreateProcess() on Windows.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   100
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   101
 * It is not a system call in itself, but usually a wrapper implemented within
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   102
 * the libc in terms of one of (fork|vfork|clone)+exec - so whether or not it
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   103
 * has advantages over calling the naked (fork|vfork|clone) functions depends
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   104
 * on how posix_spawn(3) is implemented.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   105
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   106
 * Note that when using posix_spawn(3), we exec twice: first a tiny binary called
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   107
 * the jspawnhelper, then in the jspawnhelper we do the pre-exec work and exec a
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   108
 * second time, this time the target binary (similar to the "exec-twice-technique"
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   109
 * described in http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-September/055333.html).
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   110
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   111
 * This is a JDK-specific implementation detail which just happens to be
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   112
 * implemented for jdk.lang.Process.launchMechanism=POSIX_SPAWN.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   113
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   114
 * --- Linux-specific ---
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   115
 *
53722
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   116
 * How does glibc implement posix_spawn?
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   117
 * (see: sysdeps/posix/spawni.c for glibc < 2.24,
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   118
 *       sysdeps/unix/sysv/linux/spawni.c for glibc >= 2.24):
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   119
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   120
 * 1) Before glibc 2.4 (released 2006), posix_spawn(3) used just fork(2)/exec(2).
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   121
 *    This would be bad for the JDK since we would risk the known memory issues with
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   122
 *    fork(2). But since this only affects glibc variants which have long been
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   123
 *    phased out by modern distributions, this is irrelevant.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   124
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   125
 * 2) Between glibc 2.4 and glibc 2.23, posix_spawn uses either fork(2) or
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   126
 *    vfork(2) depending on how exactly the user called posix_spawn(3):
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   127
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   128
 * <quote>
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   129
 *       The child process is created using vfork(2) instead of fork(2) when
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   130
 *       either of the following is true:
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   131
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   132
 *       * the spawn-flags element of the attributes object pointed to by
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   133
 *          attrp contains the GNU-specific flag POSIX_SPAWN_USEVFORK; or
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   134
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   135
 *       * file_actions is NULL and the spawn-flags element of the attributes
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   136
 *          object pointed to by attrp does not contain
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   137
 *          POSIX_SPAWN_SETSIGMASK, POSIX_SPAWN_SETSIGDEF,
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   138
 *          POSIX_SPAWN_SETSCHEDPARAM, POSIX_SPAWN_SETSCHEDULER,
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   139
 *          POSIX_SPAWN_SETPGROUP, or POSIX_SPAWN_RESETIDS.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   140
 * </quote>
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   141
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   142
 * Due to the way the JDK calls posix_spawn(3), it would therefore call vfork(2).
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   143
 * So we would avoid the fork(2) memory problems. However, there still remains the
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   144
 * risk associated with vfork(2). But it is smaller than were we to call vfork(2)
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   145
 * directly since we use the jspawnhelper, moving all pre-exec work off to after
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   146
 * the first exec, thereby reducing the vulnerable time window.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   147
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   148
 * 3) Since glibc >= 2.24, glibc uses clone+exec:
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   149
 *
53722
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   150
 *    new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   151
 *                     CLONE_VM | CLONE_VFORK | SIGCHLD, &args);
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   152
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   153
 * This is even better than (2):
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   154
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   155
 * CLONE_VM means we run in the parent's memory image, as with (2)
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   156
 * CLONE_VFORK means parent waits until we exec, as with (2)
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   157
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   158
 * However, error possibilities are further reduced since:
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   159
 * - posix_spawn(3) passes a separate stack for the child to run on, eliminating
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   160
 *   the danger of trashing the forking thread's stack in the parent process.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   161
 * - posix_spawn(3) takes care to temporarily block all incoming signals to the
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   162
 *   child process until the first exec(2) has been called,
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   163
 *
53722
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   164
 * TL;DR
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   165
 * Calling posix_spawn(3) for glibc
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   166
 * (2) < 2.24 is not perfect but still better than using plain vfork(2), since
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   167
 *     the chance of an error happening is greatly reduced
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   168
 * (3) >= 2.24 is the best option - portable, fast and as safe as possible.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   169
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   170
 * ---
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   171
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   172
 * How does muslc implement posix_spawn?
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   173
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   174
 * They always did use the clone (.. CLONE_VM | CLONE_VFORK ...)
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   175
 * technique. So we are safe to use posix_spawn() here regardless of muslc
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   176
 * version.
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   177
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   178
 * </Linux-specific>
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   179
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   180
 *
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   181
 * Based on the above analysis, we are currently defaulting to posix_spawn()
f037d1a2e899 8212828: (process) Change the Process launch mechanism default on Linux to be posix_spawn
stuefe
parents: 52364
diff changeset
   182
 * on all Unices including Linux.
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
   183
 */
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   184
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
setSIGCHLDHandler(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    /* There is a subtle difference between having the signal handler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * for SIGCHLD be SIG_DFL and SIG_IGN.  We cannot obtain process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * termination information for child processes if the signal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * handler is SIG_IGN.  It must be SIG_DFL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * We used to set the SIGCHLD handler only on Linux, but it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * safest to set it unconditionally.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * Consider what happens if java's parent process sets the SIGCHLD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * handler to SIG_IGN.  Normally signal handlers are inherited by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * children, but SIGCHLD is a controversial case.  Solaris appears
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     * to always reset it to SIG_DFL, but this behavior may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * non-standard-compliant, and we shouldn't rely on it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * References:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    struct sigaction sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    sa.sa_handler = SIG_DFL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    sigemptyset(&sa.sa_mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    if (sigaction(SIGCHLD, &sa, NULL) < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
static void*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
xmalloc(JNIEnv *env, size_t size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    void *p = malloc(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    if (p == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        JNU_ThrowOutOfMemoryError(env, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    return p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
 * If PATH is not defined, the OS provides some default value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
 * Unfortunately, there's no portable way to get this value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
 * Fortunately, it's only needed if the child has PATH while we do not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
defaultPath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
#ifdef __solaris__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    /* These really are the Solaris defaults! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    return (geteuid() == 0 || getuid() == 0) ?
41107
567f832618d7 8165161: Solaris: /usr/ccs /opt/sfw and /opt/csw are dead, references should be expunged
alanbur
parents: 40745
diff changeset
   236
        "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
567f832618d7 8165161: Solaris: /usr/ccs /opt/sfw and /opt/csw are dead, references should be expunged
alanbur
parents: 40745
diff changeset
   237
        "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    return ":/bin:/usr/bin";    /* glibc */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
effectivePath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    const char *s = getenv("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    return (s != NULL) ? s : defaultPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
countOccurrences(const char *s, char c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    int count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    for (count = 0; *s != '\0'; s++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        count += (*s == c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
static const char * const *
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   260
effectivePathv(JNIEnv *env)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   262
    char *p;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    int i;
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   264
    const char *path = effectivePath();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    int count = countOccurrences(path, ':') + 1;
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   266
    size_t pathvsize = sizeof(const char *) * (count+1);
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   267
    size_t pathsize = strlen(path) + 1;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   268
    const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   270
    if (pathv == NULL)
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   271
        return NULL;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   272
    p = (char *) pathv + pathvsize;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   273
    memcpy(p, path, pathsize);
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   274
    /* split PATH by replacing ':' with NULs; empty components => "." */
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   275
    for (i = 0; i < count; i++) {
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   276
        char *q = p + strcspn(p, ":");
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   277
        pathv[i] = (p == q) ? "." : p;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   278
        *q = '\0';
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   279
        p = q + 1;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   280
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    pathv[count] = NULL;
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   282
    return pathv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
JNIEXPORT void JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   286
Java_java_lang_ProcessImpl_init(JNIEnv *env, jclass clazz)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   288
    parentPathv = effectivePathv(env);
22641
e47f8892133e 8033372: Check jdk/src/share/native/java/lang for JNI pending exception issues
alanb
parents: 22597
diff changeset
   289
    CHECK_NULL(parentPathv);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    setSIGCHLDHandler(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
#ifndef WIFEXITED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
#define WIFEXITED(status) (((status)&0xFF) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
#ifndef WEXITSTATUS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
#define WEXITSTATUS(status) (((status)>>8)&0xFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
#ifndef WIFSIGNALED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
#ifndef WTERMSIG
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
#define WTERMSIG(status) ((status)&0x7F)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
static const char *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
getBytes(JNIEnv *env, jbyteArray arr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    return arr == NULL ? NULL :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    if (parr != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   324
#define IOE_FORMAT "error=%d, %s"
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   325
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    const char *detail = defaultDetail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    char *errmsg;
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   331
    size_t fmtsize;
32846
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   332
    char tmpbuf[1024];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    jstring s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    if (errnum != 0) {
32846
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   336
        int ret = getErrorString(errnum, tmpbuf, sizeof(tmpbuf));
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   337
        if (ret != EINVAL)
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   338
            detail = tmpbuf;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   341
    fmtsize = sizeof(IOE_FORMAT) + strlen(detail) + 3 * sizeof(errnum);
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   342
    errmsg = NEW(char, fmtsize);
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   343
    if (errmsg == NULL)
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   344
        return;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   345
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   346
    snprintf(errmsg, fmtsize, IOE_FORMAT, errnum, detail);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    s = JNU_NewStringPlatform(env, errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    if (s != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        jobject x = JNU_NewObjectByName(env, "java/io/IOException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                                        "(Ljava/lang/String;)V", s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        if (x != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            (*env)->Throw(env, x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    free(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
55403
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   357
/**
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   358
 * Throws an IOException with a message composed from the result of waitpid status.
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   359
 */
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   360
static void throwExitCause(JNIEnv *env, int pid, int status) {
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   361
    char ebuf[128];
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   362
    if (WIFEXITED(status)) {
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   363
        snprintf(ebuf, sizeof ebuf,
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   364
            "Failed to exec spawn helper: pid: %d, exit value: %d",
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   365
            pid, WEXITSTATUS(status));
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   366
    } else if (WIFSIGNALED(status)) {
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   367
        snprintf(ebuf, sizeof ebuf,
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   368
            "Failed to exec spawn helper: pid: %d, signal: %d",
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   369
            pid, WTERMSIG(status));
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   370
    } else {
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   371
        snprintf(ebuf, sizeof ebuf,
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   372
            "Failed to exec spawn helper: pid: %d, status: 0x%08x",
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   373
            pid, status);
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   374
    }
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   375
    throwIOException(env, 0, ebuf);
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   376
}
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   377
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
#ifdef DEBUG_PROCESS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
/* Debugging process code is difficult; where to write debug output? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
debugPrint(char *format, ...)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    FILE *tty = fopen("/dev/tty", "w");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    va_list ap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    va_start(ap, format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    vfprintf(tty, format, ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    va_end(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    fclose(tty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
#endif /* DEBUG_PROCESS */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   392
static void
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   393
copyPipe(int from[2], int to[2])
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   394
{
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   395
    to[0] = from[0];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   396
    to[1] = from[1];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   397
}
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   398
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   399
/* arg is an array of pointers to 0 terminated strings. array is terminated
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   400
 * by a null element.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   401
 *
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   402
 * *nelems and *nbytes receive the number of elements of array (incl 0)
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   403
 * and total number of bytes (incl. 0)
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   404
 * Note. An empty array will have one null element
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   405
 * But if arg is null, then *nelems set to 0, and *nbytes to 0
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   406
 */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   407
static void arraysize(const char * const *arg, int *nelems, int *nbytes)
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   408
{
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   409
    int i, bytes, count;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   410
    const char * const *a = arg;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   411
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   412
    int *q;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   413
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   414
        *nelems = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   415
        *nbytes = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   416
        return;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   417
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   418
    /* count the array elements and number of bytes */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   419
    for (count=0, bytes=0; *a != 0; count++, a++) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   420
        bytes += strlen(*a)+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   421
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   422
    *nbytes = bytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   423
    *nelems = count+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   424
}
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   425
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   426
/* copy the strings from arg[] into buf, starting at given offset
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   427
 * return new offset to next free byte
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   428
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   429
static int copystrings(char *buf, int offset, const char * const *arg) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   430
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   431
    const char * const *a;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   432
    int count=0;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   433
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   434
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   435
        return offset;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   436
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   437
    for (p=buf+offset, a=arg; *a != 0; a++) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   438
        int len = strlen(*a) +1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   439
        memcpy(p, *a, len);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   440
        p += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   441
        count += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   442
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   443
    return offset+count;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   444
}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   446
/**
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   447
 * We are unusually paranoid; use of vfork is
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   448
 * especially likely to tickle gcc/glibc bugs.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   449
 */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   450
#ifdef __attribute_noinline__  /* See: sys/cdefs.h */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   451
__attribute_noinline__
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   452
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   453
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   454
/* vfork(2) is deprecated on Solaris */
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   455
#ifndef __solaris__
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   456
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   457
vforkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   458
    volatile pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   459
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   460
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   461
     * We separate the call to vfork into a separate function to make
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   462
     * very sure to keep stack of child from corrupting stack of parent,
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   463
     * as suggested by the scary gcc warning:
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   464
     *  warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork'
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   465
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   466
    resultPid = vfork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   467
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   468
    if (resultPid == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   469
        childProcess(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   470
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   471
    assert(resultPid != 0);  /* childProcess never returns */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   472
    return resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   473
}
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   474
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   475
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   476
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   477
forkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   478
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   479
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   480
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   481
     * From Solaris fork(2): In Solaris 10, a call to fork() is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   482
     * identical to a call to fork1(); only the calling thread is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   483
     * replicated in the child process. This is the POSIX-specified
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   484
     * behavior for fork().
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   485
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   486
    resultPid = fork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   487
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   488
    if (resultPid == 0) {
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   489
        childProcess(c);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   490
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   491
    assert(resultPid != 0);  /* childProcess never returns */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   492
    return resultPid;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   493
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   494
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   495
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   496
spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   497
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   498
    jboolean isCopy;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   499
    int i, offset, rval, bufsize, magic;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   500
    char *buf, buf1[16];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   501
    char *hlpargs[2];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   502
    SpawnInfo sp;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   503
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   504
    /* need to tell helper which fd is for receiving the childstuff
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   505
     * and which fd to send response back on
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   506
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   507
    snprintf(buf1, sizeof(buf1), "%d:%d", c->childenv[0], c->fail[1]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   508
    /* put the fd string as argument to the helper cmd */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   509
    hlpargs[0] = buf1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   510
    hlpargs[1] = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   511
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   512
    /* Following items are sent down the pipe to the helper
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   513
     * after it is spawned.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   514
     * All strings are null terminated. All arrays of strings
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   515
     * have an empty string for termination.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   516
     * - the ChildStuff struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   517
     * - the SpawnInfo struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   518
     * - the argv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   519
     * - the envv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   520
     * - the home directory string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   521
     * - the parentPath string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   522
     * - the parentPathv array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   523
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   524
    /* First calculate the sizes */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   525
    arraysize(c->argv, &sp.nargv, &sp.argvBytes);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   526
    bufsize = sp.argvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   527
    arraysize(c->envv, &sp.nenvv, &sp.envvBytes);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   528
    bufsize += sp.envvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   529
    sp.dirlen = c->pdir == 0 ? 0 : strlen(c->pdir)+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   530
    bufsize += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   531
    arraysize(parentPathv, &sp.nparentPathv, &sp.parentPathvBytes);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   532
    bufsize += sp.parentPathvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   533
    /* We need to clear FD_CLOEXEC if set in the fds[].
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   534
     * Files are created FD_CLOEXEC in Java.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   535
     * Otherwise, they will be closed when the target gets exec'd */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   536
    for (i=0; i<3; i++) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   537
        if (c->fds[i] != -1) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   538
            int flags = fcntl(c->fds[i], F_GETFD);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   539
            if (flags & FD_CLOEXEC) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   540
                fcntl(c->fds[i], F_SETFD, flags & (~1));
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   541
            }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   542
        }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   543
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   544
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   545
    rval = posix_spawn(&resultPid, helperpath, 0, 0, (char * const *) hlpargs, environ);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   546
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   547
    if (rval != 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   548
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   549
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   550
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   551
    /* now the lengths are known, copy the data */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   552
    buf = NEW(char, bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   553
    if (buf == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   554
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   555
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   556
    offset = copystrings(buf, 0, &c->argv[0]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   557
    offset = copystrings(buf, offset, &c->envv[0]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   558
    memcpy(buf+offset, c->pdir, sp.dirlen);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   559
    offset += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   560
    offset = copystrings(buf, offset, parentPathv);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   561
    assert(offset == bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   562
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   563
    magic = magicNumber();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   564
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   565
    /* write the two structs and the data buffer */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   566
    write(c->childenv[1], (char *)&magic, sizeof(magic)); // magic number first
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   567
    write(c->childenv[1], (char *)c, sizeof(*c));
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   568
    write(c->childenv[1], (char *)&sp, sizeof(sp));
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   569
    write(c->childenv[1], buf, bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   570
    free(buf);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   571
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   572
    /* In this mode an external main() in invoked which calls back into
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   573
     * childProcess() in this file, rather than directly
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   574
     * via the statement below */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   575
    return resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   576
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   577
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   578
/*
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   579
 * Start a child process running function childProcess.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   580
 * This function only returns in the parent.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   581
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   582
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   583
startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   584
    switch (c->mode) {
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   585
/* vfork(2) is deprecated on Solaris */
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   586
#ifndef __solaris__
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   587
      case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   588
        return vforkChild(c);
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   589
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   590
      case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   591
        return forkChild(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   592
      case MODE_POSIX_SPAWN:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   593
        return spawnChild(env, process, c, helperpath);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   594
      default:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   595
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   596
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   597
}
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   598
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
JNIEXPORT jint JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   600
Java_java_lang_ProcessImpl_forkAndExec(JNIEnv *env,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                                       jobject process,
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   602
                                       jint mode,
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   603
                                       jbyteArray helperpath,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                                       jbyteArray prog,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                                       jbyteArray argBlock, jint argc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                                       jbyteArray envBlock, jint envc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                                       jbyteArray dir,
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   608
                                       jintArray std_fds,
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   609
                                       jboolean redirectErrorStream)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    int errnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    int resultPid = -1;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   613
    int in[2], out[2], err[2], fail[2], childenv[2];
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   614
    jint *fds = NULL;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   615
    const char *phelperpath = NULL;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   616
    const char *pprog = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   617
    const char *pargBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   618
    const char *penvBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   619
    ChildStuff *c;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   622
    childenv[0] = childenv[1] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   624
    if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   625
    c->argv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   626
    c->envv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   627
    c->pdir = NULL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   629
    /* Convert prog + argBlock into a char ** argv.
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   630
     * Add one word room for expansion of argv for use by
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   631
     * execve_as_traditional_shell_script.
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   632
     * This word is also used when using posix_spawn mode
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   633
     */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   634
    assert(prog != NULL && argBlock != NULL);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   635
    if ((phelperpath = getBytes(env, helperpath))   == NULL) goto Catch;
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   636
    if ((pprog       = getBytes(env, prog))         == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   637
    if ((pargBlock   = getBytes(env, argBlock))     == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   638
    if ((c->argv     = NEW(const char *, argc + 3)) == NULL) goto Catch;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   639
    c->argv[0] = pprog;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   640
    c->argc = argc + 2;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   641
    initVectorFromBlock(c->argv+1, pargBlock, argc);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    if (envBlock != NULL) {
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   644
        /* Convert envBlock into a char ** envv */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   645
        if ((penvBlock = getBytes(env, envBlock))   == NULL) goto Catch;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   646
        if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   647
        initVectorFromBlock(c->envv, penvBlock, envc);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   648
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   649
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   650
    if (dir != NULL) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   651
        if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   654
    assert(std_fds != NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   655
    fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   656
    if (fds == NULL) goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   657
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   658
    if ((fds[0] == -1 && pipe(in)  < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   659
        (fds[1] == -1 && pipe(out) < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   660
        (fds[2] == -1 && pipe(err) < 0) ||
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   661
        (pipe(childenv) < 0) ||
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        (pipe(fail) < 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        throwIOException(env, errno, "Bad file descriptor");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
    }
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   666
    c->fds[0] = fds[0];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   667
    c->fds[1] = fds[1];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   668
    c->fds[2] = fds[2];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   670
    copyPipe(in,   c->in);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   671
    copyPipe(out,  c->out);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   672
    copyPipe(err,  c->err);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   673
    copyPipe(fail, c->fail);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   674
    copyPipe(childenv, c->childenv);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   675
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   676
    c->redirectErrorStream = redirectErrorStream;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   677
    c->mode = mode;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   678
55240
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   679
    /* In posix_spawn mode, require the child process to signal aliveness
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   680
     * right after it comes up. This is because there are implementations of
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   681
     * posix_spawn() which do not report failed exec()s back to the caller
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   682
     * (e.g. glibc, see JDK-8223777). In those cases, the fork() will have
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   683
     * worked and successfully started the child process, but the exec() will
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   684
     * have failed. There is no way for us to distinguish this from a target
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   685
     * binary just exiting right after start.
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   686
     *
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   687
     * Note that we could do this additional handshake in all modes but for
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   688
     * prudence only do it when it is needed (in posix_spawn mode). */
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   689
    c->sendAlivePing = (mode == MODE_POSIX_SPAWN) ? 1 : 0;
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   690
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   691
    resultPid = startChild(env, process, c, phelperpath);
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   692
    assert(resultPid != 0);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   693
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    if (resultPid < 0) {
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   695
        switch (c->mode) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   696
          case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   697
            throwIOException(env, errno, "vfork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   698
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   699
          case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   700
            throwIOException(env, errno, "fork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   701
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   702
          case MODE_POSIX_SPAWN:
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   703
            throwIOException(env, errno, "posix_spawn failed");
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   704
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   705
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   708
    close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec  (childproc.c)  */
50
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   709
55240
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   710
    /* If we expect the child to ping aliveness, wait for it. */
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   711
    if (c->sendAlivePing) {
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   712
        switch(readFully(fail[0], &errnum, sizeof(errnum))) {
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   713
        case 0: /* First exec failed; */
55403
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   714
            {
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   715
                int tmpStatus = 0;
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   716
                int p = waitpid(resultPid, &tmpStatus, 0);
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   717
                throwExitCause(env, p, tmpStatus);
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   718
                goto Catch;
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   719
            }
55240
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   720
        case sizeof(errnum):
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   721
            assert(errnum == CHILD_IS_ALIVE);
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   722
            if (errnum != CHILD_IS_ALIVE) {
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   723
                /* Should never happen since the first thing the spawn
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   724
                 * helper should do is to send an alive ping to the parent,
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   725
                 * before doing any subsequent work. */
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   726
                throwIOException(env, 0, "Bad code from spawn helper "
55403
8d50ff464ae5 8226242: Diagnostic output for posix_spawn failure
rriggs
parents: 55240
diff changeset
   727
                                         "(Failed to exec spawn helper)");
55240
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   728
                goto Catch;
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   729
            }
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   730
            break;
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   731
        default:
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   732
            throwIOException(env, errno, "Read failed");
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   733
            goto Catch;
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   734
        }
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   735
    }
57b93b113ec0 8223777: In posix_spawn mode, failing to exec() jspawnhelper does not result in an error
stuefe
parents: 53722
diff changeset
   736
50
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   737
    switch (readFully(fail[0], &errnum, sizeof(errnum))) {
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   738
    case 0: break; /* Exec succeeded */
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   739
    case sizeof(errnum):
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        waitpid(resultPid, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        throwIOException(env, errnum, "Exec failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        goto Catch;
50
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   743
    default:
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   744
        throwIOException(env, errno, "Read failed");
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   745
        goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   748
    fds[0] = (in [1] != -1) ? in [1] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   749
    fds[1] = (out[0] != -1) ? out[0] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   750
    fds[2] = (err[0] != -1) ? err[0] : -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
 Finally:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    /* Always clean up the child's side of the pipes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    closeSafely(in [0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    closeSafely(out[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    closeSafely(err[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   758
    /* Always clean up fail and childEnv descriptors */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
    closeSafely(fail[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    closeSafely(fail[1]);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   761
    closeSafely(childenv[0]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   762
    closeSafely(childenv[1]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   764
    releaseBytes(env, helperpath, phelperpath);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   765
    releaseBytes(env, prog,       pprog);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   766
    releaseBytes(env, argBlock,   pargBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   767
    releaseBytes(env, envBlock,   penvBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   768
    releaseBytes(env, dir,        c->pdir);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   769
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   770
    free(c->argv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   771
    free(c->envv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   772
    free(c);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   774
    if (fds != NULL)
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   775
        (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   776
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    return resultPid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
 Catch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    /* Clean up the parent's side of the pipes in case of failure only */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   781
    closeSafely(in [1]); in[1] = -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   782
    closeSafely(out[0]); out[0] = -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   783
    closeSafely(err[0]); err[0] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    goto Finally;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786