Du befindest dich hier: FSI Informatik » jahrgaenge » 2006 » "Muster"-Lösungen » "Muster"-Lösungen zu Klausuren aus Softwaresysteme 1 » Vordiplomsklausuren » März 2006
März 2006
Aufgabe 1
- b) 3
- c) 1 ist als falsch gedacht und unpassend formuliert (hat juk, glaube ich, gesagt; gemeint ist, daß alle Adressen zum Zeitpunkt des Programmstarts aufgelöst werden, aber das ist nicht richtig, weil es Adreßbezüge gibt, die vorher aufgelöst werden können.)
- d) 1
- e) 2
- f) 4
- g) 1
- h) 4
- i) 3
- j) 2
- k) 4
- l) 2
- m) 3
- n) 3
Aufgabe 2
Zum testen müssen sem.c und sem.h selbst geschrieben werden.
- a)
/* author: Noya, Sven Pfaller */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <dirent.h> #include <sys/stat.h> #include <dirent.h> #include <pthread.h> /* "sem.h" pthread_mutex_t // for (int i void *xxx(void *) string.h & unlink */ /* Includes, Funktionsdeklarationen, globale Variablen */ #include <limits.h> #include "sem.h" #include <string.h> #define NBUFFER 9 #define PORT 7654 #define URL "localhost" int main(int argc, char **argv); static void process_jobs(); static void job(FILE *file); static void *process_queue(void *data); static void thread_error(char *msg); static void error(char *msg); static void num_error(char *msg, int num); static FILE *buffer[NBUFFER]; static int bread; static int bwrite; static int sock; static SEM *semfree; static SEM *semfill; static pthread_mutex_t block; /* Funktion main */ int main(int argc, char **argv) { /* lokale Variablen und was man sonst am Anfang so vorbereitet */ pthread_t thread; struct sockaddr_in addr; struct hostent *host; int e; int i; bread = 0; bwrite = 0; /* Semaphore erzeugen und initialisieren */ semfree = sem_init(NBUFFER); semfill = sem_init(0); /* queue-Threads erzeugen */ for (i = 1; i < argc; i++) { if ((e = pthread_create(&thread, NULL, process_queue, (void *) argv[i])) != 0) { num_error("pthread_create", e); } } /* Verbindung zu Printserver aufbauen */ host = gethostbyname(URL); if (host == NULL) error("gethostbyname"); sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) error("socket"); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length); if (connect(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1) error("connect"); /* Auftraege bearbeiten, Ende main */ process_jobs(); /* Ende von main - wird nie erreicht */ return 0; } /* Funktionen process_jobs */ static void process_jobs() { FILE *cfile; FILE *file; char fname[PATH_MAX + 2]; while (1) { P(semfill); cfile = buffer[bread]; bread = (bread + 1) % NBUFFER; V(semfree); if (fgets(fname, PATH_MAX + 2, cfile) == NULL) error("fgets"); fname[strlen(fname) - 1] = '\0'; printf(".global: processing document (%s)...\n", fname); file = fopen(fname, "r"); if (file == NULL) error("fopen"); job(file); printf(".global: processing document (%s) done\n", fname); fclose(cfile); fclose(file); /* if unlinking failes, ignore it */ unlink(fname); } } /* Funktion job */ static void job(FILE *file) { struct stat info; int fd; FILE *sockfp; char buf[1024]; fd = fileno(file); sockfp = fdopen(sock, "w"); if (sockfp == NULL) error("fdopen"); if (fstat(fd, &info) == -1) error("fstat"); if (fprintf(sockfp, "print job length=%i\n", info.st_size) < 0) error("fprintf"); while (fgets(buf, 1024, file) != NULL) { if (fputs(buf, sockfp) == EOF) error("fputs"); } if (feof(file) == 0) error("fgets"); fflush(sockfp); } /* Funktion process_queue */ static void *process_queue(void *data) { char *dirname; DIR *dir; struct dirent *entry; FILE *cfile; char path[PATH_MAX + 1]; dirname = (char *) data; while (1) { dir = opendir(dirname); if (dir == NULL) thread_error("opening directory failed"); errno = 0; while ((entry = readdir(dir)) != NULL) { if (entry->d_name[0] == 'c') { snprintf(path, PATH_MAX + 1, "%s/%s", dirname, entry->d_name); cfile = fopen(path, "r"); if (cfile != NULL) { P(semfree); pthread_mutex_lock(&block); buffer[bwrite] = cfile; bwrite = (bwrite + 1) % NBUFFER; pthread_mutex_unlock(&block); V(semfill); printf("%s: found document control file (%s), added to global queue\n", dirname, entry->d_name); /* if unlinking failes, ignore it */ unlink(path); } } errno = 0; } if (errno != 0) thread_error("reading from directory failed"); closedir(dir); } } static void thread_error(char *msg) { perror(msg); pthread_exit(NULL); } static void error(char *msg) { perror(msg); exit(1); } static void num_error(char *msg, int num) { printf("%s: %s\n", msg, strerror(num)); exit(1); }
- b)
# author: Noya, Sven Pfaller (kalterregen@gmx.net) CFLAGS=-ansi -pedantic -D_POSIX_SOURCE -g .PHONY: clean lpqmanager: sem.o lpqmanager.o gcc ${CFLAGS} -o lpqmanager lpqmanager.o sem.o -lpthread sem.o: sem.c sem.h gcc ${CFLAGS} -c -o sem.o sem.c lpqmanager.o: lpqmanager.c gcc ${CFLAGS} -c -o lpqmanager.o lpqmanager.c clean: rm -f *.o rm -f lpqmanager
Aufgabe 3
Aufgabe 4
- a)
- b)
- c)
- d)