rendered paste body/* Prosty interpreter polece */#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <pthread.h>#include <sys/wait.h>#include <sys/resource.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <fcntl.h> #define INPUTSIZ 256#define MAXPAR 20int outfd = -1;int readfd,dupfd,stderrfd;char *filename;pthread_mutex_t outfd_mutex = PTHREAD_MUTEX_INITIALIZER;#define BUFSIZE 1024void *checkth(void *arg){// fd_set fs; char buf[BUFSIZE]; while (1) { /* FD_ZERO(&fs); FD_SET(readfd,&fs); if (select(readfd+1,&fs,0,0,0)!=1) continue;*/ ssize_t ret = read(readfd,buf,BUFSIZE); if (ret > 0) { write(0,buf,ret); pthread_mutex_lock(&outfd_mutex); if (outfd !=-1) write(outfd,buf,ret); pthread_mutex_unlock(&outfd_mutex); } }};void doshell(char *cmd) { char *argv[MAXPAR+1]; int argc=0, status; pid_t pid; struct rusage ru;/* Dzielenie linii polecen na "wyrazy" */ if((argv[argc]=strtok(cmd," \t\n"))==NULL) return; while(argv[argc] && argc<MAXPAR-1){ argv[++argc]=strtok(NULL," \t\n"); } if ((strcmp(argv[0],"kopia")==0)&& (argc == 2)) { pthread_mutex_lock(&outfd_mutex); if (outfd!=-1) { close(outfd); free(filename); outfd = -1; } if (strcmp(argv[1],"NULL")==0) { pthread_mutex_unlock(&outfd_mutex); return; } outfd = open(argv[1],O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR); if (outfd == -1) perror("kopia::open"); filename = (char *)malloc(strlen(argv[1])+1); if (!filename) { perror("malloc"); exit (-1); } strcpy(filename,argv[1]); pthread_mutex_unlock(&outfd_mutex); return; } else if (strcmp(argv[0],"kopia")==0) { if (outfd==-1) fprintf(stderr,"kopiowane nie jest w uzyciu\n"); else fprintf(stderr,"kopiowane jest w uzyciu, nazwa pliku %s\n",filename); return; } if ( (pid = fork()) < 0) { perror("Blad wywolania fork"); exit(2); } if (pid == 0) { if (dup2(dupfd,1)==-1) { perror("child::stdout_dup2"); exit(-1); } else close(dupfd); if (dup2(stderrfd,2)==-1) { perror("child::stderr_dup2"); exit(-1); } else close(stderrfd); execvp(argv[0],argv); perror("Blad wywolania execvp"); exit(1); } while( (pid=wait3(&status,0,&ru))>0 ){ if(WIFEXITED(status)){ printf("Proces nr %d zakonczony z kodem wyjscia %d\n", pid,WEXITSTATUS(status)); } if(WIFSIGNALED(status)){ printf("Proces nr %d dostal sygnal nr %d\n", pid,WTERMSIG(status)); } if(WIFSTOPPED(status)){ printf("Proces nr %d zatrzymany przez sygnal nr %d\n", pid, WSTOPSIG(status)); }/* Tu mona doda kod wykorzystujcy informacje zawarte w strukturze ru * Opis pl struktury w: man getrusage */ }}int main() { char buf[INPUTSIZ]; int pipes[2]; pthread_t tid; if (pipe(pipes)!=0) { perror("pipe"); exit (-1); } readfd = pipes[0]; dupfd = pipes[1]; stderrfd = open("stderr.txt",O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR); if (stderrfd == -1) { perror("stderr::open"); exit(-1); } if (pthread_create(&tid,0,checkth,0)!=0){ perror("pthread_create"); exit(-1); } printf("\n> "); while (fgets(buf, INPUTSIZ, stdin) != NULL) { doshell(buf); printf("\n> "); } exit(0);}