diff options
Diffstat (limited to 'emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp')
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp b/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp new file mode 100644 index 0000000..c97ff58 --- /dev/null +++ b/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp @@ -0,0 +1,210 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "osProcess.h" +#include <stdio.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <poll.h> +#include <pthread.h> +#include <string.h> +#include <pwd.h> +#include <paths.h> +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <assert.h> + +namespace osUtils { + +// +// buildArgList converts a command line into null terminated argument list. +// to be used with execv or execvp. +// each argument is seperated by space or tab, to specify multiple words +// at the same argument place it inside single-quoted or double-quoted string. +// +static char **buildArgList(const char *command) +{ + char **argv = NULL; + int argvSize = 0; + int nArgs = 0; + char *tmpcmd = strdup(command); + char *t = tmpcmd; + char *strStart = NULL; + int i = 0; + + #define ADD_ARG \ + { \ + nArgs++; \ + if (!argv) { \ + argvSize = 12; \ + argv = (char **)malloc(argvSize * sizeof(char *)); \ + } \ + else if (nArgs > argvSize) { \ + argvSize += 12; \ + argv = (char **)realloc(argv, argvSize * sizeof(char *)); \ + } \ + argv[nArgs-1] = t; \ + t = NULL; \ + } + + while( tmpcmd[i] != '\0' ) { + if (!strStart) { + if (tmpcmd[i] == '"' || tmpcmd[i] == '\'') { + strStart = &tmpcmd[i]; + } + else if (tmpcmd[i] == ' ' || tmpcmd[i] == '\t') { + tmpcmd[i] = '\0'; + if (t) ADD_ARG; + } + else if (!t) { + t = &tmpcmd[i]; + } + } + else if (tmpcmd[i] == *strStart) { + t = strStart; + strStart = NULL; + } + + i++; + } + if (t) { + ADD_ARG; + } + if (nArgs > 0) { + ADD_ARG; // for NULL terminating list + } + + return argv; +} + +static pid_t start_process(const char *command,const char *startDir) +{ + pid_t pid; + + pid = fork(); + + if (pid < 0) { + return pid; + } + else if (pid == 0) { + // + // Close all opened file descriptors + // + for (int i=3; i<256; i++) { + close(i); + } + + if (startDir) { + chdir(startDir); + } + + char **argv = buildArgList(command); + if (!argv) { + return -1; + } + execvp(argv[0], argv); + + perror("execl"); + exit(-101); + } + + return pid; +} + +childProcess * +childProcess::create(const char *p_cmdLine, const char *p_startdir) +{ + childProcess *child = new childProcess(); + if (!child) { + return NULL; + } + + child->m_pid = start_process(p_cmdLine, p_startdir); + if (child->m_pid < 0) { + delete child; + return NULL; + } + + return child; +} + +childProcess::~childProcess() +{ +} + +bool +childProcess::wait(int *exitStatus) +{ + int ret=0; + if (m_pid>0) { + pid_t pid = waitpid(m_pid,&ret,0); + if (pid != -1) { + m_pid=-1; + if (exitStatus) { + *exitStatus = ret; + } + return true; + } + } + return false; +} + +int +childProcess::tryWait(bool &isAlive) +{ + int ret=0; + isAlive = false; + if (m_pid>0) { + pid_t pid = waitpid(m_pid,&ret,WNOHANG); + if (pid == 0) { + isAlive = true; + } + } + + return ((char)WEXITSTATUS(ret)); +} + +int ProcessGetPID() +{ + return getpid(); +} + +int KillProcess(int pid, bool wait) +{ + if (pid<1) { + return false; + } + + if (0!=kill(pid,SIGTERM)) { + return false; + } + + if (wait) { + if (waitpid(pid,NULL,0)<0) { + return false; + } + } + + return true; +} + +bool isProcessRunning(int pid) +{ + return (kill(pid,0) == 0); +} + +} // of namespace osUtils |