jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c
author rriggs
Fri, 22 May 2015 10:12:18 -0400
changeset 30784 28105f71beb2
parent 29724 638809ff54f3
child 30899 d2408e757489
permissions -rw-r--r--
8074818: Resolve disabled warnings for libjava 8080007: Stop ignoring warnings for libjava Reviewed-by: alanb, erikj
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
     2
 * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3431
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#undef  _LARGEFILE64_SOURCE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#define _LARGEFILE64_SOURCE 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include "jni.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include "jvm.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "jvm_md.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "jni_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
#include "io_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * Platform-specific support for java.lang.Process
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
#include <assert.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
#include <stddef.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
#include <sys/types.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
#include <ctype.h>
11691
ff8aec7600fe 7133301: (process) UNIXProcess_md.c should include sys/wait.h rather than wait.h
ngmr
parents: 5506
diff changeset
    43
#include <sys/wait.h>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
#include <signal.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
    47
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    48
#include <spawn.h>
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 11691
diff changeset
    49
#endif
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 11691
diff changeset
    50
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    51
#include "childproc.h"
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    52
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
    53
/*
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    54
 * There are 4 possible strategies we might use to "fork":
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    55
 *
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    56
 * - fork(2).  Very portable and reliable but subject to
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    57
 *   failure due to overcommit (see the documentation on
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    58
 *   /proc/sys/vm/overcommit_memory in Linux proc(5)).
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    59
 *   This is the ancient problem of spurious failure whenever a large
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    60
 *   process starts a small subprocess.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    61
 *
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    62
 * - vfork().  Using this is scary because all relevant man pages
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    63
 *   contain dire warnings, e.g. Linux vfork(2).  But at least it's
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    64
 *   documented in the glibc docs and is standardized by XPG4.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    65
 *   http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    66
 *   On Linux, one might think that vfork() would be implemented using
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    67
 *   the clone system call with flag CLONE_VFORK, but in fact vfork is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    68
 *   a separate system call (which is a good sign, suggesting that
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    69
 *   vfork will continue to be supported at least on Linux).
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    70
 *   Another good sign is that glibc implements posix_spawn using
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    71
 *   vfork whenever possible.  Note that we cannot use posix_spawn
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    72
 *   ourselves because there's no reliable way to close all inherited
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    73
 *   file descriptors.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    74
 *
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    75
 * - clone() with flags CLONE_VM but not CLONE_THREAD.  clone() is
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    76
 *   Linux-specific, but this ought to work - at least the glibc
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    77
 *   sources contain code to handle different combinations of CLONE_VM
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    78
 *   and CLONE_THREAD.  However, when this was implemented, it
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    79
 *   appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    80
 *   the simple program
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    81
 *     Runtime.getRuntime().exec("/bin/true").waitFor();
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    82
 *   with:
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    83
 *     #  Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    84
 *     #  Error: pthread_getattr_np failed with errno = 3 (ESRCH)
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    85
 *   We believe this is a glibc bug, reported here:
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    86
 *     http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    87
 *   but the glibc maintainers closed it as WONTFIX.
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    88
 *
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    89
 * - posix_spawn(). While posix_spawn() is a fairly elaborate and
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    90
 *   complicated system call, it can't quite do everything that the old
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    91
 *   fork()/exec() combination can do, so the only feasible way to do
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    92
 *   this, is to use posix_spawn to launch a new helper executable
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    93
 *   "jprochelper", which in turn execs the target (after cleaning
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    94
 *   up file-descriptors etc.) The end result is the same as before,
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    95
 *   a child process linked to the parent in the same way, but it
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    96
 *   avoids the problem of duplicating the parent (VM) process
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    97
 *   address space temporarily, before launching the target command.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
    98
 *
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
    99
 * Based on the above analysis, we are currently using vfork() on
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   100
 * Linux and posix_spawn() on other Unix systems.
2948
7f4d7737d38f 6853336: (process) disable or remove clone-exec feature (6850720)
tbell
parents: 2946
diff changeset
   101
 */
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   102
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   103
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
setSIGCHLDHandler(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    /* There is a subtle difference between having the signal handler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * for SIGCHLD be SIG_DFL and SIG_IGN.  We cannot obtain process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * termination information for child processes if the signal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * handler is SIG_IGN.  It must be SIG_DFL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * We used to set the SIGCHLD handler only on Linux, but it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * safest to set it unconditionally.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Consider what happens if java's parent process sets the SIGCHLD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * handler to SIG_IGN.  Normally signal handlers are inherited by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * children, but SIGCHLD is a controversial case.  Solaris appears
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * to always reset it to SIG_DFL, but this behavior may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * non-standard-compliant, and we shouldn't rely on it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * References:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    struct sigaction sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    sa.sa_handler = SIG_DFL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    sigemptyset(&sa.sa_mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    if (sigaction(SIGCHLD, &sa, NULL) < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
static void*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
xmalloc(JNIEnv *env, size_t size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    void *p = malloc(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    if (p == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        JNU_ThrowOutOfMemoryError(env, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    return p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * If PATH is not defined, the OS provides some default value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 * Unfortunately, there's no portable way to get this value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * Fortunately, it's only needed if the child has PATH while we do not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
defaultPath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
#ifdef __solaris__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /* These really are the Solaris defaults! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    return (geteuid() == 0 || getuid() == 0) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    return ":/bin:/usr/bin";    /* glibc */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
static const char*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
effectivePath(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    const char *s = getenv("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    return (s != NULL) ? s : defaultPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
countOccurrences(const char *s, char c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    int count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    for (count = 0; *s != '\0'; s++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        count += (*s == c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
static const char * const *
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   179
effectivePathv(JNIEnv *env)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   181
    char *p;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    int i;
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   183
    const char *path = effectivePath();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    int count = countOccurrences(path, ':') + 1;
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   185
    size_t pathvsize = sizeof(const char *) * (count+1);
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   186
    size_t pathsize = strlen(path) + 1;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   187
    const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   189
    if (pathv == NULL)
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   190
        return NULL;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   191
    p = (char *) pathv + pathvsize;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   192
    memcpy(p, path, pathsize);
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   193
    /* split PATH by replacing ':' with NULs; empty components => "." */
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   194
    for (i = 0; i < count; i++) {
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   195
        char *q = p + strcspn(p, ":");
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   196
        pathv[i] = (p == q) ? "." : p;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   197
        *q = '\0';
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   198
        p = q + 1;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   199
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    pathv[count] = NULL;
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   201
    return pathv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
JNIEXPORT void JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   205
Java_java_lang_ProcessImpl_init(JNIEnv *env, jclass clazz)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
{
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   207
    parentPathv = effectivePathv(env);
22641
e47f8892133e 8033372: Check jdk/src/share/native/java/lang for JNI pending exception issues
alanb
parents: 22597
diff changeset
   208
    CHECK_NULL(parentPathv);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    setSIGCHLDHandler(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
#ifndef WIFEXITED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
#define WIFEXITED(status) (((status)&0xFF) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
#ifndef WEXITSTATUS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
#define WEXITSTATUS(status) (((status)>>8)&0xFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
#ifndef WIFSIGNALED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
#ifndef WTERMSIG
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
#define WTERMSIG(status) ((status)&0x7F)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
/* Block until a child process exits and return its exit code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
   Note, can only be called once for any given pid. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
JNIEXPORT jint JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   232
Java_java_lang_ProcessImpl_waitForProcessExit(JNIEnv* env,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                                              jobject junk,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                                              jint pid)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    /* We used to use waitid() on Solaris, waitpid() on Linux, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * waitpid() is more standard, so use it on all POSIX platforms. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    int status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    /* Wait for the child process to exit.  This returns immediately if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
       the child has already exited. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    while (waitpid(pid, &status, 0) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        switch (errno) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        case ECHILD: return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        case EINTR: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        default: return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    if (WIFEXITED(status)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
         * The child exited normally; get its exit code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        return WEXITSTATUS(status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    } else if (WIFSIGNALED(status)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        /* The child exited because of a signal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
         * The best value to return is 0x80 + signal number,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
         * because that is what all Unix shells do, and because
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
         * it allows callers to distinguish between process exit and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
         * process death by signal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
         * Unfortunately, the historical behavior on Solaris is to return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
         * the signal number, and we preserve this for compatibility. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
#ifdef __solaris__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        return WTERMSIG(status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        return 0x80 + WTERMSIG(status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
         * Unknown exit code; pass it through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        return status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
static const char *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
getBytes(JNIEnv *env, jbyteArray arr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    return arr == NULL ? NULL :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    if (parr != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   289
#define IOE_FORMAT "error=%d, %s"
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   290
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    const char *detail = defaultDetail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    char *errmsg;
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   296
    size_t fmtsize;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    jstring s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    if (errnum != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        const char *s = strerror(errnum);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        if (strcmp(s, "Unknown error") != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            detail = s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   305
    fmtsize = sizeof(IOE_FORMAT) + strlen(detail) + 3 * sizeof(errnum);
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   306
    errmsg = NEW(char, fmtsize);
16860
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   307
    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
   308
        return;
8fecebee12b0 8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jzavgren
parents: 13149
diff changeset
   309
30784
28105f71beb2 8074818: Resolve disabled warnings for libjava
rriggs
parents: 29724
diff changeset
   310
    snprintf(errmsg, fmtsize, IOE_FORMAT, errnum, detail);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    s = JNU_NewStringPlatform(env, errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    if (s != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        jobject x = JNU_NewObjectByName(env, "java/io/IOException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                                        "(Ljava/lang/String;)V", s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        if (x != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            (*env)->Throw(env, x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    free(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
#ifdef DEBUG_PROCESS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
/* Debugging process code is difficult; where to write debug output? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
debugPrint(char *format, ...)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    FILE *tty = fopen("/dev/tty", "w");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    va_list ap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    va_start(ap, format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    vfprintf(tty, format, ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    va_end(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    fclose(tty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
#endif /* DEBUG_PROCESS */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   335
static void
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   336
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
   337
{
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   338
    to[0] = from[0];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   339
    to[1] = from[1];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   340
}
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   341
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   342
/* 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
   343
 * by a null element.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   344
 *
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   345
 * *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
   346
 * 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
   347
 * 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
   348
 * 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
   349
 */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   350
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
   351
{
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   352
    int i, bytes, count;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   353
    const char * const *a = arg;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   354
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   355
    int *q;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   356
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   357
        *nelems = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   358
        *nbytes = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   359
        return;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   360
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   361
    /* 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
   362
    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
   363
        bytes += strlen(*a)+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   364
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   365
    *nbytes = bytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   366
    *nelems = count+1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   367
}
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   368
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   369
/* 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
   370
 * 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
   371
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   372
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
   373
    char *p;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   374
    const char * const *a;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   375
    int count=0;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   376
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   377
    if (arg == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   378
        return offset;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   379
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   380
    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
   381
        int len = strlen(*a) +1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   382
        memcpy(p, *a, len);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   383
        p += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   384
        count += len;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   385
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   386
    return offset+count;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   387
}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   389
/**
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   390
 * We are unusually paranoid; use of vfork is
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   391
 * 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
   392
 */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   393
#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
   394
__attribute_noinline__
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   395
#endif
19399
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
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   398
vforkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   399
    volatile pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   400
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   401
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   402
     * 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
   403
     * 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
   404
     * 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
   405
     *  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
   406
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   407
    resultPid = vfork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   408
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   409
    if (resultPid == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   410
        childProcess(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   411
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   412
    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
   413
    return resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   414
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   415
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   416
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   417
forkChild(ChildStuff *c) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   418
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   419
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   420
    /*
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   421
     * 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
   422
     * 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
   423
     * 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
   424
     * behavior for fork().
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   425
     */
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   426
    resultPid = fork();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   427
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   428
    if (resultPid == 0) {
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   429
        childProcess(c);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   430
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   431
    assert(resultPid != 0);  /* childProcess never returns */
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   432
    return resultPid;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   433
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   434
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
   435
#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
   436
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   437
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
   438
    pid_t resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   439
    jboolean isCopy;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   440
    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
   441
    char *buf, buf1[16];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   442
    char *hlpargs[2];
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   443
    SpawnInfo sp;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   444
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   445
    /* 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
   446
     * 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
   447
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   448
    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
   449
    /* 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
   450
    hlpargs[0] = buf1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   451
    hlpargs[1] = 0;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   452
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   453
    /* 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
   454
     * after it is spawned.
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   455
     * 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
   456
     * 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
   457
     * - the ChildStuff struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   458
     * - the SpawnInfo struct
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   459
     * - the argv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   460
     * - the envv strings array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   461
     * - the home directory string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   462
     * - the parentPath string
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   463
     * - the parentPathv array
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   464
     */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   465
    /* First calculate the sizes */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   466
    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
   467
    bufsize = sp.argvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   468
    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
   469
    bufsize += sp.envvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   470
    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
   471
    bufsize += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   472
    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
   473
    bufsize += sp.parentPathvBytes;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   474
    /* 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
   475
     * 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
   476
     * 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
   477
    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
   478
        if (c->fds[i] != -1) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   479
            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
   480
            if (flags & FD_CLOEXEC) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   481
                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
   482
            }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   483
        }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   484
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   485
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   486
    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
   487
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   488
    if (rval != 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   489
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   490
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   491
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   492
    /* 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
   493
    buf = NEW(char, bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   494
    if (buf == 0) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   495
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   496
    }
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   497
    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
   498
    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
   499
    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
   500
    offset += sp.dirlen;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   501
    offset = copystrings(buf, offset, parentPathv);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   502
    assert(offset == bufsize);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   503
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   504
    magic = magicNumber();
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   505
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   506
    /* 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
   507
    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
   508
    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
   509
    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
   510
    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
   511
    free(buf);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   512
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   513
    /* 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
   514
     * 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
   515
     * via the statement below */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   516
    return resultPid;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   517
}
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   518
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   519
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
 * 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
   522
 * 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
   523
 */
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   524
static pid_t
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   525
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
   526
    switch (c->mode) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   527
      case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   528
        return vforkChild(c);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   529
      case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   530
        return forkChild(c);
22597
7515a991bb37 8024854: PPC64: Basic changes and files to build the class library on AIX
simonis
parents: 19399
diff changeset
   531
#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
   532
      case MODE_POSIX_SPAWN:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   533
        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
   534
#endif
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   535
      default:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   536
        return -1;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   537
    }
3430
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   538
}
8d6d03175761 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion
martin
parents: 3421
diff changeset
   539
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
JNIEXPORT jint JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   541
Java_java_lang_ProcessImpl_forkAndExec(JNIEnv *env,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                                       jobject process,
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   543
                                       jint mode,
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   544
                                       jbyteArray helperpath,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                                       jbyteArray prog,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                                       jbyteArray argBlock, jint argc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                                       jbyteArray envBlock, jint envc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                                       jbyteArray dir,
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   549
                                       jintArray std_fds,
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   550
                                       jboolean redirectErrorStream)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    int errnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    int resultPid = -1;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   554
    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
   555
    jint *fds = NULL;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   556
    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
   557
    const char *pprog = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   558
    const char *pargBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   559
    const char *penvBlock = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   560
    ChildStuff *c;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    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
   563
    childenv[0] = childenv[1] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   565
    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
   566
    c->argv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   567
    c->envv = NULL;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   568
    c->pdir = NULL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   570
    /* 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
   571
     * 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
   572
     * execve_as_traditional_shell_script.
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   573
     * This word is also used when using posix_spawn mode
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   574
     */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   575
    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
   576
    if ((phelperpath = getBytes(env, helperpath))   == NULL) goto Catch;
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   577
    if ((pprog       = getBytes(env, prog))         == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   578
    if ((pargBlock   = getBytes(env, argBlock))     == NULL) goto Catch;
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   579
    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
   580
    c->argv[0] = pprog;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   581
    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
   582
    initVectorFromBlock(c->argv+1, pargBlock, argc);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    if (envBlock != NULL) {
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   585
        /* 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
   586
        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
   587
        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
   588
        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
   589
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   590
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   591
    if (dir != NULL) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   592
        if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   595
    assert(std_fds != NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   596
    fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   597
    if (fds == NULL) goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   598
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   599
    if ((fds[0] == -1 && pipe(in)  < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   600
        (fds[1] == -1 && pipe(out) < 0) ||
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   601
        (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
   602
        (pipe(childenv) < 0) ||
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        (pipe(fail) < 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        throwIOException(env, errno, "Bad file descriptor");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    }
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   607
    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
   608
    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
   609
    c->fds[2] = fds[2];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   611
    copyPipe(in,   c->in);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   612
    copyPipe(out,  c->out);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   613
    copyPipe(err,  c->err);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   614
    copyPipe(fail, c->fail);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   615
    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
   616
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   617
    c->redirectErrorStream = redirectErrorStream;
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   618
    c->mode = mode;
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   619
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   620
    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
   621
    assert(resultPid != 0);
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   622
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    if (resultPid < 0) {
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   624
        switch (c->mode) {
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   625
          case MODE_VFORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   626
            throwIOException(env, errno, "vfork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   627
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   628
          case MODE_FORK:
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   629
            throwIOException(env, errno, "fork failed");
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   630
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   631
          case MODE_POSIX_SPAWN:
29724
638809ff54f3 7021006: (process) Remove disabled clone-exec feature
rriggs
parents: 28665
diff changeset
   632
            throwIOException(env, errno, "posix_spawn failed");
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   633
            break;
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   634
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    }
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   637
    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
   638
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   639
    switch (readFully(fail[0], &errnum, sizeof(errnum))) {
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   640
    case 0: break; /* Exec succeeded */
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   641
    case sizeof(errnum):
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        waitpid(resultPid, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        throwIOException(env, errnum, "Exec failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        goto Catch;
50
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   645
    default:
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   646
        throwIOException(env, errno, "Read failed");
a437b3f9d7f4 6671051: (process) Runtime.exec() hangs if signalled during fork/exec
martin
parents: 48
diff changeset
   647
        goto Catch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   650
    fds[0] = (in [1] != -1) ? in [1] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   651
    fds[1] = (out[0] != -1) ? out[0] : -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   652
    fds[2] = (err[0] != -1) ? err[0] : -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
 Finally:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    /* Always clean up the child's side of the pipes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    closeSafely(in [0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    closeSafely(out[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    closeSafely(err[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   660
    /* Always clean up fail and childEnv descriptors */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    closeSafely(fail[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    closeSafely(fail[1]);
19399
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   663
    closeSafely(childenv[0]);
e2e5122cd62e 5049299: (process) Use posix_spawn, not fork, on S10 to avoid swap exhaustion
robm
parents: 16860
diff changeset
   664
    closeSafely(childenv[1]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
25980
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   666
    releaseBytes(env, helperpath, phelperpath);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   667
    releaseBytes(env, prog,       pprog);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   668
    releaseBytes(env, argBlock,   pargBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   669
    releaseBytes(env, envBlock,   penvBlock);
76e7de7a6ef7 8054841: (process) ProcessBuilder leaks native memory
igerasim
parents: 22641
diff changeset
   670
    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
   671
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   672
    free(c->argv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   673
    free(c->envv);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents: 1936
diff changeset
   674
    free(c);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   676
    if (fds != NULL)
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   677
        (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 2
diff changeset
   678
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    return resultPid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
 Catch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
    /* 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
   683
    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
   684
    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
   685
    closeSafely(err[0]); err[0] = -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    goto Finally;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
JNIEXPORT void JNICALL
28665
fe8344cf6496 8071481: (Process) Merge UNIXProcess.java into ProcessImpl.java
rriggs
parents: 25991
diff changeset
   690
Java_java_lang_ProcessImpl_destroyProcess(JNIEnv *env,
13149
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   691
                                          jobject junk,
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   692
                                          jint pid,
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   693
                                          jboolean force)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
{
13149
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   695
    int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM;
27d52f97a5cc 4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents: 12047
diff changeset
   696
    kill(pid, sig);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
}