학번 : 이름 : 1. What will be the output of this program? assumption: parent's process id=10100, child process id=10101. #include "apue.h" char buf[] = "a write to stdout\n"; int main(void) int var; /* automatic variable on the stack */ pid_t pid; int glob = 31; /* external variable in initialized data */ if (write(stdout_fileno, buf, sizeof(buf)-1)!= sizeof(buf)-1) err_sys("write error"); printf("before fork\n"); /* we don't flush stdout */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) glob++; /* modify variables */ sprintf(buf, stdout\n ); else sleep(2); printf("%d %d %d %s\n", getpid(), pid, glob, buf); exit(0); 2. What will be the output if you change fork with vfork? Hint: 3. Which of the followings are shared among multiple threads/processes? 목록 : code, register, stack, data, heap, file, address space a) multiple threads: b) multiple processes:
4. What will be the output of this program? Explain results for each variable and each thread. #include "apue.h" int var=1; pthread_mutex_t lock; void* mythread(void* arg) sleep((int)(intptr_t)arg); static int glob = 31; int nvar=30; pthread_mutex_lock(&lock); glob++; /* modify variables */ pthread_mutex_unlock(&lock); var++; nvar++; printf("%d %d %d\n", glob, var, nvar); return NULL; int main(void) void* res; pthread_t thread[2]; pthread_create(&thread[0], NULL, mythread, 1); pthread_create(&thread[1], NULL, mythread, 2); pthread_join(&thread[0], &res); pthread_join(&thread[1], &res); return 0; 5. (a) What will be the output of this program? int main() int pip[2]; FILE* fp0; FILE* fp1; char buffer[100]; pipe(pip); fp0=fdopen(3, r ); fp1=fdopen(4, w ); fprintf(fp1, %s, HI ); fclose(fp1); fscanf(fp0, %s\n, buffer); fprintf(stdout, buffer); printf( \n );
(b). 사용자가터미널에서다음명령을입력했을때, 다음세개의프로세스에서호출되는함수를아래보기중나열하시오. 단, 모든 dup2 명령은 Child process 가수행한다고가정하시오. (Assume that dup2 is called from the child process). 명령 : $ cat < main.c grep main 보기 : (1) pipe(rd, WR) // 파일디스크립터 RD ( 입력 ) 와 WR( 출력 ) 을연결하는파이프생성 (2) dup2(wr,1) (3) fork, (4) waitpid, (5) FD=open('main.c'), (6) dup2(fd,0), (7) dup2(rd,0) List which of the above functions are called for each process. Shell process: Child process 1( exec( cat )) : Child process 2( exec( grep )) : sigprocmask description for problem 6:
6. 이전장에나오는 sigprocmask 함수의설명을참고하여다음프로그램의출력물과그출력물이화면이표시되는시점을예측하세요. ( 힌트 : 각줄이표시되는시점은다음 6 가지중하나. (1) 프로그램수행직후, (2) 5 초후 (3) 10 초후 (4) 15 초후 (5) 20 초후 (6) 30 초후 ) #include "apue.h" #include <signal.h> #include <unistd.h> #include <stdio.h> static void sig_usr1(int signo) printf("caught SIGUSR1\n"); int main(void) sigset_t newmask, oldmask, pendmask; if (signal(sigusr1, sig_usr1) == SIG_ERR) err_sys("can't catch SIGUSR1"); sigemptyset(&newmask); sigaddset(&newmask, SIGUSR1); if (sigprocmask(sig_block, &newmask, &oldmask) < 0) err_sys("sig_block error"); sleep(15); /* Reset signal mask */ if (sigprocmask(sig_setmask, &oldmask, NULL) < 0) err_sys("sig_setmask error"); sleep(15); printf("done!\n"); exit(0); 실행내용 : $./a.out & [1] 21413 ( 21413 이라는 process id 로백그라운드에서수행중.) $ kill -USR1 21413 (5 초가지난후이명령이실행된다고가정.) $ kill -USR1 21413 (8 초가지난후이명령이실행된다고가정.) $ kill -USR1 21413 (20 초가지난후이명령이실행된다고가정.) ( 모든시간은프로그램시작시간기준임 ) 결과물및각줄의출력시점 :
7. 다음은클라이언트가보낸메시지를처리하는간단한서버프로그램의소스코드이다. #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> int main() int server_sockfd, jlient_sockfd; int server_len, client_len; char string[256]; struct sockaddr_in server_address; struct sockaddr_in client_address; server_sockfd = socket(af_inet, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(inaddr_any); server_address.sin_port = htons(9734); server_len = sizeof(server_address); printf("0\n"); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); printf("1\n"); listen(server_sockfd, 5); printf("2\n"); client_sockfd=accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); printf("3\n"); read(client_sockfd, string, 256); printf("%s\n", string);... 만약클라이언트가서버에연결후아래코드를실행했을때각줄실행전후서버의출력을예측하세요. connect(sockfd, (struct sockaddr *)&address, sizeof(address)); // 연결된다고가정. write(sockfd, "asdf", 5);
8. 다음두개의소스코드를보고, 아래명령문의출력을예측하세요. ( 단 real user-id 는 1000 가정, 공란총 2 개채우세요 ) a.out (a.c): #include "apue.h" int main(int argc, char *argv[]) system(argv[1]); exit(0); b.out (b.c): #include "apue.h" int main(void) printf("real uid=%d effective uid=%d\n", getuid(), geteuid()); return 0; $./a.out./b.out $ sudo chown root./a.out $ sudo chmod +s./a.out $./a.out./b.out 9. a. 위에서만들어진 a.out 은보안상위험하다. 그이유를설명하고, 그위험성을피하기위해 a.c 를수정하시오. Hint: seteuid(new_effective_user_id) 함수사용할것. b. Saved SUID 개념이필요한이유를위시나리오와관련하여설명하세요. a.c 는반드시 effective root 권한이필요한프로그램이지만, 때때로임의의다른프로그램을호출해야한다고가정하세요.
10. 다음 4 가지프로그램이구현되어있다고가정하자../tolower ( stdin 입력을소문자로변환해 stdout 으로출력하는프로그램 )./toupper ( stdin 입력을대문자로변환해 stdout 으로출력하는프로그램 )./tomixed ( stdin 입력을소문자와대문자로번갈아가면서변환해 stdout 으로출력 ) tee ( stdin 입력을파일과 stdout 으로동시에출력 ) 또한다음두개의파일이있다고가정하자. File1: asdf ASDF File2: povijh 다음각과정에서화면출력, 파일출력, 프로그램종료등을 모두 예측하세요 : $./tolower < File1 $ mkfifo fifo1 $./tolower < fifo1 > File3 & $./toupper < File1 tee fifo1 $ cat File3 $./toupper < File3 > fifo1 아래정의를참고하여 10 번문항을푸세요.
11. 다음은채팅프로그램의클라이언트소스코드이다. 공란을채우시오. ( 총 6 개 ) void prompt() printf("<you> "); fflush(stdout); main (int argc, char *argv[]) int len, rc, sockfd, max_sd; char send_buf[4096], recv_buf[4096]; struct sockaddr_in serv_addr; fd_set master_set, select_result; sockfd = socket(af_inet, SOCK_STREAM, 0)); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(server_port); inet_pton(af_inet, argv[1], &serv_addr.sin_addr); connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr); FD_ZERO(&master_set); FD_SET(, & master_set); FD_SET(, & master_set); max_sd=max(, ); printf("connected to remote host. Start sending messages.\n"); prompt(); while(1) memcpy(&select_result, &master_set, sizeof(master_set)); rc = select(max_sd + 1, &select_result, NULL, NULL, NULL); if( ) gets(send_buf); send(sockfd, send_buf, strlen(send_buf), 0); prompt(); else if( ) rc = recv(sockfd, recv_buf, 4096, 0); if (rc < 0) exit(-9); // recv failed if (rc == 0) printf("server disconnected\n"); close(sockfd); exit(0); recv_buf[rc]=0; // make null terminated string printf("\r%s\n", recv_buf); prompt(); else // timed out close(sockfd); return 0; close(sockfd); return 0;
12. 다음은무한루프를돌면서클라이언트가보낸메시지를처리하는서버프로그램의소스코드이다. #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> int main() int server_sockfd, jlient_sockfd; int server_len, client_len; char string[256]; struct sockaddr_in server_address; struct sockaddr_in client_address; server_sockfd = socket(af_inet, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(inaddr_any); server_address.sin_port = htons(9734); server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); listen(server_sockfd, 5); while(1) printf("server waiting\n"); client_sockfd=accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); while(1) read(client_sockfd, string, 256); printf("from client = %s\n", string); write(client_sockfd, string, 256); a. 만약클라이언트가서버에연결후아래코드를실행했을때서버와클라이언트프로그램의화면출력을예측하세요. char string[256] connect(sockfd, (struct sockaddr *)&address, sizeof(address)); // 연결된다고가정. read(sockfd, string2, 256); write(sockfd, "asdf", 5); printf("from server = %s\n", string2); b. 아래코드를수행했을때의수행결과를예측하세요. char string[256] connect(sockfd, (struct sockaddr *)&address, sizeof(address)); // 연결된다고가정. write(sockfd, "asdf", 5); read(sockfd, string2, 256); printf("from server = %s\n", string2);
c. 위서버프로그램은단한명의클라이언트만을다룰수있다. 이프로그램을여러클라이언트를지원하도록개선하기위하여 I/O Multiplexing 을이용하는경우, select 함수를이용할수있다. 즉 select 함수의입력으로파일서술자 (file descriptor) 의목록이저장된 fd_set 을넘겨주고, 그중사용가능한파일서술자가생길때까지차단되어 (block) 기다리는방식으로구현할수있다. 다음 select 함수의설명을참조하여예를들어클라이언트가 4 명접속되어있는경우, select 함수의인자로들어가는 readfds 에어떤 file descriptor 가선택되어있어야하는지나열하세요. 13. You run gcc -c final.c -final.o to compile the code. a. What would be in the final.o file? b. Now, you link final.o along with the standard C library (libc.a). What is the command line to do that? (hint: libc.a will be linked by default. You do not need to specify any dependencies.) c. What does the linker do if the C library is a static library (libc.a)? d. If the C library is a dynamic shared library (libc.so), how is the program different?
14. Which lines of the above code always generate a system call? List '#'s. 15. Which lines of the above code might generate a system call? List '#'s. (hint: system call sbrk changes data segment size.)
16. Consider the following program. Assume that there won't be any unexpected signals. int ticks =0; void handler(int signum ) ticks ++; printf ("tick tock: %d\n", ticks ); if(ticks < 10) alarm (1); else raise (SIGQUIT); //< MARK 1 int main () signal(sigalrm, handler ); //< MARK 2 alarm (1); //MARK 3 while (1) pause (); //< MARK 3 a. At MARK 2, what is the purpose of the call to signal() with respect to future deliveries of SIGALRM from the O.S.? b. What is the result of the system call at MARK 1? c. How many SIGALRM signals are delivered to the program? Explain. d. What is the purpose of pause() at MARK 3? Is it better or worse then replacing it with the following code without pause()? //MARK 3 while(1);