jdk/src/java.base/unix/native/libjava/UNIXProcess_md.c
author chegar
Mon, 18 Aug 2014 10:59:36 +0100
changeset 25991 e48157b42439
parent 25980 jdk/src/solaris/native/java/lang/UNIXProcess_md.c@76e7de7a6ef7
parent 25859 jdk/src/solaris/native/java/lang/UNIXProcess_md.c@3317bb8137f4
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
     2
 * Copyright (c) 1995, 2013, 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
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   100
 * Linux and spawn() on other Unix systems, but the code to use clone()
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   101
 * and fork() remains.
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
   102
 */
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   103
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   104
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
setSIGCHLDHandler(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    /* There is a subtle difference between having the signal handler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * for SIGCHLD be SIG_DFL and SIG_IGN.  We cannot obtain process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * termination information for child processes if the signal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * handler is SIG_IGN.  It must be SIG_DFL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * We used to set the SIGCHLD handler only on Linux, but it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * safest to set it unconditionally.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * Consider what happens if java's parent process sets the SIGCHLD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * handler to SIG_IGN.  Normally signal handlers are inherited by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * children, but SIGCHLD is a controversial case.  Solaris appears
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * to always reset it to SIG_DFL, but this behavior may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * non-standard-compliant, and we shouldn't rely on it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * References:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    struct sigaction sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    sa.sa_handler = SIG_DFL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    sigemptyset(&sa.sa_mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    if (sigaction(SIGCHLD, &sa, NULL) < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
static void*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
xmalloc(JNIEnv *env, size_t size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    void *p = malloc(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    if (p == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        JNU_ThrowOutOfMemoryError(env, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    return p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 * If PATH is not defined, the OS provides some default value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * Unfortunately, there's no portable way to get this value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 * Fortunately, it's only needed if the child has PATH while we do not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
defaultPath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
#ifdef __solaris__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    /* These really are the Solaris defaults! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    return (geteuid() == 0 || getuid() == 0) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    return ":/bin:/usr/bin";    /* glibc */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
effectivePath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    const char *s = getenv("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    return (s != NULL) ? s : defaultPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
countOccurrences(const char *s, char c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    int count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    for (count = 0; *s != '\0'; s++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        count += (*s == c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
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
   180
effectivePathv(JNIEnv *env)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   182
    char *p;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    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
   184
    const char *path = effectivePath();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    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
   186
    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
   187
    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
   188
    const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   190
    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
   191
        return NULL;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   192
    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
   193
    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
   194
    /* 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
   195
    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
   196
        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
   197
        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
   198
        *q = '\0';
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   199
        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
   200
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    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
   202
    return pathv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
JNIEXPORT void JNICALL
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   206
Java_java_lang_UNIXProcess_init(JNIEnv *env, jclass clazz)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   208
    parentPathv = effectivePathv(env);
22641
e47f8892133e 8033372: Check jdk/src/share/native/java/lang for JNI pending exception issues
alanb
parents: 22597
diff changeset
   209
    CHECK_NULL(parentPathv);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    setSIGCHLDHandler(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
#ifndef WIFEXITED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
#define WIFEXITED(status) (((status)&0xFF) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
#ifndef WEXITSTATUS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
#define WEXITSTATUS(status) (((status)>>8)&0xFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
#ifndef WIFSIGNALED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
#ifndef WTERMSIG
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
#define WTERMSIG(status) ((status)&0x7F)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
/* Block until a child process exits and return its exit code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
   Note, can only be called once for any given pid. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
JNIEXPORT jint JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                                              jobject junk,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                                              jint pid)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    /* We used to use waitid() on Solaris, waitpid() on Linux, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * waitpid() is more standard, so use it on all POSIX platforms. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    int status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    /* Wait for the child process to exit.  This returns immediately if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
       the child has already exited. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    while (waitpid(pid, &status, 0) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        switch (errno) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        case ECHILD: return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        case EINTR: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        default: return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    if (WIFEXITED(status)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
         * The child exited normally; get its exit code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        return WEXITSTATUS(status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    } else if (WIFSIGNALED(status)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        /* The child exited because of a signal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
         * The best value to return is 0x80 + signal number,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
         * because that is what all Unix shells do, and because
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
         * it allows callers to distinguish between process exit and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
         * process death by signal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
         * Unfortunately, the historical behavior on Solaris is to return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
         * the signal number, and we preserve this for compatibility. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
#ifdef __solaris__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        return WTERMSIG(status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        return 0x80 + WTERMSIG(status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
         * Unknown exit code; pass it through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        return status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
static const char *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
getBytes(JNIEnv *env, jbyteArray arr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    return arr == NULL ? NULL :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    if (parr != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    static const char * const format = "error=%d, %s";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    const char *detail = defaultDetail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    char *errmsg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    jstring s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    if (errnum != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        const char *s = strerror(errnum);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        if (strcmp(s, "Unknown error") != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            detail = s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   305
    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
   306
        return;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   307
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    sprintf(errmsg, format, errnum, detail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    s = JNU_NewStringPlatform(env, errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    if (s != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        jobject x = JNU_NewObjectByName(env, "java/io/IOException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                                        "(Ljava/lang/String;)V", s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        if (x != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            (*env)->Throw(env, x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    free(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
#ifdef DEBUG_PROCESS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
/* Debugging process code is difficult; where to write debug output? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
debugPrint(char *format, ...)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    FILE *tty = fopen("/dev/tty", "w");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    va_list ap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    va_start(ap, format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    vfprintf(tty, format, ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    va_end(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    fclose(tty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
#endif /* DEBUG_PROCESS */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   333
static void
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   334
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
   335
{
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   336
    to[0] = from[0];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   337
    to[1] = from[1];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   338
}
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   339
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   340
/* 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
   341
 * by a null element.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   342
 *
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   343
 * *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
   344
 * 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
   345
 * 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
   346
 * 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
   347
 */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   348
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
   349
{
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   350
    int i, bytes, count;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   351
    const char * const *a = arg;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   352
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   353
    int *q;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   354
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   355
        *nelems = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   356
        *nbytes = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   357
        return;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   358
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   359
    /* 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
   360
    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
   361
        bytes += strlen(*a)+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   362
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   363
    *nbytes = bytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   364
    *nelems = count+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   365
}
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   366
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   367
/* 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
   368
 * 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
   369
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   370
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
   371
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   372
    const char * const *a;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   373
    int count=0;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   374
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   375
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   376
        return offset;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   377
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   378
    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
   379
        int len = strlen(*a) +1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   380
        memcpy(p, *a, len);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   381
        p += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   382
        count += len;
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
    return offset+count;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   385
}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   387
/**
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   388
 * We are unusually paranoid; use of clone/vfork is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   389
 * 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
   390
 */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   391
#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
   392
__attribute_noinline__
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   393
#endif
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   394
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   395
#define START_CHILD_USE_CLONE 0  /* clone() currently disabled; see above. */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   396
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   397
#ifdef START_CHILD_USE_CLONE
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   398
static pid_t
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   399
cloneChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   400
#ifdef __linux__
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   401
#define START_CHILD_CLONE_STACK_SIZE (64 * 1024)
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   402
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   403
     * See clone(2).
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   404
     * Instead of worrying about which direction the stack grows, just
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   405
     * allocate twice as much and start the stack in the middle.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   406
     */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   407
    if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL)
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   408
        /* errno will be set to ENOMEM */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   409
        return -1;
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   410
    return clone(childProcess,
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   411
                 c->clone_stack + START_CHILD_CLONE_STACK_SIZE,
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   412
                 CLONE_VFORK | CLONE_VM | SIGCHLD, c);
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   413
#else
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   414
/* not available on Solaris / Mac */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   415
    assert(0);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   416
    return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   417
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   418
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   419
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   420
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   421
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   422
vforkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   423
    volatile pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   424
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   425
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   426
     * 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
   427
     * 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
   428
     * 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
   429
     *  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
   430
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   431
    resultPid = vfork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   432
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   433
    if (resultPid == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   434
        childProcess(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   435
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   436
    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
   437
    return resultPid;
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
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   441
forkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   442
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   443
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   444
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   445
     * 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
   446
     * 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
   447
     * 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
   448
     * behavior for fork().
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   449
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   450
    resultPid = fork();
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
    if (resultPid == 0) {
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   453
        childProcess(c);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   454
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   455
    assert(resultPid != 0);  /* childProcess never returns */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   456
    return resultPid;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   457
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   458
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
   459
#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
   460
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   461
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
   462
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   463
    jboolean isCopy;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   464
    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
   465
    char *buf, buf1[16];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   466
    char *hlpargs[2];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   467
    SpawnInfo sp;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   468
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   469
    /* 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
   470
     * 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
   471
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   472
    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
   473
    /* 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
   474
    hlpargs[0] = buf1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   475
    hlpargs[1] = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   476
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   477
    /* 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
   478
     * after it is spawned.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   479
     * 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
   480
     * 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
   481
     * - the ChildStuff struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   482
     * - the SpawnInfo struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   483
     * - the argv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   484
     * - the envv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   485
     * - the home directory string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   486
     * - the parentPath string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   487
     * - the parentPathv array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   488
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   489
    /* First calculate the sizes */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   490
    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
   491
    bufsize = sp.argvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   492
    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
   493
    bufsize += sp.envvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   494
    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
   495
    bufsize += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   496
    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
   497
    bufsize += sp.parentPathvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   498
    /* 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
   499
     * 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
   500
     * 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
   501
    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
   502
        if (c->fds[i] != -1) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   503
            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
   504
            if (flags & FD_CLOEXEC) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   505
                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
   506
            }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   507
        }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   508
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   509
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   510
    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
   511
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   512
    if (rval != 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   513
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   514
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   515
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   516
    /* 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
   517
    buf = NEW(char, bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   518
    if (buf == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   519
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   520
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   521
    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
   522
    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
   523
    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
   524
    offset += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   525
    offset = copystrings(buf, offset, parentPathv);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   526
    assert(offset == bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   527
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   528
    magic = magicNumber();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   529
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   530
    /* 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
   531
    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
   532
    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
   533
    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
   534
    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
   535
    free(buf);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   536
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   537
    /* 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
   538
     * 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
   539
     * via the statement below */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   540
    return resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   541
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   542
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   543
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   544
/*
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   545
 * 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
   546
 * 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
   547
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   548
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   549
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
   550
    switch (c->mode) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   551
      case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   552
        return vforkChild(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   553
      case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   554
        return forkChild(c);
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
   555
#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
   556
      case MODE_POSIX_SPAWN:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   557
        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
   558
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   559
      default:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   560
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   561
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   562
}
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   563
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
JNIEXPORT jint JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                                       jobject process,
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   567
                                       jint mode,
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   568
                                       jbyteArray helperpath,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                                       jbyteArray prog,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                                       jbyteArray argBlock, jint argc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                                       jbyteArray envBlock, jint envc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                                       jbyteArray dir,
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   573
                                       jintArray std_fds,
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   574
                                       jboolean redirectErrorStream)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    int errnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    int resultPid = -1;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   578
    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
   579
    jint *fds = NULL;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   580
    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
   581
    const char *pprog = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   582
    const char *pargBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   583
    const char *penvBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   584
    ChildStuff *c;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    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
   587
    childenv[0] = childenv[1] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   589
    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
   590
    c->argv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   591
    c->envv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   592
    c->pdir = NULL;
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   593
    c->clone_stack = NULL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   595
    /* 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
   596
     * 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
   597
     * execve_as_traditional_shell_script.
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   598
     * This word is also used when using spawn mode
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   599
     */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   600
    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
   601
    if ((phelperpath = getBytes(env, helperpath))   == NULL) goto Catch;
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   602
    if ((pprog       = getBytes(env, prog))         == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   603
    if ((pargBlock   = getBytes(env, argBlock))     == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   604
    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
   605
    c->argv[0] = pprog;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   606
    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
   607
    initVectorFromBlock(c->argv+1, pargBlock, argc);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    if (envBlock != NULL) {
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   610
        /* 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
   611
        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
   612
        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
   613
        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
   614
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   615
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   616
    if (dir != NULL) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   617
        if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   620
    assert(std_fds != NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   621
    fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   622
    if (fds == NULL) goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   623
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   624
    if ((fds[0] == -1 && pipe(in)  < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   625
        (fds[1] == -1 && pipe(out) < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   626
        (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
   627
        (pipe(childenv) < 0) ||
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        (pipe(fail) < 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        throwIOException(env, errno, "Bad file descriptor");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    }
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   632
    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
   633
    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
   634
    c->fds[2] = fds[2];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   636
    copyPipe(in,   c->in);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   637
    copyPipe(out,  c->out);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   638
    copyPipe(err,  c->err);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   639
    copyPipe(fail, c->fail);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   640
    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
   641
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   642
    c->redirectErrorStream = redirectErrorStream;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   643
    c->mode = mode;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   644
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   645
    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
   646
    assert(resultPid != 0);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   647
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    if (resultPid < 0) {
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   649
        switch (c->mode) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   650
          case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   651
            throwIOException(env, errno, "vfork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   652
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   653
          case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   654
            throwIOException(env, errno, "fork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   655
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   656
          case MODE_POSIX_SPAWN:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   657
            throwIOException(env, errno, "spawn failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   658
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   659
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   662
    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
   663
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   664
    switch (readFully(fail[0], &errnum, sizeof(errnum))) {
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   665
    case 0: break; /* Exec succeeded */
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   666
    case sizeof(errnum):
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        waitpid(resultPid, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        throwIOException(env, errnum, "Exec failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        goto Catch;
50
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   670
    default:
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   671
        throwIOException(env, errno, "Read failed");
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   672
        goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   675
    fds[0] = (in [1] != -1) ? in [1] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   676
    fds[1] = (out[0] != -1) ? out[0] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   677
    fds[2] = (err[0] != -1) ? err[0] : -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
 Finally:
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   680
    free(c->clone_stack);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   681
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
    /* Always clean up the child's side of the pipes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    closeSafely(in [0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    closeSafely(out[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
    closeSafely(err[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   687
    /* Always clean up fail and childEnv descriptors */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    closeSafely(fail[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    closeSafely(fail[1]);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   690
    closeSafely(childenv[0]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   691
    closeSafely(childenv[1]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   693
    releaseBytes(env, helperpath, phelperpath);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   694
    releaseBytes(env, prog,       pprog);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   695
    releaseBytes(env, argBlock,   pargBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   696
    releaseBytes(env, envBlock,   penvBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   697
    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
   698
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   699
    free(c->argv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   700
    free(c->envv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   701
    free(c);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   703
    if (fds != NULL)
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   704
        (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   705
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    return resultPid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
 Catch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
    /* 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
   710
    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
   711
    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
   712
    closeSafely(err[0]); err[0] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    goto Finally;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
JNIEXPORT void JNICALL
13149
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   717
Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env,
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   718
                                          jobject junk,
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   719
                                          jint pid,
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   720
                                          jboolean force)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
{
13149
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   722
    int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM;
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   723
    kill(pid, sig);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
}