Exam 4 practice questions
Note: in addition to these problems, you should also try Questions 4 and 5 from the Spring 2020 final exam and Question 5 from the Fall 2019 final exam.
A. Unix I/O
A1) Consider the following server main loop:
int server_fd = Open_listenfd(port);
while (1) {
int client_fd = Accept(server_fd, NULL, NULL);
int pid = Fork();
if (pid == 0) {
// in child
chat_with_client(client_fd);
exit(0);
}
}
Assume that
Open_listenfd,Accept, andForkare functions fromcsapp.handcsapp.c- the
chat_with_clientfunction correctly handles all details of communicating with the remote client, including closing the client socket file descriptor - the main server process has a handler for
SIGCHLDto wait for child processes to exit - the server intentionally does not place any limit on how many client sub-processes can be running
- the server intentionally does not have any mechanism for handling shutdown requests
Describe a bug in this main loop, and how to fix it.
B. Network communication
B1) Complete the following function, called chat_with_client. It should implement the server side of a network protocol in which the client will repeatedly send lines of text, and for each line of text that is not quit, the server will send back the reversal of the line sent by the client. When the client sends the line quit, then the client session has ended, and the connection should be closed by the server.
For example, if the client sends
Hello, world
Colorless green sheep sleep furiously
A smell of petroleum prevails throughout
quit
then the server should send back
dlrow ,olleH
ylsuoiruf peels peehs neerg sselroloC
tuohguorht sliaverp muelortep fo llems A
You may implement and call helper functions as necessary. You may use the functions defined in csapp.h and csapp.c.
void chat_with_client(int client_fd) {
// TODO: complete this function
C. Concurrency
C1) Consider the following IntStack data type.
The header file:
// intstack.h
#ifndef INTSTACK_H
#define INTSTACK_H
#define MAX 256
struct IntStack {
int contents[MAX];
int top;
};
void intstack_init(struct IntStack *s);
void intstack_push(struct IntStack *s, int val);
int intstack_pop(struct IntStack *s);
#endif // INTSTACK_H
The implementation file:
// intstack.c
void intstack_init(struct IntStack *s) {
s->top = 0;
}
void intstack_push(struct IntStack *s, int val) {
assert(s->top < MAX);
s->contents[s->top] = val;
s->top++;
}
int intstack_pop(struct IntStack *s) {
assert(s->top > 0);
s->top--;
return s->contents[s->top];
}
Modify the IntStack data type so that it can be safely used by multiple threads.
When the intstack_push function is called, and the stack is full, the function
should wait until the stack is not full, and then push the specified value.
When the intstack_pop function is called, and the stack is empty, the function
should wait until the stack is not empty, and then pop the top value.