1 /*
   2  * Copyright (c) 1998, 2020, 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 static char *skipWhitespace(char *p) {
  34     while ((*p != '\0') && isspace(*p)) {
  35         p++;
  36     }
  37     return p;
  38 }
  39 
  40 static char *skipNonWhitespace(char *p) {
  41     while ((*p != '\0') && !isspace(*p)) {
  42         p++;
  43     }
  44     return p;
  45 }
  46 
  47 int
  48 dbgsysExec(char *cmdLine)
  49 {
  50     int i;
  51     int argc;
  52     pid_t pid_err = (pid_t)(-1); /* this is the error return value */
  53     pid_t pid;
  54     char **argv = NULL;
  55     char *p;
  56     char *args;
  57 
  58     /* Skip leading whitespace */
  59     cmdLine = skipWhitespace(cmdLine);
  60 
  61     /*LINTED*/
  62     args = jvmtiAllocate((jint)strlen(cmdLine)+1);
  63     if (args == NULL) {
  64         return SYS_NOMEM;
  65     }
  66     (void)strcpy(args, cmdLine);
  67 
  68     p = args;
  69 
  70     argc = 0;
  71     while (*p != '\0') {
  72         p = skipNonWhitespace(p);
  73         argc++;
  74         if (*p == '\0') {
  75             break;
  76         }
  77         p = skipWhitespace(p);
  78     }
  79 
  80     /*LINTED*/
  81     argv = jvmtiAllocate((argc + 1) * (jint)sizeof(char *));
  82     if (argv == 0) {
  83         jvmtiDeallocate(args);
  84         return SYS_NOMEM;
  85     }
  86 
  87     for (i = 0, p = args; i < argc; i++) {
  88         argv[i] = p;
  89         p = skipNonWhitespace(p);
  90         *p++ = '\0';
  91         p = skipWhitespace(p);
  92     }
  93     argv[i] = NULL;  /* NULL terminate */
  94 
  95     if ((pid = fork()) == 0) {
  96         /* Child process */
  97         int i;
  98         long max_fd;
  99 
 100         /* close everything */
 101         max_fd = sysconf(_SC_OPEN_MAX);
 102         /*LINTED*/
 103         for (i = 3; i < (int)max_fd; i++) {
 104             (void)close(i);
 105         }
 106 
 107         (void)execvp(argv[0], argv);
 108 
 109         exit(-1);
 110     }
 111     jvmtiDeallocate(args);
 112     jvmtiDeallocate(argv);
 113     if (pid == pid_err) {
 114         return SYS_ERR;
 115     } else {
 116         return SYS_OK;
 117     }
 118 }