Du befindest dich hier: FSI Informatik » jahrgaenge » 2006 » "Muster"-Lösungen » "Muster"-Lösungen zu Klausuren aus Softwaresysteme 1 » Vordiplomsklausuren » März 2006

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2006 [05.09.2007 11:55] 131.188.30.106jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2006 [08.09.2007 16:34] (aktuell) 88.65.116.180
Zeile 19: Zeile 19:
  
 ==== Aufgabe 2 ==== ==== Aufgabe 2 ====
 +
 +Zum testen müssen sem.c und sem.h selbst geschrieben werden.
  
   * a)   * a)
  
 <code c> <code c>
 +/* 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);
 +}
 +
 </code> </code>
  
   * b)   * b)
 +
 +<code>
 +# 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
 +</code>
  
 ==== Aufgabe 3 ==== ==== Aufgabe 3 ====