Created
April 23, 2014 07:01
-
-
Save kangear/11205146 to your computer and use it in GitHub Desktop.
Can get stderr.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <sys/wait.h> | |
#include <malloc.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#ifdef __ANDROID__ | |
#define _PATH_BSHELL "/system/bin/sh" | |
#define printf(fmt,args...) ALOGW (fmt ,##args) | |
#else | |
#define _PATH_BSHELL "/bin/sh" | |
#endif | |
/* | |
* Pointer to array allocated at run-time. | |
*/ | |
static pid_t *childpid = NULL; | |
/* | |
* From our open_max(), {Prog openmax}. | |
*/ | |
static int maxfd; | |
FILE * | |
mypopen(const char *cmdstring, const char *type) | |
{ | |
int i; | |
int pfd[2]; | |
pid_t pid; | |
FILE *fp; | |
/* only allow "r" "e" or "w" */ | |
if ((type[0] != 'r' && type[0] != 'w' && type[0] != 'e') || type[1] != 0) { | |
errno = EINVAL; /* required by POSIX */ | |
return(NULL); | |
} | |
if (childpid == NULL) { /* first time through */ | |
/* allocate zeroed out array for child pids */ | |
maxfd = 256; | |
if ((childpid = (pid_t*)calloc(maxfd, sizeof(pid_t))) == NULL) | |
return(NULL); | |
} | |
if (pipe(pfd) < 0) | |
return(NULL); /* errno set by pipe() */ | |
if ((pid = fork()) < 0) { | |
return(NULL); /* errno set by fork() */ | |
} else if (pid == 0) { /* child */ | |
if (*type == 'e') { | |
close(pfd[0]); | |
if (pfd[1] != STDERR_FILENO) { | |
dup2(pfd[1], STDERR_FILENO); | |
close(pfd[1]); | |
} | |
} else if (*type == 'r') { | |
close(pfd[0]); | |
if (pfd[1] != STDOUT_FILENO) { | |
dup2(pfd[1], STDOUT_FILENO); | |
close(pfd[1]); | |
} | |
} else { | |
close(pfd[1]); | |
if (pfd[0] != STDIN_FILENO) { | |
dup2(pfd[0], STDIN_FILENO); | |
close(pfd[0]); | |
} | |
} | |
/* close all descriptors in childpid[] */ | |
for (i = 0; i < maxfd; i++) | |
if (childpid[i] > 0) | |
close(i); | |
execl(_PATH_BSHELL, "sh", "-c", cmdstring, (char *)0); | |
_exit(127); | |
} | |
/* parent continues... */ | |
if (*type == 'e') { | |
close(pfd[1]); | |
if ((fp = fdopen(pfd[0], "r")) == NULL) | |
return(NULL); | |
} else if (*type == 'r') { | |
close(pfd[1]); | |
if ((fp = fdopen(pfd[0], type)) == NULL) | |
return(NULL); | |
} else { | |
close(pfd[0]); | |
if ((fp = fdopen(pfd[1], type)) == NULL) | |
return(NULL); | |
} | |
childpid[fileno(fp)] = pid; /* remember child pid for this fd */ | |
return(fp); | |
} | |
int | |
mypclose(FILE *fp) | |
{ | |
int fd, stat; | |
pid_t pid; | |
if (childpid == NULL) { | |
errno = EINVAL; | |
return(-1); /* popen() has never been called */ | |
} | |
fd = fileno(fp); | |
if ((pid = childpid[fd]) == 0) { | |
errno = EINVAL; | |
return(-1); /* fp wasn't opened by popen() */ | |
} | |
childpid[fd] = 0; | |
if (fclose(fp) == EOF) | |
return(-1); | |
while (waitpid(pid, &stat, 0) < 0) | |
if (errno != EINTR) | |
return(-1); /* error other than EINTR from waitpid() */ | |
return(stat); /* return child's termination status */ | |
} | |
int shellcmd(const char *cmd){ | |
FILE *fp; | |
char buf[1024]; | |
fp = mypopen(cmd,"e"); | |
if (fp==NULL) return -1; | |
while(fgets(buf,1024,fp)!=NULL) | |
{ | |
printf("shellcmd:%s", buf); | |
} | |
pclose(fp); | |
return 0; | |
} | |
int main() | |
{ | |
shellcmd("ls kangear"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment