int my_open(const char* pathname, int mode) { int fd, sockfd[2], status; pid_t childpid; char c, argsockfd[10], argmode[10]; Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); if ((childpid = Fork()) == 0) { /* child process */ Close(sockfd[0]); snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]); snprintf(argmode, sizeof(argmode), "%d", mode); execl("./openfile", "openfile", argsockfd, pathname, argmode, (char*)NULL); err_sys("execl error"); } /* parent process - wait for the child to terminate */ Close(sockfd[1]); /* close the end we don't use */ Waitpid(childpid, &status, 0); if (WIFEXITED(status) == 0) err_quit("child did not terminate"); if ((status = WEXITSTATUS(status)) == 0) Read_fd(sockfd[0], &c, 1, &fd); else { errno = status; /* set errno value from child's status */ fd = -1; } Close(sockfd[0]); return (fd); }
int my_open(char *pathname,int mode){ int sockfd[2],fd,state; pid_t childpid; char argmode[10]; char argsock[10]; socketpair(AF_LOCAL,SOCK_STREAM,0,sockfd); if((childpid=fork()) == 0){ close(sockfd[0]); snprintf(argmode,sizeof(argmode),"%d",mode); snprintf(argsock,sizeof(argsock),"%d",sockfd[1]); execl("./openfile","openfile",argsock,pathname,argmode,(char *)NULL); err_sys("execl error"); } close(sockfd[0]); waitpid(childpid,&state,0); if(WIFEXITED(status) == 0) err_quit("child not terminated"); if((status = WEXITSTATUS(status)) == 0) Read_fd(sockfd[1],&c,&fd); else{ errno = status; fd=-1; } close(fd[1]); return (fd); }
int readable_conn(int i) { int unixfd, recvfd; char c; ssize_t n; socklen_t len; struct sockaddr_storage ss; unixfd = client[i].connfd; recvfd = -1; if ( (n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) { err_msg("client %d terminated, recvfd = %d", i, recvfd); goto clientdone; /* client probably terminated */ } /* 4data from client; should be descriptor */ if (recvfd < 0) { err_msg("read_fd did not return descriptor"); goto clienterr; } /* end readable_conn1 */ /* include readable_conn2 */ len = sizeof(ss); if (getsockname(recvfd, (SA *) &ss, &len) < 0) { err_ret("getsockname error"); goto clienterr; } client[i].family = ss.ss_family; if ( (client[i].lport = sock_get_port((SA *)&ss, len)) == 0) { client[i].lport = sock_bind_wild(recvfd, client[i].family); if (client[i].lport <= 0) { err_ret("error binding ephemeral port"); goto clienterr; } } Write(unixfd, "1", 1); /* tell client all OK */ Close(recvfd); /* all done with client's UDP socket */ return(--nready); clienterr: Write(unixfd, "0", 1); /* tell client error occurred */ clientdone: Close(unixfd); if (recvfd >= 0) Close(recvfd); FD_CLR(unixfd, &allset); client[i].connfd = -1; return(--nready); }
void child_main(int i, int listenfd, int addrlen) { char c; int connfd; ssize_t n; void web_child(int); printf("child %ld starting\n", (long) getpid()); for (;;) { if ((n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0) err_quit("read_fd returned 0"); if (connfd < 0) err_quit("no descriptor from read_fd"); web_child(connfd); /* process request */ Close(connfd); Write(STDERR_FILENO, "", 1); /* tell parent we're ready again */ } }