900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > [第八章] 深入理解计算机系统第三版 家庭作业参考答案

[第八章] 深入理解计算机系统第三版 家庭作业参考答案

时间:2020-12-08 17:14:26

相关推荐

[第八章] 深入理解计算机系统第三版 家庭作业参考答案

8.9

8.10

A.fork

B.longjmp execve

C.setjmp

8.11

4次,画画进程图就行了

8.12

8次

8.13

x=4

x=3

x=2

8.14

3

8.15

5

8.16

counter = 2

8.17

hello 0 1 Bye 2 Bye

hello 1 0 Bye 2 Bye

hello 1 Bye 0 2 Bye

8.18

BD

8.19

2^n

8.20

#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <setjmp.h>#include <signal.h>#include <dirent.h>#include <sys/time.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <errno.h>#include <math.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>void unix_error(char *msg) /* Unix-style error */{fprintf(stderr, "%s: %s\n", msg, strerror(errno));exit(0);}void Execve(const char *filename, char *const argv[], char *const envp[]) {if (execve(filename, argv, envp) < 0)unix_error("Execve error");}int main(int argc, char **argv, char **env) {Execve("/bin/ls", argv, env);return 0;}

8.21

abc 或 bac

8.22

#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <setjmp.h>#include <signal.h>#include <dirent.h>#include <sys/time.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <errno.h>#include <math.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#define MAXARGS 128#define MAXLINE 8192 /* Max text line length */extern char **environ; /* Defined by libc *//* Linux C中environ 变量是一个char** 类型,存储着系统的环境变量 */void unix_error(char *msg) /* Unix-style error */{fprintf(stderr, "%s: %s\n", msg, strerror(errno));exit(0);}void app_error(char *msg) /* Application error */{fprintf(stderr, "%s\n", msg);exit(0);}pid_t Wait(int *status) {pid_t pid;if ((pid = wait(status)) < 0)unix_error("Wait error");return pid;}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;}/* parseline - Parse the command line and build the argv array */int parseline(char *buf, char **argv) {char *delim; /* Points to first space delimiter */int argc; /* Number of args */int bg; /* Background job? */buf[strlen(buf)-1] = ' '; /* Replace trailing '\n' with space */while (*buf && (*buf == ' ')) /* Ignore leading spaces */buf++;/* Build the argv list */argc = 0;while ((delim = strchr(buf, ' '))) {argv[argc++] = buf;*delim = '\0';buf = delim + 1;while (*buf && (*buf == ' ')) /* Ignore spaces */buf++;}argv[argc] = NULL;if (argc == 0) /* Ignore blank line */return 1;/* Should the job run in the background? */if ((bg = (*argv[argc-1] == '&')) != 0)argv[--argc] = NULL;return bg;}pid_t Fork(void) {pid_t pid;if ((pid = fork()) < 0)unix_error("Fork error");return pid;}int mysystem(char *command) {char *Argv[MAXARGS];int status;if(Fork() == 0) {parseline(command, Argv);for(int i = 0; i < MAXARGS; i++) {if(Argv[i]==NULL) {break;}}execve("/bin/sh", Argv, environ);}Wait(&status); /*等待子进程结束*/return WEXITSTATUS(status);}int main(int argc, char **argv, char **env) {char str[12] = "/bin/sh -c ";char command[MAXLINE];char temp[MAXLINE-12];printf("\033[1;32m>\033[0m ");while(Fgets(temp, MAXLINE-12, stdin)) {strcpy(command, str);strcat(command, temp);printf("\033[1;32m mysystem 返回值为 %d \n\033[0m", mysystem(command));printf("\033[1;32m\n>\033[0m ");}return 0;}

我并没有使用 “csapp.h” 头文件,而是用到什么就复制出什么,一方面可以清楚被封装函数的调用方法,另一方面可以学习作者是如何对函数进行封装的。

我做的有些麻烦,虽然使用了 parseline 函数,但是我的代码只支持不带参数的 command,比如 “/bin/sh ls -a”,就只能识别到 “/bin/sh ls”,可以修改 parseline 函数,不过我懒 (ಥ _ ಥ)

对于几种不同的输入,有不同的返回值:

USER@NAME:~# ./mysystem> ls123.py 公共模板.........mysystem 返回值为 0 > ./exit12mysystem 返回值为 12 > lllll/bin/sh: 1: lllll: not foundmysystem 返回值为 127

exit12 程序非常简单,只有四行:

#include <stdio.h>#include <stdlib.h>int main() {exit(12);}

8.23

一个进程的待处理信号不会排队,只会被丢弃。

8.24

#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <setjmp.h>#include <signal.h>#include <dirent.h>#include <sys/time.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <errno.h>#include <math.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#define N 2const char CONSTINT[10] = "HAHA";//只读常量void unix_error(char *msg) /* Unix-style error */{fprintf(stderr, "%s: %s\n", msg, strerror(errno));exit(0);}pid_t Waitpid(pid_t pid, int *iptr, int options) {pid_t retpid;if ((retpid = waitpid(pid, iptr, options)) < 0) unix_error("Waitpid error");return(retpid);}pid_t Fork(void) {pid_t pid;if ((pid = fork()) < 0)unix_error("Fork error");return pid;}int main() {int status, i;pid_t pid;for (i = 0; i < N; i++) if ((pid = Fork()) == 0) {/* Child */scanf("%s", &CONSTINT); //访问只读常量exit(100 + i); } while ((pid = waitpid(-1, &status, 0)) > 0) {if (WIFEXITED(status)) {printf("child %d terminated normally with exit status=%d\n",pid, WEXITSTATUS(status)); }else if(WIFSIGNALED(status)) {//const char *s;printf("child %d terminated by signal %d:", pid, WTERMSIG(status));fflush(stdout);psignal(WTERMSIG(status), NULL);}}if (errno != ECHILD)unix_error("waitpid error");exit(0);}

USER@NAME:~# gcc -o P8-24 P8-24.c USER@NAME:~# ./P8-24123123child 11345 terminated by signal 11: Segmentation fault22child 11344 terminated by signal 11: Segmentation fault

8.25

#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <setjmp.h>#include <signal.h>#include <dirent.h>#include <sys/time.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <errno.h>#include <math.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>sigjmp_buf buf;unsigned int Alarm(unsigned int seconds) {return alarm(seconds);}void handler(int sig) {siglongjmp(buf, 1);}char *tfgets(char *s, int size, FILE *stream) {signal(SIGALRM, handler);if (!sigsetjmp(buf, 1)) {Alarm(5);fgets(s, size, stream);}else {return NULL;}signal(SIGALRM, SIG_DFL);return s;}int main() {while(1) {char s[50];char *temp = tfgets(s, 50, stdin);if(temp == NULL) {printf("超时\n\n");} else {printf("输入的字符串是:%s\n", temp);}}exit(0); }

8.26

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。