#include < stdio.h > #include < signal.h > #include < errno.h > #define R (0) #define W (1) static struct pid { struct pid *next; FILE *fp; pid_t pid; } *pidlist; FILE *popen_err(char *command,char *option) { struct pid *cur; int pipe_c2p_e[2]; int pid; FILE *fp; if ((*option != 'r') || option[1]){ fprintf(stderr,"popen_err():option error:return(NULL)\n"); return (NULL); } if ((cur = (struct pid *)malloc(sizeof(struct pid))) == NULL){ fprintf(stderr,"popen_err():malloc error:return(NULL)\n"); return (NULL); } if(piep(pipe_c2p_e)<0){ perror("pipe"); return(NULL); } if((pid=fork())<0){ perror("fork"); close(pipe_c2p_e[R]); close(pipe_c2p_e[W]); return(NULL); } if(pid==0){ close(pipe_c2p_e[R]); dup2(pipe_c2p_e[W],2); close(pipe_c2p_e[W]); execlp("sh","sh","-c",command,NULL); _exit(127); } close(pipe_c2p_e[W]); fp=fdopen(pipe_c2p_e[R],option); cur->fp = fp; cur->pid = pid; cur->next = pidlist; pidlist = cur; return(fp); } int pclose_err(FILE *fp) { register struct pid *cur, *last; #if BSD /* for */ int omask; #else /* SYSV */ sigset_t set,omask; #endif int pstat; pid_t pid; extern int errno; fclose(fp); for(last = NULL, cur = pidlist; cur; last = cur, cur = cur->next){ if (cur->fp == fp){ break; } } if (cur == NULL){ return (-1); } #if BSD /* for BSD */ omask = sigblock(sigmask(SIGINT|sigmask(SIGQUIT)|sigmask(SIGHUP)); do { pid = waitpid(cur->pid, (int *) &pstat, 0); } while (pid == -1 && errno == EINTER); (void)sigsetmask(omask); } #else /* SYSV */ sigemptyset(&set); sigaddset(&set,SIGINT); sigaddset(&set,SIGQUIT); sigaddset(&set,SIGHUP); sigprocmask(SIG_SETMASK,&set,&omask); do { pid = waitpid(cur->pid, (int *)&pstat, 0); } while (pid == -1 && errno == EINTR); sigprocmask(SIG_SETMASK, &omask,NULL); #endif if (last == NULL){ pidlist = cur->next; } else { last->next = cur->next; } free(cur); return (pid == -1 ? -1 : pstat); }