proj/exam-2020W-2A: Add Musterlösung
This commit is contained in:
@@ -64,10 +64,32 @@ void error_exit(const char *msg) {
|
|||||||
* Hints: getaddrinfo(3), socket(2), listen(2)
|
* Hints: getaddrinfo(3), socket(2), listen(2)
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int setup_connection(const char *port_str) {
|
int setup_connection(const char *port_str) {
|
||||||
// put your code here
|
struct addrinfo hints, *ai;
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
// Replace with a meaningful return value
|
int res = getaddrinfo(NULL, port_str, &hints, &ai);
|
||||||
return -1;
|
if (res != 0)
|
||||||
|
error_exit("getaddrinfo() failed");
|
||||||
|
|
||||||
|
int sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
|
if (sockfd < 0)
|
||||||
|
error_exit("socket() failed");
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
|
||||||
|
error_exit("setsockopt() failed");
|
||||||
|
|
||||||
|
if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)
|
||||||
|
error_exit("bind() failed");
|
||||||
|
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
|
||||||
|
if (listen(sockfd, 1) < 0)
|
||||||
|
error_exit("listen() failed");
|
||||||
|
return sockfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -91,7 +113,29 @@ int setup_connection(const char *port_str) {
|
|||||||
* Hints: accept(2), fdopen(3), fgets(3), fprintf(3), fclose(3)
|
* Hints: accept(2), fdopen(3), fgets(3), fprintf(3), fclose(3)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void server_request_handler(int sockfd, const char *command) {
|
void server_request_handler(int sockfd, const char *command) {
|
||||||
// put your code here
|
int connfd = accept(sockfd, NULL, NULL);
|
||||||
|
if (connfd < 0)
|
||||||
|
error_exit("accept() failed");
|
||||||
|
|
||||||
|
|
||||||
|
FILE *fps = fdopen(connfd, "w+");
|
||||||
|
|
||||||
|
char argument[MAX_ARGUMENT_LEN + 1] = {0};
|
||||||
|
fgets(argument, sizeof(argument), fps);
|
||||||
|
|
||||||
|
FILE *fpc = NULL;
|
||||||
|
fpc = execute_command(command, argument);
|
||||||
|
|
||||||
|
if (fpc) {
|
||||||
|
int c;
|
||||||
|
while ((c = fgetc(fpc)) != EOF)
|
||||||
|
fputc(c, fps);
|
||||||
|
fclose(fpc);
|
||||||
|
} else {
|
||||||
|
fputs("COMMAND_FAILED", fps);
|
||||||
|
}
|
||||||
|
fflush(fps);
|
||||||
|
fclose(fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -120,10 +164,50 @@ void server_request_handler(int sockfd, const char *command) {
|
|||||||
* Hints: pipe(2), dup2(2), fork(2), exec(3), fdopen(3), wait(3)
|
* Hints: pipe(2), dup2(2), fork(2), exec(3), fdopen(3), wait(3)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
FILE *execute_command(const char *command, const char *argument) {
|
FILE *execute_command(const char *command, const char *argument) {
|
||||||
// put your code here
|
// file stream to read the output of the process
|
||||||
|
FILE *proc_output = NULL;
|
||||||
|
|
||||||
// Replace with a meaningful return value
|
// file descriptors for the pipe for parent-child process communication
|
||||||
return NULL;
|
int c2p[2];
|
||||||
|
|
||||||
|
// create the pipes
|
||||||
|
if (pipe(c2p) == -1)
|
||||||
|
error_exit("cannot create pipe");
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case 0:
|
||||||
|
// duplicate write end to stdout
|
||||||
|
if (dup2(c2p[1], STDOUT_FILENO) == -1) {
|
||||||
|
error_exit("dup2() failed");
|
||||||
|
}
|
||||||
|
close(c2p[0]);
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
|
||||||
|
// exec the command
|
||||||
|
if (execlp(command, command, argument, NULL) == -1) {
|
||||||
|
error_exit("exec() failed");
|
||||||
|
}
|
||||||
|
case -1:
|
||||||
|
error_exit("fork() failed");
|
||||||
|
|
||||||
|
default:
|
||||||
|
// parent process
|
||||||
|
proc_output = fdopen(c2p[0], "r");
|
||||||
|
if (proc_output == NULL) {
|
||||||
|
error_exit("fdopen() failed");
|
||||||
|
}
|
||||||
|
close(c2p[1]);
|
||||||
|
|
||||||
|
int stat = 0;
|
||||||
|
wait(&stat);
|
||||||
|
|
||||||
|
if (WIFEXITED(stat) && WEXITSTATUS(stat) == 0) {
|
||||||
|
} else {
|
||||||
|
proc_output = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return proc_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user