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 
  41 static char *skipWhitespace(char *p) {
  42     while ((*p != '\0') && isspace(*p)) {
  43         p++;
  44     }
  45     return p;
  46 }
  47 
  48 static char *skipNonWhitespace(char *p) {
  49     while ((*p != '\0') && !isspace(*p)) {
  50         p++;
  51     }
  52     return p;
  53 }
  54 
  55 int
  56 dbgsysExec(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 }