aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp')
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp210
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