This is just a set of OS dependant functionality needed by the emulator OpenGL host renderer. It currently has implementation for Linux and Windows only. osDynLibrary - dlopen/dlsym abstraction osProcess - interface to launch a new process, wait and kill it. osThread - abstraction interface for creating a thread. Change-Id: Ib0264592d8c87e865da87acf5c94e2b331801ca4
211 lines
4.3 KiB
C++
211 lines
4.3 KiB
C++
/*
|
|
* 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
|