Du befindest dich hier: FSI Informatik » jahrgaenge » 2006 » "Muster"-Lösungen » "Muster"-Lösungen zu Klausuren aus Softwaresysteme 1 » Vordiplomsklausuren » März 2005
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige ÜberarbeitungVorherige ÜberarbeitungNächste Überarbeitung | Vorherige Überarbeitung | ||
jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2005 [03.09.2007 08:19] – 10.222.3.150 | jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2005 [08.09.2007 19:17] (aktuell) – 89.58.27.191 | ||
---|---|---|---|
Zeile 3: | Zeile 3: | ||
==== Aufgabe 1 ==== | ==== Aufgabe 1 ==== | ||
- | * a) **?** | + | * a) 3 (?) |
* b) 1 | * b) 1 | ||
- | * c) 3 (?) | + | * c) 3 ([[http:// |
* d) 3 | * d) 3 | ||
- | * e) 1 => ** Korrektur: 3 ** | + | * e) 1 |
- | * f) 1(?) | + | * f) 1(?) das ist mal ne wirklich interessante frage... |
+ | -> Wenn zu einem Zeitpunkt nur ein Prozeß reell laufen kann, weil nur ein Prozessor da ist, und wenn dabei keine Verdrängung stattfinden kann, kommt keine Nebenläufigkeit zustande. Also müssen die Zugriffe nicht koordiniert werden. | ||
* g) 3 | * g) 3 | ||
* h) 2 | * h) 2 | ||
* i) 4 | * i) 4 | ||
- | * j) 4 (?) | + | * j) 4 //(?) ich tippe auf 2: eine seite = 4096, hauptspeicher = 4GB => ca. 2000 seiten im system, jeder eintrag in der tabelle 4 byte (32bit) macht dann 2000 x 4 = 8000 byte...// -> 4 ist korrekt, Rechnung: 4294967296 / 4096 *32 / 8 = 4194304 //Ich will nen TR!// |
* k) 3 | * k) 3 | ||
* l) 2 | * l) 2 | ||
- | * m) 4 => ** Korrektur: 3 ** | + | * m) 4 |
* n) 2 | * n) 2 | ||
* o) 4 | * o) 4 | ||
Zeile 24: | Zeile 25: | ||
<code c> | <code c> | ||
+ | /* includes */ | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | /* Funktionsdeklarationen, | ||
+ | |||
+ | #define MAX_LEN 128 | ||
+ | |||
+ | int main(int argc, char **argv); | ||
+ | static void serve(int sock); | ||
+ | static void prattr(char *filename); | ||
+ | static void error(char *msg); | ||
+ | static void sighandler(int sig); | ||
+ | |||
+ | /* Funktion main */ | ||
+ | |||
+ | int main(int argc, char **argv) | ||
+ | { | ||
+ | /* lokale Variablen und was man sonst am Anfang so vorbereitet */ | ||
+ | |||
+ | int port; | ||
+ | int sock; | ||
+ | struct sockaddr_in addr; | ||
+ | struct sockaddr_in client_addr; | ||
+ | int client_addr_len = sizeof(struct sockaddr_in); | ||
+ | int client_sock; | ||
+ | int pid; | ||
+ | struct sigaction action; | ||
+ | |||
+ | if (argc != 2) { | ||
+ | printf(" | ||
+ | exit(1); | ||
+ | } | ||
+ | port = atoi(argv[1]); | ||
+ | |||
+ | /* Ein Signal-Handler für SIGCHLD (ein Kindprozess stirbt) wird installiert. So können Zombies mit waitpid abgeholt werden. */ | ||
+ | action.sa_handler = sighandler; | ||
+ | sigemtpyset(& | ||
+ | action.flags = SA_RESTART; | ||
+ | sigaction(SIGCHLD, | ||
+ | |||
+ | /* Socket oeffnen */ | ||
+ | |||
+ | sock = socket(PF_INET, | ||
+ | if (sock == -1) error(" | ||
+ | |||
+ | /* Socket an angegebenen Port und beliebige IP-Adressen binden */ | ||
+ | |||
+ | addr.sin_family = AF_INET; | ||
+ | addr.sin_port = htons(port); | ||
+ | addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
+ | if (bind(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1) error(" | ||
+ | |||
+ | /* Warteschlange ankommender Verbindungen auf 5 einstellen */ | ||
+ | |||
+ | if (listen(sock, | ||
+ | |||
+ | /* Server-Schleife */ | ||
+ | |||
+ | while (1) { | ||
+ | |||
+ | /* Verbindung aufnehmen */ | ||
+ | |||
+ | client_sock = accept(sock, | ||
+ | if (client_sock == -1) error(" | ||
+ | |||
+ | /* Prozess zur Kommandoausführung erzeugen */ | ||
+ | |||
+ | pid = fork(); | ||
+ | switch(pid) { | ||
+ | |||
+ | /* Fehler bei Prozesserzeugung */ | ||
+ | |||
+ | case -1: | ||
+ | error(" | ||
+ | break; | ||
+ | |||
+ | /* Sohnprozess */ | ||
+ | |||
+ | case 0: | ||
+ | serve(client_sock); | ||
+ | break; | ||
+ | |||
+ | /* Vaterprozess */ | ||
+ | |||
+ | default: | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } /* Ende Funktion main */ | ||
+ | |||
+ | /* serve-Funktion */ | ||
+ | |||
+ | static void serve(int sock) { | ||
+ | FILE *f; | ||
+ | char buffer[MAX_LEN + 2]; | ||
+ | |||
+ | f = fdopen(sock, | ||
+ | if (f == NULL) error(" | ||
+ | |||
+ | errno = 0; | ||
+ | while (fgets(buffer, | ||
+ | buffer[strlen(buffer) - 1] = ' | ||
+ | prattr(buffer); | ||
+ | errno = 0; | ||
+ | } | ||
+ | if (errno != 0) error(" | ||
+ | |||
+ | fclose(f); | ||
+ | close(sock); | ||
+ | |||
+ | exit(0); | ||
+ | } | ||
+ | |||
+ | /* prattr-Funktion */ | ||
+ | |||
+ | static void prattr(char *filename) { | ||
+ | struct stat info; | ||
+ | |||
+ | if (stat(filename, | ||
+ | printf(" | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (S_ISREG(info.st_mode)) { | ||
+ | printf(" | ||
+ | } else if (S_ISDIR(info.st_mode)) { | ||
+ | printf(" | ||
+ | } else { | ||
+ | printf(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* weitere Funktionen, falls benoetigt */ | ||
+ | |||
+ | static void error(char *msg) { | ||
+ | perror(msg); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | static void sighandler(int sig) { | ||
+ | int pid; | ||
+ | int status; | ||
+ | |||
+ | while ((pid = waitpid(-1, & | ||
+ | if (pid == -1) error(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | Alternative Lösung: Diese schreibt die angeforderte Information auch wieder auf den socket zurück | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | /* fehlende includes */ | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #define DEFAULT_PORT 31337 | ||
+ | |||
+ | static void serve(int socket); | ||
+ | static void prattr(char *filename); | ||
+ | static void sigchld_handler_install(void); | ||
+ | static void sigchld_handler(int sig); | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | int sock; | ||
+ | unsigned short port; | ||
+ | struct sockaddr_in saddr; | ||
+ | |||
+ | if (argc > 1) { | ||
+ | port = atoi(argv[1]); | ||
+ | } else { | ||
+ | port = DEFAULT_PORT; | ||
+ | } | ||
+ | |||
+ | sigchld_handler_install(); | ||
+ | |||
+ | sock = socket(PF_INET, | ||
+ | if (sock < 0) { | ||
+ | perror(" | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | | ||
+ | saddr.sin_family = AF_INET; | ||
+ | saddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
+ | saddr.sin_port = htons(port); | ||
+ | |||
+ | if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { | ||
+ | perror(" | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | |||
+ | if (listen(sock, | ||
+ | perror(" | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | | ||
+ | printf(" | ||
+ | | ||
+ | while (1) { | ||
+ | pid_t pid; | ||
+ | int clsock; | ||
+ | struct sockaddr clsaddr; | ||
+ | socklen_t clsaddr_len = sizeof(clsaddr); | ||
+ | |||
+ | clsock = accept(sock, | ||
+ | if (clsock == -1) { | ||
+ | perror(" | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | switch(pid = fork()) { | ||
+ | case -1: | ||
+ | /* error */ | ||
+ | perror(" | ||
+ | return EXIT_FAILURE; | ||
+ | |||
+ | break; | ||
+ | case 0: | ||
+ | /* child */ | ||
+ | close(sock); | ||
+ | |||
+ | serve(clsock); | ||
+ | |||
+ | close(clsock); | ||
+ | exit(EXIT_SUCCESS); | ||
+ | |||
+ | break; | ||
+ | case 1: | ||
+ | /* parent */ | ||
+ | close(clsock); | ||
+ | |||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return EXIT_SUCCESS; | ||
+ | } | ||
+ | |||
+ | static void serve(int socket) { | ||
+ | char file[128+2]; | ||
+ | FILE *fd = fdopen(socket, | ||
+ | |||
+ | if (dup2(socket, | ||
+ | perror(" | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | |||
+ | while(fgets(file, | ||
+ | file[strlen(file)-1] = ' | ||
+ | |||
+ | prattr(file); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | static void prattr(char *filename) { | ||
+ | struct stat statbuf; | ||
+ | |||
+ | if (stat(filename, | ||
+ | printf(" | ||
+ | } else { | ||
+ | if (S_ISDIR(statbuf.st_mode)) { | ||
+ | printf(" | ||
+ | } else if (S_ISREG(statbuf.st_mode)) { | ||
+ | printf(" | ||
+ | } else { | ||
+ | printf(" | ||
+ | } | ||
+ | } | ||
+ | fclose(fd); | ||
+ | } | ||
+ | |||
+ | static void sigchld_handler_install(void) { | ||
+ | struct sigaction sa; | ||
+ | | ||
+ | sigemptyset(& | ||
+ | sa.sa_handler = sigchld_handler; | ||
+ | sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; | ||
+ | if (sigaction(SIGCHLD, | ||
+ | perror(" | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | static void sigchld_handler(int sig) { | ||
+ | int errsvr; | ||
+ | int status; | ||
+ | pid_t pid; | ||
+ | |||
+ | errsvr = errno; | ||
+ | |||
+ | while((pid = waitpid(-1, & | ||
+ | if (pid == -1) { | ||
+ | if (errno == ECHILD) { | ||
+ | break; | ||
+ | } | ||
+ | perror(" | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | errno = errsvr; | ||
+ | } | ||
</ | </ | ||
* b) | * b) | ||
+ | |||
+ | < | ||
+ | fileattrd: fileattrd.o | ||
+ | |||
+ | .PHONY: clean | ||
+ | clean: | ||
+ | $(RM) fileattrd fileattrd.o | ||
+ | |||
+ | #restliche regeln sind alle implizit vorhanden | ||
+ | |||
+ | </ | ||
==== Aufgabe 3 ==== | ==== Aufgabe 3 ==== |