《CSAPP》(第3版)答案(第八章)

您所在的位置:网站首页 spss第八章课后题答案解题步骤是什么 《CSAPP》(第3版)答案(第八章)

《CSAPP》(第3版)答案(第八章)

2023-12-04 16:57| 来源: 网络整理| 查看: 265

《CSAPP》(第3版)答案(第八章) P9 process paircocurrent?ABNoACYesADYesBCYesBDYesCDYes P10

A. call once, return twice fork B. call once, never return longjmp, execve C. call once, return 1 or more times setjmp

P11

4行

c +-------+ | "hello" | c | p +-------+-------+ | fork "hello" | | c | +-------+ | | "hello" | | | p | p +------+-------+-------+ main fork fork "hello" P12

8行

c +-------+---------+ | "hello" "hello" | c | p +-------+-------+---------+ | fork "hello" "hello" | | c | +-------+---------+ | | "hello" "hello" | | | p | p +------+-------+-------+---------+ main fork fork "hello" "hello" P13

a = 4 a=4 a=4 a = 3 a=3 a=3 a = 2 a=2 a=2

P14

3行

c +-------+ | "hello" | c | p +-------+-------+ | fork "hello" | | p +------+-------+-------+ main fork return "hello" P15

5行

c +-------+---------+ | "hello" "hello" | c | p +-------+-------+---------+ | fork "hello" "hello" | | | p +------+-------+-------+ main fork return "hello" P16

c o u n t e r = 2 counter = 2 counter=2 注意子进程有自己的计数器。

P17 hello 0 1 Bye 2 Bye hello 1 0 Bye 2 Bye hello 1 Bye 0 2 Bye P18 c +-------+---------+ | "0" exit "2" | c | p +-------+-------+---------+ | fork "1" exit "2" | (atexit) | c | +-------+---------+ | | "0" exit | | | p | p +------+-------+-------+---------+ main fork fork "1" exit

2一定在0/1后面,所以是B、D

P19

2 n = 2 6 = 64 2^n=2^6=64 2n=26=64

P20 #include #include "csapp.h" int main(int argc, char* argv[], char* env[]) { if (execve("/bin/ls", argv, env) == -1) { fprintf(stderr, "execve error: %s\n", strerror(errno)); exit(1); } } P21

abc或bac

P22 #include #include "csapp.h" int mysystem(char* command) { pid_t pid; int status; if ((pid = Fork()) == 0) { char* argv[4] = { "", "-c", command, NULL }; execve("/bin/sh", argv, environ); } printf("child pid: %d\n", pid); if (Waitpid(pid, &status, 0) > 0) { if (WIFEXITED(status)) return WEXITSTATUS(status); if (WIFSIGNALED(status)) return WTERMSIG(status); } } int main(int argc, char* argv[]) { int code; code = mysystem("./exit-code"); printf("normally exit, code: %d\n", code); fflush(stdout); code = mysystem("./wait-sig"); printf("exit caused by signal, code: %d\n", code); fflush(stdout); return 0; }

csapp.h

#ifndef __CSAPP_H__ #define __CSAPP_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Default file permissions are DEF_MODE & ~DEF_UMASK */ /* $begin createmasks */ #define DEF_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH #define DEF_UMASK S_IWGRP|S_IWOTH /* $end createmasks */ /* Simplifies calls to bind(), connect(), and accept() */ /* $begin sockaddrdef */ typedef struct sockaddr SA; /* $end sockaddrdef */ /* Persistent state for the robust I/O (Rio) package */ /* $begin rio_t */ #define RIO_BUFSIZE 8192 typedef struct { int rio_fd; /* Descriptor for this internal buf */ int rio_cnt; /* Unread bytes in internal buf */ char *rio_bufptr; /* Next unread byte in internal buf */ char rio_buf[RIO_BUFSIZE]; /* Internal buffer */ } rio_t; /* $end rio_t */ /* External variables */ extern int h_errno; /* Defined by BIND for DNS errors */ extern char **environ; /* Defined by libc */ /* Misc constants */ #define MAXLINE 8192 /* Max text line length */ #define MAXBUF 8192 /* Max I/O buffer size */ #define LISTENQ 1024 /* Second argument to listen() */ /* Our own error-handling functions */ void unix_error(char *msg); void posix_error(int code, char *msg); void dns_error(char *msg); void gai_error(int code, char *msg); void app_error(char *msg); /* Process control wrappers */ pid_t Fork(void); void Execve(const char *filename, char *const argv[], char *const envp[]); pid_t Wait(int *status); pid_t Waitpid(pid_t pid, int *iptr, int options); void Kill(pid_t pid, int signum); unsigned int Sleep(unsigned int secs); void Pause(void); unsigned int Alarm(unsigned int seconds); void Setpgid(pid_t pid, pid_t pgid); pid_t Getpgrp(); /* Signal wrappers */ typedef void handler_t(int); handler_t *Signal(int signum, handler_t *handler); void Sigprocmask(int how, const sigset_t *set, sigset_t *oldset); void Sigemptyset(sigset_t *set); void Sigfillset(sigset_t *set); void Sigaddset(sigset_t *set, int signum); void Sigdelset(sigset_t *set, int signum); int Sigismember(const sigset_t *set, int signum); int Sigsuspend(const sigset_t *set); /* Sio (Signal-safe I/O) routines */ ssize_t sio_puts(char s[]); ssize_t sio_putl(long v); void sio_error(char s[]); /* Sio wrappers */ ssize_t Sio_puts(char s[]); ssize_t Sio_putl(long v); void Sio_error(char s[]); /* Unix I/O wrappers */ int Open(const char *pathname, int flags, mode_t mode); ssize_t Read(int fd, void *buf, size_t count); ssize_t Write(int fd, const void *buf, size_t count); off_t Lseek(int fildes, off_t offset, int whence); void Close(int fd); int Select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int Dup2(int fd1, int fd2); void Stat(const char *filename, struct stat *buf); void Fstat(int fd, struct stat *buf) ; /* Directory wrappers */ DIR *Opendir(const char *name); struct dirent *Readdir(DIR *dirp); int Closedir(DIR *dirp); /* Memory mapping wrappers */ void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); void Munmap(void *start, size_t length); /* Standard I/O wrappers */ void Fclose(FILE *fp); FILE *Fdopen(int fd, const char *type); char *Fgets(char *ptr, int n, FILE *stream); FILE *Fopen(const char *filename, const char *mode); void Fputs(const char *ptr, FILE *stream); size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream); void Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); /* Dynamic storage allocation wrappers */ void *Malloc(size_t size); void *Realloc(void *ptr, size_t size); void *Calloc(size_t nmemb, size_t size); void Free(void *ptr); /* Sockets interface wrappers */ int Socket(int domain, int type, int protocol); void Setsockopt(int s, int level, int optname, const void *optval, int optlen); void Bind(int sockfd, struct sockaddr *my_addr, int addrlen); void Listen(int s, int backlog); int Accept(int s, struct sockaddr *addr, socklen_t *addrlen); void Connect(int sockfd, struct sockaddr *serv_addr, int addrlen); /* Protocol independent wrappers */ void Getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void Getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); void Freeaddrinfo(struct addrinfo *res); void Inet_ntop(int af, const void *src, char *dst, socklen_t size); void Inet_pton(int af, const char *src, void *dst); /* DNS wrappers */ struct hostent *Gethostbyname(const char *name); struct hostent *Gethostbyaddr(const char *addr, int len, int type); /* Pthreads thread control wrappers */ void Pthread_create(pthread_t *tidp, pthread_attr_t *attrp, void * (*routine)(void *), void *argp); void Pthread_join(pthread_t tid, void **thread_return); void Pthread_cancel(pthread_t tid); void Pthread_detach(pthread_t tid); void Pthread_exit(void *retval); pthread_t Pthread_self(void); void Pthread_once(pthread_once_t *once_control, void (*init_function)()); /* POSIX semaphore wrappers */ void Sem_init(sem_t *sem, int pshared, unsigned int value); void P(sem_t *sem); void V(sem_t *sem); /* Rio (Robust I/O) package */ ssize_t rio_readn(int fd, void *usrbuf, size_t n); ssize_t rio_writen(int fd, void *usrbuf, size_t n); void rio_readinitb(rio_t *rp, int fd); ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n); ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen); /* Wrappers for Rio package */ ssize_t Rio_readn(int fd, void *usrbuf, size_t n); void Rio_writen(int fd, void *usrbuf, size_t n); void Rio_readinitb(rio_t *rp, int fd); ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n); ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen); /* Reentrant protocol-independent client/server helpers */ int open_clientfd(char *hostname, char *port); int open_listenfd(char *port); /* Wrappers for reentrant protocol-independent client/server helpers */ int Open_clientfd(char *hostname, char *port); int Open_listenfd(char *port); #endif /* __CSAPP_H__ */ /* $end csapp.h */

csapp.c

#include "csapp.h" /************************** * Error-handling functions **************************/ /* $begin errorfuns */ /* $begin unixerror */ void unix_error(char *msg) /* Unix-style error */ { fprintf(stderr, "%s: %s\n", msg, strerror(errno)); exit(0); } /* $end unixerror */ void posix_error(int code, char *msg) /* Posix-style error */ { fprintf(stderr, "%s: %s\n", msg, strerror(code)); exit(0); } void gai_error(int code, char *msg) /* Getaddrinfo-style error */ { fprintf(stderr, "%s: %s\n", msg, gai_strerror(code)); exit(0); } void app_error(char *msg) /* Application error */ { fprintf(stderr, "%s\n", msg); exit(0); } /* $end errorfuns */ void dns_error(char *msg) /* Obsolete gethostbyname error */ { fprintf(stderr, "%s\n", msg); exit(0); } /********************************************* * Wrappers for Unix process control functions ********************************************/ /* $begin forkwrapper */ pid_t Fork(void) { pid_t pid; if ((pid = fork()) pid_t pid; if ((pid = wait(status)) int rc; if ((rc = kill(pid, signum)) unsigned int rc; if ((rc = sleep(secs)) int rc; if ((rc = setpgid(pid, pgid)) struct sigaction action, old_action; action.sa_handler = handler; sigemptyset(&action.sa_mask); /* Block sigs of type being handled */ action.sa_flags = SA_RESTART; /* Restart syscalls if possible */ if (sigaction(signum, &action, &old_action) if (sigemptyset(set) if (sigaddset(set, signum) int rc; if ((rc = sigismember(set, signum)) int c, i, j; for (i = 0, j = strlen(s)-1; i int c, i = 0; int neg = v int i = 0; while (s[i] != '\0') ++i; return i; } /* $end sioprivate */ /* Public Sio functions */ /* $begin siopublic */ ssize_t sio_puts(char s[]) /* Put string */ { return write(STDOUT_FILENO, s, sio_strlen(s)); //line:csapp:siostrlen } ssize_t sio_putl(long v) /* Put long */ { char s[128]; sio_ltoa(v, s, 10); /* Based on K&R itoa() */ //line:csapp:sioltoa return sio_puts(s); } void sio_error(char s[]) /* Put error message and exit */ { sio_puts(s); _exit(1); //line:csapp:sioexit } /* $end siopublic */ /******************************* * Wrappers for the SIO routines ******************************/ ssize_t Sio_putl(long v) { ssize_t n; if ((n = sio_putl(v)) sio_error(s); } /******************************** * Wrappers for Unix I/O routines ********************************/ int Open(const char *pathname, int flags, mode_t mode) { int rc; if ((rc = open(pathname, flags, mode)) ssize_t rc; if ((rc = write(fd, buf, count)) int rc; if ((rc = close(fd)) int rc; if ((rc = dup2(fd1, fd2)) if (fstat(fd, buf) struct dirent *dep; errno = 0; dep = readdir(dirp); if ((dep == NULL) && (errno != 0)) unix_error("readdir error"); return dep; } int Closedir(DIR *dirp) { int rc; if ((rc = closedir(dirp)) if (munmap(start, length) void *p; if ((p = realloc(ptr, size)) == NULL) unix_error("Realloc error"); return p; } void *Calloc(size_t nmemb, size_t size) { void *p; if ((p = calloc(nmemb, size)) == NULL) unix_error("Calloc error"); return p; } void Free(void *ptr) { free(ptr); } /****************************************** * Wrappers for the Standard I/O functions. ******************************************/ void Fclose(FILE *fp) { if (fclose(fp) != 0) unix_error("Fclose error"); } FILE *Fdopen(int fd, const char *type) { FILE *fp; if ((fp = fdopen(fd, type)) == NULL) unix_error("Fdopen error"); return fp; } char *Fgets(char *ptr, int n, FILE *stream) { char *rptr; if (((rptr = fgets(ptr, n, stream)) == NULL) && ferror(stream)) app_error("Fgets error"); return rptr; } FILE *Fopen(const char *filename, const char *mode) { FILE *fp; if ((fp = fopen(filename, mode)) == NULL) unix_error("Fopen error"); return fp; } void Fputs(const char *ptr, FILE *stream) { if (fputs(ptr, stream) == EOF) unix_error("Fputs error"); } size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t n; if (((n = fread(ptr, size, nmemb, stream)) int rc; if ((rc = socket(domain, type, protocol)) int rc; if ((rc = bind(sockfd, my_addr, addrlen)) int rc; if ((rc = accept(s, addr, addrlen)) int rc; if ((rc = getaddrinfo(node, service, hints, res)) != 0) gai_error(rc, "Getaddrinfo error"); } /* $end getaddrinfo */ void Getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { int rc; if ((rc = getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)) != 0) gai_error(rc, "Getnameinfo error"); } void Freeaddrinfo(struct addrinfo *res) { freeaddrinfo(res); } void Inet_ntop(int af, const void *src, char *dst, socklen_t size) { if (!inet_ntop(af, src, dst, size)) unix_error("Inet_ntop error"); } void Inet_pton(int af, const char *src, void *dst) { int rc; rc = inet_pton(af, src, dst); if (rc == 0) app_error("inet_pton error: invalid dotted-decimal address"); else if (rc struct hostent *p; if ((p = gethostbyaddr(addr, len, type)) == NULL) dns_error("Gethostbyaddr error"); return p; } /************************************************ * Wrappers for Pthreads thread control functions ************************************************/ void Pthread_create(pthread_t *tidp, pthread_attr_t *attrp, void * (*routine)(void *), void *argp) { int rc; if ((rc = pthread_create(tidp, attrp, routine, argp)) != 0) posix_error(rc, "Pthread_create error"); } void Pthread_cancel(pthread_t tid) { int rc; if ((rc = pthread_cancel(tid)) != 0) posix_error(rc, "Pthread_cancel error"); } void Pthread_join(pthread_t tid, void **thread_return) { int rc; if ((rc = pthread_join(tid, thread_return)) != 0) posix_error(rc, "Pthread_join error"); } /* $begin detach */ void Pthread_detach(pthread_t tid) { int rc; if ((rc = pthread_detach(tid)) != 0) posix_error(rc, "Pthread_detach error"); } /* $end detach */ void Pthread_exit(void *retval) { pthread_exit(retval); } pthread_t Pthread_self(void) { return pthread_self(); } void Pthread_once(pthread_once_t *once_control, void (*init_function)()) { pthread_once(once_control, init_function); } /******************************* * Wrappers for Posix semaphores *******************************/ void Sem_init(sem_t *sem, int pshared, unsigned int value) { if (sem_init(sem, pshared, value) if (sem_post(sem) if ((nread = read(fd, bufp, nleft)) size_t nleft = n; ssize_t nwritten; char *bufp = usrbuf; while (nleft > 0) { if ((nwritten = write(fd, bufp, nleft)) int cnt; while (rp->rio_cnt if (errno != EINTR) /* Interrupted by sig handler return */ return -1; } else if (rp->rio_cnt == 0) /* EOF */ return 0; else rp->rio_bufptr = rp->rio_buf; /* Reset buffer ptr */ } /* Copy min(n, rp->rio_cnt) bytes from internal buf to user buf */ cnt = n; if (rp->rio_cnt rio_cnt; memcpy(usrbuf, rp->rio_bufptr, cnt); rp->rio_bufptr += cnt; rp->rio_cnt -= cnt; return cnt; } /* $end rio_read */ /* * rio_readinitb - Associate a descriptor with a read buffer and reset buffer */ /* $begin rio_readinitb */ void rio_readinitb(rio_t *rp, int fd) { rp->rio_fd = fd; rp->rio_cnt = 0; rp->rio_bufptr = rp->rio_buf; } /* $end rio_readinitb */ /* * rio_readnb - Robustly read n bytes (buffered) */ /* $begin rio_readnb */ ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n) { size_t nleft = n; ssize_t nread; char *bufp = usrbuf; while (nleft > 0) { if ((nread = rio_read(rp, bufp, nleft)) = 0 */ } /* $end rio_readnb */ /* * rio_readlineb - Robustly read a text line (buffered) */ /* $begin rio_readlineb */ ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) { int n, rc; char c, *bufp = usrbuf; for (n = 1; n *bufp++ = c; if (c == '\n') { n++; break; } } else if (rc == 0) { if (n == 1) return 0; /* EOF, no data read */ else break; /* EOF, some data was read */ } else return -1; /* Error */ } *bufp = 0; return n-1; } /* $end rio_readlineb */ /********************************** * Wrappers for robust I/O routines **********************************/ ssize_t Rio_readn(int fd, void *ptr, size_t nbytes) { ssize_t n; if ((n = rio_readn(fd, ptr, nbytes)) rio_readinitb(rp, fd); } ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) { ssize_t rc; if ((rc = rio_readnb(rp, usrbuf, n)) int clientfd, rc; struct addrinfo hints, *listp, *p; /* Get a list of potential server addresses */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; /* Open a connection */ hints.ai_flags = AI_NUMERICSERV; /* ... using a numeric port arg. */ hints.ai_flags |= AI_ADDRCONFIG; /* Recommended for connections */ if ((rc = getaddrinfo(hostname, port, &hints, &listp)) != 0) { fprintf(stderr, "getaddrinfo failed (%s:%s): %s\n", hostname, port, gai_strerror(rc)); return -2; } /* Walk the list for one that we can successfully connect to */ for (p = listp; p; p = p->ai_next) { /* Create a socket descriptor */ if ((clientfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) ai_addr, p->ai_addrlen) != -1) break; /* Success */ if (close(clientfd) struct addrinfo hints, *listp, *p; int listenfd, rc, optval=1; /* Get a list of potential server addresses */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; /* Accept connections */ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* ... on any IP address */ hints.ai_flags |= AI_NUMERICSERV; /* ... using port number */ if ((rc = getaddrinfo(NULL, port, &hints, &listp)) != 0) { fprintf(stderr, "getaddrinfo failed (port %s): %s\n", port, gai_strerror(rc)); return -2; } /* Walk the list for one that we can bind to */ for (p = listp; p; p = p->ai_next) { /* Create a socket descriptor */ if ((listenfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) ai_addr, p->ai_addrlen) == 0) break; /* Success */ if (close(listenfd) close(listenfd); return -1; } return listenfd; } /* $end open_listenfd */ /**************************************************** * Wrappers for reentrant protocol-independent helpers ****************************************************/ int Open_clientfd(char *hostname, char *port) { int rc; if ((rc = open_clientfd(hostname, port)) int status, i; pid_t pid; /* Parent creates N children */ for (i = 0; i if (WIFEXITED(status)) printf("child %d terminated normally with exit status=%d\n", pid, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) { /* print signal that cause process exit */ char buf[LEN]; sprintf(buf, "child %d terminated by signal %d", pid, WTERMSIG(status)); psignal(WTERMSIG(status), buf); } else printf("child %d terminated abnormally\n", pid); } /* The only normal termination is if there are no more children */ if (errno != ECHILD) unix_error("waitpid error"); exit(0); } /* $end waitpid1 */ P25 #include #include "csapp.h" sigjmp_buf buf; void handler(int sig) { /* jump */ siglongjmp(buf, 1); } char* tfgets(char* s, int size, FILE* stream) { char* result; if (!sigsetjmp(buf, 1)) { alarm(5); if (signal(SIGALRM, handler) == SIG_ERR) unix_error("set alarm handler error"); return fgets(s, size, stream); } else { /* run out of time */ return NULL; } } #define LEN 100 int main(int argc, char* argv[]) { char buf[LEN]; char* input = tfgets(buf, LEN, stdin); if (input == NULL) { printf("nothing input: NULL\n"); } else { printf("%s", input); } return 0; } P26 🐴 第八章 完


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3