1/*
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdlib.h>
27#include <unistd.h>
28#include <string.h>
29#include <ctype.h>
30#include "sys.h"
31#include "util.h"
32
33#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
34  /* Linux, BSD, AIX */
35  #define FORK() fork()
36#else
37  /* Solaris (make sure we always get the POSIX-specified behavior) */
38  #define FORK() fork1()
39#endif
40
41static char *skipWhitespace(char *p) {
42    while ((*p != '\0') && isspace(*p)) {
43        p++;
44    }
45    return p;
46}
47
48static char *skipNonWhitespace(char *p) {
49    while ((*p != '\0') && !isspace(*p)) {
50        p++;
51    }
52    return p;
53}
54
55int
56dbgsysExec(char *cmdLine)
57{
58    int i;
59    int argc;
60    pid_t pid_err = (pid_t)(-1); /* this is the error return value */
61    pid_t pid;
62    char **argv = NULL;
63    char *p;
64    char *args;
65
66    /* Skip leading whitespace */
67    cmdLine = skipWhitespace(cmdLine);
68
69    /*LINTED*/
70    args = jvmtiAllocate((jint)strlen(cmdLine)+1);
71    if (args == NULL) {
72        return SYS_NOMEM;
73    }
74    (void)strcpy(args, cmdLine);
75
76    p = args;
77
78    argc = 0;
79    while (*p != '\0') {
80        p = skipNonWhitespace(p);
81        argc++;
82        if (*p == '\0') {
83            break;
84        }
85        p = skipWhitespace(p);
86    }
87
88    /*LINTED*/
89    argv = jvmtiAllocate((argc + 1) * (jint)sizeof(char *));
90    if (argv == 0) {
91        jvmtiDeallocate(args);
92        return SYS_NOMEM;
93    }
94
95    for (i = 0, p = args; i < argc; i++) {
96        argv[i] = p;
97        p = skipNonWhitespace(p);
98        *p++ = '\0';
99        p = skipWhitespace(p);
100    }
101    argv[i] = NULL;  /* NULL terminate */
102
103    if ((pid = FORK()) == 0) {
104        /* Child process */
105        int i;
106        long max_fd;
107
108        /* close everything */
109        max_fd = sysconf(_SC_OPEN_MAX);
110        /*LINTED*/
111        for (i = 3; i < (int)max_fd; i++) {
112            (void)close(i);
113        }
114
115        (void)execvp(argv[0], argv);
116
117        exit(-1);
118    }
119    jvmtiDeallocate(args);
120    jvmtiDeallocate(argv);
121    if (pid == pid_err) {
122        return SYS_ERR;
123    } else {
124        return SYS_OK;
125    }
126}
127