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