Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* License: GPL */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <libgen.h>
- #include <signal.h>
- #include <string.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <stdbool.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/wait.h>
- const char * basename_argv0;
- int ExecCommandWaitChild(pid_t ChildPID) {
- int ChildStatus;
- int status;
- status=waitpid(ChildPID,&ChildStatus,0);
- if (status==-1)
- return (-1);
- if (WIFEXITED(ChildStatus))
- return (WEXITSTATUS(ChildStatus));
- else
- return (-1);
- }
- int ExecCommandWaitChildList(pid_t * ChildPIDList) {
- int ExitStatus;
- ExitStatus=0;
- if (ChildPIDList!=NULL) {
- unsigned int ChildCount;
- int i;
- ChildCount=0;
- for (i=0; ChildPIDList[i]!=-1; i++)
- ChildCount++;
- for (i=ChildCount-1; i>=0; i--) {
- int ChildExitStatus;
- ChildExitStatus=ExecCommandWaitChild(ChildPIDList[i]);
- if (ExitStatus==0 && ChildExitStatus!=0)
- ExitStatus=ChildExitStatus;
- }
- free(ChildPIDList);
- }
- return (ExitStatus);
- }
- int ExecCommandListRedir(const char * const * const * const CommandArgList, char * const FileName) {
- const char * const * CommandArgs;
- int * PipeFDList;
- pid_t * ChildPIDList;
- unsigned int ChildCount;
- int OutFileFD;
- int ExitStatus;
- bool ForegroundProcess;
- long int maxfd;
- int SavedErrNo;
- int status;
- int i;
- if (CommandArgList==NULL)
- return (-1);
- ChildCount=0;
- for (i=0; CommandArgList[i]!=NULL; i++)
- ChildCount++;
- if (ChildCount==0)
- return (-1);
- #ifdef DEBUG
- int j;
- fprintf(stderr,"%s: ",__FUNCTION__);
- for (i=0; i<ChildCount; i++) {
- for (j=0; CommandArgList[i][j]!=NULL; j++)
- fprintf(stderr,"%s ",CommandArgList[i][j]);
- if (i<ChildCount-1)
- fprintf(stderr,"| ");
- else
- fprintf(stderr,"> %s\n",FileName);
- }
- #endif
- PipeFDList=NULL;
- ChildPIDList=NULL;
- ExitStatus=-1;
- if (FileName!=NULL) {
- OutFileFD=mkstemp(FileName);
- if (OutFileFD==-1)
- goto ExecCommandListRedirExit;
- ForegroundProcess=false;
- }
- else {
- OutFileFD=-1;
- ForegroundProcess=true;
- }
- if (ChildCount>1) {
- PipeFDList=malloc((ChildCount-1)*(2*sizeof(int)));
- if (PipeFDList==NULL)
- goto ExecCommandListRedirExit;
- for (i=0; i<ChildCount-1; i++) {
- PipeFDList[2*i+0]=-1;
- PipeFDList[2*i+1]=-1;
- }
- }
- ChildPIDList=malloc((ChildCount+1)*sizeof(pid_t));
- if (ChildPIDList==NULL)
- goto ExecCommandListRedirExit;
- for (i=0; i<ChildCount+1; i++)
- ChildPIDList[i]=-1;
- maxfd=sysconf(_SC_OPEN_MAX);
- for (i=ChildCount-1; i>=0; i--) {
- if (i>0) {
- status=pipe(&PipeFDList[2*(i-1)]);
- if (status==-1) {
- if (ForegroundProcess==true)
- fprintf(stderr,"%s: pipe creation failed: %s\n",basename_argv0,strerror(errno));
- goto ExecCommandListRedirExit;
- }
- }
- ChildPIDList[i]=fork();
- if (ChildPIDList[i]==0) { /* child */
- struct sigaction sa;
- int fd;
- if (i>0)
- dup2(PipeFDList[2*(i-1)+0],STDIN_FILENO);
- else if (ForegroundProcess==false) {
- fd=open("/dev/null",O_RDONLY);
- if (fd!=-1)
- dup2(fd,STDIN_FILENO);
- }
- if (i<ChildCount-1)
- dup2(PipeFDList[2*i+1],STDOUT_FILENO);
- else if (OutFileFD!=-1)
- dup2(OutFileFD,STDOUT_FILENO);
- for (fd=STDERR_FILENO+1; fd<maxfd; fd++)
- close(fd);
- CommandArgs=CommandArgList[i];
- sa.sa_handler=SIG_DFL;
- sigfillset(&sa.sa_mask);
- sa.sa_flags=0;
- sigaction(SIGINT,&sa,NULL);
- sigaction(SIGTERM,&sa,NULL);
- sigaction(SIGQUIT,&sa,NULL);
- sigaction(SIGPIPE,&sa,NULL);
- execvp(CommandArgs[0],(char * const *)CommandArgs);
- if (ForegroundProcess==true)
- fprintf(stderr,"%s: %s: %s\n",basename_argv0,CommandArgs[0],strerror(errno));
- _exit(127);
- }
- /* parent */
- else if (ChildPIDList[i]==-1) {
- if (ForegroundProcess==true)
- fprintf(stderr,"%s: fork failed: %s\n",basename_argv0,strerror(errno));
- goto ExecCommandListRedirExit;
- }
- }
- ExitStatus=0;
- ExecCommandListRedirExit:
- SavedErrNo=errno;
- if (OutFileFD!=-1)
- close(OutFileFD);
- if (PipeFDList!=NULL) {
- for (i=0; i<ChildCount-1; i++) {
- close(PipeFDList[2*i+0]);
- close(PipeFDList[2*i+1]);
- }
- free(PipeFDList);
- }
- ExitStatus=ExecCommandWaitChildList(ChildPIDList);
- errno=SavedErrNo;
- return (ExitStatus);
- }
- FILE * ExecCommandListPipe(const char * const * const * const CommandArgList, pid_t ** ChildPIDListPtr) {
- const char * const * CommandArgs;
- int * PipeFDList;
- pid_t * ChildPIDList;
- unsigned int ChildCount;
- FILE * OutFile;
- long int maxfd;
- int SavedErrNo;
- int status;
- int i;
- *ChildPIDListPtr=NULL;
- if (CommandArgList==NULL)
- return (NULL);
- ChildCount=0;
- for (i=0; CommandArgList[i]!=NULL; i++)
- ChildCount++;
- if (ChildCount==0)
- return (NULL);
- #ifdef DEBUG
- int j;
- fprintf(stderr,"%s: ",__FUNCTION__);
- for (i=0; i<ChildCount; i++) {
- for (j=0; CommandArgList[i][j]!=NULL; j++)
- fprintf(stderr,"%s ",CommandArgList[i][j]);
- if (i<ChildCount-1)
- fprintf(stderr,"| ");
- else
- fprintf(stderr,"| %s\n",basename_argv0);
- }
- #endif
- OutFile=NULL;
- PipeFDList=malloc(ChildCount*(2*sizeof(int)));
- if (PipeFDList==NULL)
- goto ExecCommandListPipeExit;
- for (i=0; i<ChildCount; i++) {
- PipeFDList[2*i+0]=-1;
- PipeFDList[2*i+1]=-1;
- }
- ChildPIDList=malloc((ChildCount+1)*sizeof(pid_t));
- if (ChildPIDList==NULL)
- goto ExecCommandListPipeExit;
- for (i=0; i<ChildCount+1; i++)
- ChildPIDList[i]=-1;
- *ChildPIDListPtr=ChildPIDList;
- status=pipe(&PipeFDList[2*(ChildCount-1)]);
- if (status==-1)
- goto ExecCommandListPipeExit;
- maxfd=sysconf(_SC_OPEN_MAX);
- for (i=ChildCount-1; i>=0; i--) {
- if (i>0) {
- status=pipe(&PipeFDList[2*(i-1)]);
- if (status==-1)
- goto ExecCommandListPipeExit;
- }
- ChildPIDList[i]=fork();
- if (ChildPIDList[i]==0) { /* child */
- struct sigaction sa;
- int fd;
- if (i>0)
- dup2(PipeFDList[2*(i-1)+0],STDIN_FILENO);
- else {
- fd=open("/dev/null",O_RDONLY);
- if (fd!=-1)
- dup2(fd,STDIN_FILENO);
- }
- dup2(PipeFDList[2*i+1],STDOUT_FILENO);
- for (fd=STDERR_FILENO+1; fd<maxfd; fd++)
- close(fd);
- CommandArgs=CommandArgList[i];
- sa.sa_handler=SIG_DFL;
- sigfillset(&sa.sa_mask);
- sa.sa_flags=0;
- sigaction(SIGINT,&sa,NULL);
- sigaction(SIGTERM,&sa,NULL);
- sigaction(SIGQUIT,&sa,NULL);
- sigaction(SIGPIPE,&sa,NULL);
- execvp(CommandArgs[0],(char * const *)CommandArgs);
- _exit(127);
- }
- /* parent */
- else if (ChildPIDList[i]==-1)
- goto ExecCommandListPipeExit;
- }
- OutFile=fdopen(PipeFDList[2*(ChildCount-1)+0],"r");
- ExecCommandListPipeExit:
- SavedErrNo=errno;
- if (PipeFDList!=NULL) {
- for (i=0; i<ChildCount-1; i++) {
- close(PipeFDList[2*i+0]);
- close(PipeFDList[2*i+1]);
- }
- if (OutFile==NULL)
- close(PipeFDList[2*(ChildCount-1)+0]);
- close(PipeFDList[2*(ChildCount-1)+1]);
- free(PipeFDList);
- }
- errno=SavedErrNo;
- return (OutFile);
- }
- int ExecCommandRedir(const char * const * const CommandArgs, char * const FileName) {
- const char * const * CommandArgList[2];
- CommandArgList[0]=CommandArgs;
- CommandArgList[1]=NULL;
- return (ExecCommandListRedir(CommandArgList,FileName));
- }
- FILE * ExecCommandPipe(const char * const * const CommandArgs, pid_t * ChildPID) {
- const char * const * CommandArgList[2];
- pid_t * ChildPIDList;
- FILE * OutFile;
- int SavedErrNo;
- CommandArgList[0]=CommandArgs;
- CommandArgList[1]=NULL;
- OutFile=ExecCommandListPipe(CommandArgList,&ChildPIDList);
- SavedErrNo=errno;
- *ChildPID=ChildPIDList[0];
- errno=SavedErrNo;
- return (OutFile);
- }
- int ExecCommand(const char * const * CommandArgs) {
- int status;
- if (CommandArgs==NULL)
- return (-1);
- status=ExecCommandRedir(CommandArgs,NULL);
- return (status);
- }
- int main(int argc, char * const argv[]) {
- static const char * const Command1Args[]={
- "ls",
- "-l",
- "--si",
- "--color=auto",
- "--show-control-chars",
- "/",
- NULL
- };
- static const char * const Command2Args[]={
- "grep",
- "-i",
- "Jan",
- NULL
- };
- static const char * const Command3Args[]={
- "head",
- "-n",
- "3",
- NULL
- };
- static const char * const * const CommandArgList[]={
- Command1Args,
- Command2Args,
- Command3Args,
- NULL
- };
- FILE * infile;
- pid_t * ChildPIDList;
- pid_t ChildPID;
- int ExitStatus;
- basename_argv0=basename(argv[0]);
- /* ls -l --si --color=auto --show-control-chars / | grep -i Jan | head -n 3 | exec */
- infile=ExecCommandListPipe(CommandArgList,&ChildPIDList);
- if (infile==NULL) {
- fprintf(stderr,"%s: ExecCommandListPipe: %s\n",basename_argv0,strerror(errno));
- ExitStatus=ExecCommandWaitChildList(ChildPIDList);
- return (ExitStatus);
- }
- while (!feof(infile)) {
- char Buffer[1024];
- char * ptr;
- ptr=fgets(Buffer,sizeof(Buffer),infile);
- if (ptr==NULL) {
- if (feof(infile))
- break;
- else {
- fclose(infile);
- return (2);
- }
- }
- fputs(Buffer,stdout);
- }
- fclose(infile);
- ExitStatus=ExecCommandWaitChildList(ChildPIDList);
- fprintf(stderr,"%s: pipeline exit status: %d\n",basename_argv0,ExitStatus);
- /* ls -l --si --color=auto --show-control-chars / | exec */
- infile=ExecCommandPipe(Command1Args,&ChildPID);
- if (infile==NULL) {
- fprintf(stderr,"%s: ExecCommandPipe: %s\n",basename_argv0,strerror(errno));
- ExitStatus=ExecCommandWaitChild(ChildPID);
- return (ExitStatus);
- }
- while (!feof(infile)) {
- char Buffer[1024];
- char * ptr;
- ptr=fgets(Buffer,sizeof(Buffer),infile);
- if (ptr==NULL) {
- if (feof(infile))
- break;
- else {
- fclose(infile);
- return (2);
- }
- }
- fputs(Buffer,stdout);
- }
- fclose(infile);
- ExitStatus=ExecCommandWaitChild(ChildPID);
- fprintf(stderr,"%s: command exit status: %d\n",basename_argv0,ExitStatus);
- return (0);
- }
Advertisement
Add Comment
Please, Sign In to add comment