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

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)