//--ENTRY POINT-- int main (int argc, char **argv) { if (argc!=2) { //Argument validation. fprintf(stderr, "Invalid argument number. Terminating...\n"); exit(EXIT_FAILURE); } mainrt=getpid(); node_type *root=get_tree_from_file(argv[1]); //Read tree: we suppose non-empty return tree. pid_t _fork; int k[2]; if (pipe(k)) { //Pipe error. pipe_error(mainrt); exit(EXIT_FAILURE); } if ((_fork=fork())==-1) { //Fork error. fprintf(stderr, "Fork error at main. ERRNO: (%d).\n", errno); exit(EXIT_FAILURE); } else if (_fork==0) { //Child: ccret(close(k[0])); fork_proc(root, k[1]); } else { //Main: ccret(close(k[1])); int rwn=0, rwrv=0, result; while (rwn<sizeof(int)) { //Read result. if ((rwrv=read(k[0], &result+rwn, sizeof(int)-rwn))==-1) { read_err(getpid()); exit(EXIT_FAILURE); } rwn+=rwrv; } ccret(close(k[0])); printf("RESULT: %d\n", result); //Print result. } return 0; }
void fork_proc (node_type *cur, int pfd) { pid_t par=getpid(); size_t i=0; pid_t ch[2]; int p[2][2]; int result=0, res[2]={0, 0}; int rwn=0, rwrv=0; if (!cur->nr_children) { //If no children: atoi arg. result=atoi(cur->name); } else if (cur->nr_children==2) { //Child with 2 children: Open pipes, fork children, and wait to read. for (i=0; i<cur->nr_children; i++) { //For the 2 children, open pipes, and fork giving them the write end. if (pipe(p[i])) { //Open pipe. pipe_error(par); shit_n_exit;//exit(EXIT_FAILURE); } ch[i]=fork(); //Fork. if (ch[i]<0) { fork_error(par); shit_n_exit;//exit(EXIT_FAILURE); } else if (ch[i]==0) { ccret(close(p[i][0])); fork_proc(&cur->children[i], p[i][1]); } else { ccret(close(p[i][1])); } } for (i=0; i<cur->nr_children; i++) { //Read from the 2 child streams (and bury them in the process). rwn=rwrv=0; while (rwn<sizeof(int)) { if ((rwrv=read(p[i][0], &res[i]+rwn, sizeof(int)-rwn))==-1) { read_err(par); shit_n_exit;//exit(EXIT_FAILURE); } rwn+=rwrv; } ccret(close(p[i][0])); wait(NULL); } _Bool err=0; result = (cur->name[0]=='+') ? res[0]+res[1] : ((cur->name[0]=='*') ? res[0]*res[1] : ((cur->name[0]=='-') ? res[0]-res[1] : (err=1))); if (err && op_err(par, cur->name[0]) && shit_n_exit) ; } else { //Child with illegal number of children: fprintf(stderr, "Illegal operand number ( %u ) in process: %ld.\n", cur->nr_children, (long)par); shit_n_exit;//exit(EXIT_FAILURE); } rwn=sizeof(int); printf("Writing data (%d) to pipe from process %ld.\n", result, (long)par); while (rwn!=0) { if ((rwrv=write(pfd, &result+sizeof(int)-rwn, (sizeof(int)<<1)-rwn))==-1) { write_err(par); shit_n_exit;//exit(EXIT_FAILURE); } rwn-=rwrv; } ccret(close(pfd)); exit(EXIT_SUCCESS); }
READ3res *nfsproc3_read_3_svc(READ3args * argp, struct svc_req * rqstp) { static READ3res result; char *path; int fd, res; static char buf[NFS_MAXDATA_TCP + 1]; unsigned int maxdata; if (get_socket_type(rqstp) == SOCK_STREAM) maxdata = NFS_MAXDATA_TCP; else maxdata = NFS_MAXDATA_UDP; PREP(path, argp->file); result.status = is_reg(); /* handle reading of executables */ read_executable(rqstp, st_cache); /* handle read of owned files */ read_by_owner(rqstp, st_cache); /* if bigger than rtmax, truncate length */ if (argp->count > maxdata) argp->count = maxdata; if (result.status == NFS3_OK) { fd = fd_open(path, argp->file, UNFS3_FD_READ, TRUE); if (fd != -1) { /* read one more to check for eof */ res = backend_pread(fd, buf, argp->count + 1, (off64_t)argp->offset); /* eof if we could not read one more */ result.READ3res_u.resok.eof = (res <= (int64) argp->count); /* close for real when hitting eof */ if (result.READ3res_u.resok.eof) fd_close(fd, UNFS3_FD_READ, FD_CLOSE_REAL); else { fd_close(fd, UNFS3_FD_READ, FD_CLOSE_VIRT); res--; } if (res >= 0) { result.READ3res_u.resok.count = res; result.READ3res_u.resok.data.data_len = res; result.READ3res_u.resok.data.data_val = buf; } else { /* error during read() */ /* EINVAL means unreadable object */ if (errno == EINVAL) result.status = NFS3ERR_INVAL; else result.status = NFS3ERR_IO; } } else /* opening for read failed */ result.status = read_err(); } /* overlaps with resfail */ result.READ3res_u.resok.file_attributes = get_post_stat(path, rqstp); return &result; }