====== Lösungsvorschlag ====== ==== Aufgabe 1.1: Einfachauswahl-Fragen ==== **a)** 4 **b)** 1 **c)** 2 **d)** 1 **e)** 3 **f)** 3 **g)** 1 **h)** 2 **i)** 3 **j)** 4 **k)** 4 ==== Aufgabe 1.2: Mehrfachauswahl-Fragen ==== **a)** 1,4,6,8 **b)** 1,2,5,6,7 ==== Aufgabe 2: pinboard ==== **//TODO: FIX CODE!//** #include #include #include #include #include #include #include #include #include #include #include #include // Konstanten, Hilfsfunktionen #define LISTEN_PORT 1952 #define MAX_CLIENTS 32 #define MAX_LINE_LEN 1024 #define MESSAGE_DIR "/Users/killerchicken/klausurdinge" static void die(const char message[]) { perror(message); exit(EXIT_FAILURE); } // Funktionsdeklarationen, globale Variablen usw. static void serve(int clientSock); static int show(FILE *tx); static int pin(FILE *rx, const char msgTitle[]); static void handler(int signal); static volatile int processCounter; static sigset_t mask, old; // Funktion main() int main(int argc, char* argv[]) { struct sigaction sa = { .sa_flags = SA_RESTART|SA_NOCLDSTOP; .sa_handler = handler; }; sigemptyset(&sa.sa_mask)) (sigaction(SIGCHLD, &sa, NULL) sigemptyset(&mask); sigemptyset(&old); sigaddset(&mask, SIGCHLD); // Socket erstellen und auf Verbindungsannahme vorbereiten int sock = socket(AF_INET6, SOCK_STREAM, 0); if (sock == -1) { die("socket"); } struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6; .sin6_port = htons(LISTEN_PORT); .sin6_other = in6addr_any; }; if (-1 == bind(sock, (struct sockaddr*)&sin6, sizeof(sin6))) { die("bind"); } if (-1 == listen(sock,SOMAXCONN)) { die("listen"); } // Verbindungen annehmen und Kindprozesse starten while (1) { int client_sock = accept(sock, NULL, NULL); if (-1 == client_sock) { die("accept"); } sigprocmask(SIG_BLOCK, &block, &old); while (processCounter != 32) { sigsuspend(&old); } pid_t pid = fork(); if (pid == -1) { die("fork"); } else if (!pid) { sigprocmask(SIG_SETMASK, &old, NULL); serve(client_sock); } processCounter++; sigprocmask(SIG_SETMASK, &old, NULL); close(client_sock); } return 0; } // Ende Funktion main // Signalbehandlung für SIGCHLD static void handler(int signal) { int old_errno; while(waitpid(-1, NULL, WNOHANG) < 0) { processCounter--; } errno = old_errno; } // Ende Signalbehandlung // Funktion serve() static void serve(int client_sock) { FILE* client = fdopen(client_sock, "r"); if (!client) { perror("fdopen"); close(client); return; } char befehl[MAX_LINE_LEN + 1]; if (!fgets(befehl, sizeof(befehl), client)) { //perror("fgets"); close(client); return; } if (ferror(client)) { perror("client"); close(client); return; } if (strcmp(befehl, "show") == NULL) { show(client); fputs(client_sock, "OK"); fclose(client); } if (strncmp(befehl, "pin", 3) == NULL) { befehl[3] == '\0'; const char* filename = befehl + 4; pin(client, filename); fputs(client_sock, "OK"); fclose(client); } fputs(client_sock, "Failed!"); fclose(client); return; } // Ende Funktion serve() // Funktion show() static int show(FILE* tx) { DIR* d = opendir(MESSAGE_DIR); if (!d) { perror("opendir"); return -1; } struct dirent* e; while(errno = 0, (e = readdir(d)) != NULL) { if (e->d_name[0] == '.') { continue; } if (strcmp(e->d_name, ".") == 0) { continue; } char path[strlen(MESSAGE_DIR) + strlen(e->d_name) + 2]; sprintf(path, "%s/%s", MESSAGE_DIR, e->d_name); struct stat s; if (-1 == lstat(path, &s)) { perror("lstat"); continue; } if (S_ISREG(s.st_mode)) { errno = 0; fputs("== ", tx); fputs(e->d_name, tx); fputs(" ==\n", tx); if (errno != 0) { perror("fputs"); continue; } FILE* c = fopen(path, "r+"); if (c == NULL) { perror("fopen"); continue; } int ch; while ((ch = fgetc(c)) != EOF) { if (fputc(ch, tx) == EOF) { perror("fputc"); continue; } } if (fputc('\n', tx)) { perror("fputc"); continue; } fclose(c); } } if (errno != 0) { perror("readdir"); closedir(d); return -1; } closedir(d); return 0; } // Ende Funktion show() static int pin(FILE* rx,char* buf){ char s[MAX_LINE_LENGTH]; strcpy(s,buf+4); if(fgets(buf,MAX_LINE_LENGTH-1,rx)==NULL){ if(!feof(rx)) return -1; } if(buf[0]=='.') return -1; if(strchr(buf,(int)'/')!=NULL) return -1; //createfile and write FILE* f; if((f=fopen(buf,"w"))==NULL)return -1; fprintf(f,buf); fflush(f); fclose(f); return 0; } // Funktion pin() ==== Aufgabe 3: ==== **a)** TODO **b)** . . 3 4000 1 rw- 4 7000 1 rw- 5 8000 1 rw- 6 d000 1 rw- (Seitennummer, Adresse, Rechte) Adresse, present, read, write, execute 0 0x0 0 0 0 0 ← BTBP 1 0x6 1 1 0 1 2 0xd 1 1 1 0 3 0x0 0 0 0 0 4 0x0 0 0 0 0 5 0x0 0 0 0 0 6 0x0 0 0 0 0 7 0x0 0 0 0 0 8 0x0 0 0 0 0 9 0x0 0 0 0 0 A 0x0 0 0 0 0 B 0x0 0 0 0 0 C 0x0 0 0 0 0 D 0x0 0 0 0 0 E 0x0 0 0 0 0 F 0x9 1 1 1 0 0x2140 ------> 0xd140 **c)** Damit Adressfehler zu einem Trap fuehren (NULL-Pointer) ==== Aufgabe 4: ==== **a)** TODO **b)** Kernel-Threads: koennen auf mehrere Kerne/Prozessoren aufgeteilt werde LightWeight: koenne auch aufgeteilt werden (da sie aber mitunter gemeinsamme Daten haben muessen diese im niedrigsten gemeinsammen Speicher liegen und umso "hoeher der Speicher desto langsammer der Zugriff)) User: koennen nicht aufgeteilt werden