src/java.base/unix/native/libjava/ProcessImpl_md.c
author erikj
Tue, 12 Sep 2017 19:03:39 +0200
changeset 47216 71c04702a3d5
parent 41107 jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c@567f832618d7
child 52364 750b500ef4de
permissions -rw-r--r--
8187443: Forest Consolidation: Move files to unified layout Reviewed-by: darcy, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
     2
 * Copyright (c) 1995, 2015, 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
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
    47
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    48
#include <spawn.h>
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 11691
diff changeset
    49
#endif
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 11691
diff changeset
    50
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    51
#include "childproc.h"
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    52
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
    53
/*
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    54
 * There are 4 possible strategies we might use to "fork":
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    55
 *
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    56
 * - fork(2).  Very portable and reliable but subject to
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    57
 *   failure due to overcommit (see the documentation on
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    58
 *   /proc/sys/vm/overcommit_memory in Linux proc(5)).
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    59
 *   This is the ancient problem of spurious failure whenever a large
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    60
 *   process starts a small subprocess.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    61
 *
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    62
 * - vfork().  Using this is scary because all relevant man pages
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    63
 *   contain dire warnings, e.g. Linux vfork(2).  But at least it's
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    64
 *   documented in the glibc docs and is standardized by XPG4.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    65
 *   http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    66
 *   On Linux, one might think that vfork() would be implemented using
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    67
 *   the clone system call with flag CLONE_VFORK, but in fact vfork is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    68
 *   a separate system call (which is a good sign, suggesting that
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    69
 *   vfork will continue to be supported at least on Linux).
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    70
 *   Another good sign is that glibc implements posix_spawn using
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    71
 *   vfork whenever possible.  Note that we cannot use posix_spawn
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    72
 *   ourselves because there's no reliable way to close all inherited
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    73
 *   file descriptors.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    74
 *
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    75
 * - clone() with flags CLONE_VM but not CLONE_THREAD.  clone() is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    76
 *   Linux-specific, but this ought to work - at least the glibc
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    77
 *   sources contain code to handle different combinations of CLONE_VM
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    78
 *   and CLONE_THREAD.  However, when this was implemented, it
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    79
 *   appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    80
 *   the simple program
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    81
 *     Runtime.getRuntime().exec("/bin/true").waitFor();
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    82
 *   with:
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    83
 *     #  Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    84
 *     #  Error: pthread_getattr_np failed with errno = 3 (ESRCH)
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    85
 *   We believe this is a glibc bug, reported here:
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    86
 *     http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    87
 *   but the glibc maintainers closed it as WONTFIX.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    88
 *
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    89
 * - posix_spawn(). While posix_spawn() is a fairly elaborate and
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    90
 *   complicated system call, it can't quite do everything that the old
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    91
 *   fork()/exec() combination can do, so the only feasible way to do
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    92
 *   this, is to use posix_spawn to launch a new helper executable
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    93
 *   "jprochelper", which in turn execs the target (after cleaning
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    94
 *   up file-descriptors etc.) The end result is the same as before,
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    95
 *   a child process linked to the parent in the same way, but it
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    96
 *   avoids the problem of duplicating the parent (VM) process
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    97
 *   address space temporarily, before launching the target command.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    98
 *
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    99
 * Based on the above analysis, we are currently using vfork() on
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   100
 * Linux and posix_spawn() on other Unix systems.
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
   101
 */
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   102
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   103
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
setSIGCHLDHandler(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    /* There is a subtle difference between having the signal handler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * for SIGCHLD be SIG_DFL and SIG_IGN.  We cannot obtain process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * termination information for child processes if the signal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * handler is SIG_IGN.  It must be SIG_DFL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * We used to set the SIGCHLD handler only on Linux, but it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * safest to set it unconditionally.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Consider what happens if java's parent process sets the SIGCHLD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * handler to SIG_IGN.  Normally signal handlers are inherited by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * children, but SIGCHLD is a controversial case.  Solaris appears
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * to always reset it to SIG_DFL, but this behavior may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * non-standard-compliant, and we shouldn't rely on it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * References:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    struct sigaction sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    sa.sa_handler = SIG_DFL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    sigemptyset(&sa.sa_mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    if (sigaction(SIGCHLD, &sa, NULL) < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
static void*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
xmalloc(JNIEnv *env, size_t size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    void *p = malloc(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    if (p == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        JNU_ThrowOutOfMemoryError(env, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    return p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * If PATH is not defined, the OS provides some default value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 * Unfortunately, there's no portable way to get this value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * Fortunately, it's only needed if the child has PATH while we do not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
defaultPath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
#ifdef __solaris__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /* These really are the Solaris defaults! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    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
   155
        "/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
   156
        "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    return ":/bin:/usr/bin";    /* glibc */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
effectivePath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    const char *s = getenv("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    return (s != NULL) ? s : defaultPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
countOccurrences(const char *s, char c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    int count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    for (count = 0; *s != '\0'; s++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        count += (*s == c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
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
   179
effectivePathv(JNIEnv *env)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   181
    char *p;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    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
   183
    const char *path = effectivePath();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    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
   185
    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
   186
    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
   187
    const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   189
    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
   190
        return NULL;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   191
    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
   192
    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
   193
    /* 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
   194
    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
   195
        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
   196
        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
   197
        *q = '\0';
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   198
        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
   199
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    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
   201
    return pathv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
JNIEXPORT void JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   205
Java_java_lang_ProcessImpl_init(JNIEnv *env, jclass clazz)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   207
    parentPathv = effectivePathv(env);
22641
e47f8892133e 8033372: Check jdk/src/share/native/java/lang for JNI pending exception issues
alanb
parents: 22597
diff changeset
   208
    CHECK_NULL(parentPathv);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    setSIGCHLDHandler(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
#ifndef WIFEXITED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
#define WIFEXITED(status) (((status)&0xFF) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
#ifndef WEXITSTATUS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
#define WEXITSTATUS(status) (((status)>>8)&0xFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
#ifndef WIFSIGNALED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
#ifndef WTERMSIG
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
#define WTERMSIG(status) ((status)&0x7F)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
static const char *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
getBytes(JNIEnv *env, jbyteArray arr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    return arr == NULL ? NULL :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    if (parr != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   243
#define IOE_FORMAT "error=%d, %s"
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   244
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    const char *detail = defaultDetail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    char *errmsg;
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   250
    size_t fmtsize;
32846
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   251
    char tmpbuf[1024];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    jstring s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    if (errnum != 0) {
32846
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   255
        int ret = getErrorString(errnum, tmpbuf, sizeof(tmpbuf));
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   256
        if (ret != EINVAL)
5383225ebd0d 8133249: Occasional SIGSEGV: non thread-safe use of strerr in getLastErrorString
robm
parents: 30899
diff changeset
   257
            detail = tmpbuf;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    /* 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
   260
    fmtsize = sizeof(IOE_FORMAT) + strlen(detail) + 3 * sizeof(errnum);
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   261
    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
   262
    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
   263
        return;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   264
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   265
    snprintf(errmsg, fmtsize, IOE_FORMAT, errnum, detail);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    s = JNU_NewStringPlatform(env, errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    if (s != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        jobject x = JNU_NewObjectByName(env, "java/io/IOException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                                        "(Ljava/lang/String;)V", s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        if (x != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            (*env)->Throw(env, x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    free(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
#ifdef DEBUG_PROCESS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
/* Debugging process code is difficult; where to write debug output? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
debugPrint(char *format, ...)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    FILE *tty = fopen("/dev/tty", "w");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    va_list ap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    va_start(ap, format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    vfprintf(tty, format, ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    va_end(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    fclose(tty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
#endif /* DEBUG_PROCESS */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   290
static void
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   291
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
   292
{
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   293
    to[0] = from[0];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   294
    to[1] = from[1];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   295
}
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   296
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   297
/* 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
   298
 * by a null element.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   299
 *
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   300
 * *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
   301
 * 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
   302
 * 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
   303
 * 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
   304
 */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   305
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
   306
{
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   307
    int i, bytes, count;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   308
    const char * const *a = arg;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   309
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   310
    int *q;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   311
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   312
        *nelems = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   313
        *nbytes = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   314
        return;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   315
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   316
    /* 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
   317
    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
   318
        bytes += strlen(*a)+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   319
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   320
    *nbytes = bytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   321
    *nelems = count+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   322
}
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   323
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   324
/* 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
   325
 * 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
   326
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   327
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
   328
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   329
    const char * const *a;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   330
    int count=0;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   331
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   332
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   333
        return offset;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   334
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   335
    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
   336
        int len = strlen(*a) +1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   337
        memcpy(p, *a, len);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   338
        p += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   339
        count += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   340
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   341
    return offset+count;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   342
}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   344
/**
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   345
 * 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
   346
 * 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
   347
 */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   348
#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
   349
__attribute_noinline__
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   350
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   351
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   352
/* vfork(2) is deprecated on Solaris */
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   353
#ifndef __solaris__
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   354
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   355
vforkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   356
    volatile pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   357
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   358
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   359
     * 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
   360
     * 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
   361
     * 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
   362
     *  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
   363
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   364
    resultPid = vfork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   365
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   366
    if (resultPid == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   367
        childProcess(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   368
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   369
    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
   370
    return resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   371
}
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   372
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   373
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   374
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   375
forkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   376
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   377
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   378
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   379
     * 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
   380
     * 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
   381
     * 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
   382
     * behavior for fork().
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   383
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   384
    resultPid = fork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   385
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   386
    if (resultPid == 0) {
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   387
        childProcess(c);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   388
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   389
    assert(resultPid != 0);  /* childProcess never returns */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   390
    return resultPid;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   391
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   392
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
   393
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   394
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   395
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
   396
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   397
    jboolean isCopy;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   398
    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
   399
    char *buf, buf1[16];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   400
    char *hlpargs[2];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   401
    SpawnInfo sp;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   402
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   403
    /* 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
   404
     * 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
   405
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   406
    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
   407
    /* 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
   408
    hlpargs[0] = buf1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   409
    hlpargs[1] = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   410
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   411
    /* 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
   412
     * after it is spawned.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   413
     * 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
   414
     * 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
   415
     * - the ChildStuff struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   416
     * - the SpawnInfo struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   417
     * - the argv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   418
     * - the envv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   419
     * - the home directory string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   420
     * - the parentPath string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   421
     * - the parentPathv array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   422
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   423
    /* First calculate the sizes */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   424
    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
   425
    bufsize = sp.argvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   426
    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
   427
    bufsize += sp.envvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   428
    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
   429
    bufsize += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   430
    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
   431
    bufsize += sp.parentPathvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   432
    /* 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
   433
     * 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
   434
     * 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
   435
    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
   436
        if (c->fds[i] != -1) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   437
            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
   438
            if (flags & FD_CLOEXEC) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   439
                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
   440
            }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   441
        }
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
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   444
    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
   445
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   446
    if (rval != 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   447
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   448
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   449
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   450
    /* 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
   451
    buf = NEW(char, bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   452
    if (buf == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   453
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   454
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   455
    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
   456
    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
   457
    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
   458
    offset += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   459
    offset = copystrings(buf, offset, parentPathv);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   460
    assert(offset == bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   461
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   462
    magic = magicNumber();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   463
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   464
    /* 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
   465
    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
   466
    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
   467
    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
   468
    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
   469
    free(buf);
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
    /* 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
   472
     * 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
   473
     * via the statement below */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   474
    return resultPid;
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
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   477
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   478
/*
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   479
 * 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
   480
 * 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
   481
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   482
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   483
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
   484
    switch (c->mode) {
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   485
/* vfork(2) is deprecated on Solaris */
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   486
#ifndef __solaris__
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   487
      case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   488
        return vforkChild(c);
40745
6d7a656b1612 8161360: Deprecated vfork() should not be used on Solaris
alanbur
parents: 32846
diff changeset
   489
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   490
      case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   491
        return forkChild(c);
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
   492
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   493
      case MODE_POSIX_SPAWN:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   494
        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
   495
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   496
      default:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   497
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   498
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   499
}
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   500
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
JNIEXPORT jint JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   502
Java_java_lang_ProcessImpl_forkAndExec(JNIEnv *env,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                                       jobject process,
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   504
                                       jint mode,
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   505
                                       jbyteArray helperpath,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                                       jbyteArray prog,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                                       jbyteArray argBlock, jint argc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                                       jbyteArray envBlock, jint envc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                                       jbyteArray dir,
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   510
                                       jintArray std_fds,
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   511
                                       jboolean redirectErrorStream)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    int errnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    int resultPid = -1;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   515
    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
   516
    jint *fds = NULL;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   517
    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
   518
    const char *pprog = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   519
    const char *pargBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   520
    const char *penvBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   521
    ChildStuff *c;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    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
   524
    childenv[0] = childenv[1] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   526
    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
   527
    c->argv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   528
    c->envv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   529
    c->pdir = NULL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   531
    /* 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
   532
     * 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
   533
     * execve_as_traditional_shell_script.
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   534
     * 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
   535
     */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   536
    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
   537
    if ((phelperpath = getBytes(env, helperpath))   == NULL) goto Catch;
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   538
    if ((pprog       = getBytes(env, prog))         == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   539
    if ((pargBlock   = getBytes(env, argBlock))     == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   540
    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
   541
    c->argv[0] = pprog;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   542
    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
   543
    initVectorFromBlock(c->argv+1, pargBlock, argc);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    if (envBlock != NULL) {
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   546
        /* 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
   547
        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
   548
        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
   549
        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
   550
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   551
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   552
    if (dir != NULL) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   553
        if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   556
    assert(std_fds != NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   557
    fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   558
    if (fds == NULL) goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   559
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   560
    if ((fds[0] == -1 && pipe(in)  < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   561
        (fds[1] == -1 && pipe(out) < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   562
        (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
   563
        (pipe(childenv) < 0) ||
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        (pipe(fail) < 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        throwIOException(env, errno, "Bad file descriptor");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    }
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   568
    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
   569
    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
   570
    c->fds[2] = fds[2];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   572
    copyPipe(in,   c->in);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   573
    copyPipe(out,  c->out);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   574
    copyPipe(err,  c->err);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   575
    copyPipe(fail, c->fail);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   576
    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
   577
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   578
    c->redirectErrorStream = redirectErrorStream;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   579
    c->mode = mode;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   580
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   581
    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
   582
    assert(resultPid != 0);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   583
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    if (resultPid < 0) {
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   585
        switch (c->mode) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   586
          case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   587
            throwIOException(env, errno, "vfork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   588
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   589
          case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   590
            throwIOException(env, errno, "fork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   591
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   592
          case MODE_POSIX_SPAWN:
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   593
            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
   594
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   595
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   598
    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
   599
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   600
    switch (readFully(fail[0], &errnum, sizeof(errnum))) {
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   601
    case 0: break; /* Exec succeeded */
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   602
    case sizeof(errnum):
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        waitpid(resultPid, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        throwIOException(env, errnum, "Exec failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        goto Catch;
50
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   606
    default:
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   607
        throwIOException(env, errno, "Read failed");
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   608
        goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   611
    fds[0] = (in [1] != -1) ? in [1] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   612
    fds[1] = (out[0] != -1) ? out[0] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   613
    fds[2] = (err[0] != -1) ? err[0] : -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
 Finally:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    /* Always clean up the child's side of the pipes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    closeSafely(in [0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    closeSafely(out[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    closeSafely(err[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   621
    /* Always clean up fail and childEnv descriptors */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    closeSafely(fail[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    closeSafely(fail[1]);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   624
    closeSafely(childenv[0]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   625
    closeSafely(childenv[1]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   627
    releaseBytes(env, helperpath, phelperpath);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   628
    releaseBytes(env, prog,       pprog);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   629
    releaseBytes(env, argBlock,   pargBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   630
    releaseBytes(env, envBlock,   penvBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   631
    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
   632
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   633
    free(c->argv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   634
    free(c->envv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   635
    free(c);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   637
    if (fds != NULL)
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   638
        (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   639
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    return resultPid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
 Catch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    /* 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
   644
    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
   645
    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
   646
    closeSafely(err[0]); err[0] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    goto Finally;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649