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

September 2006

Aufgabe 1

  • a) 2
  • b) 3
  • c) 4
  • d) 3
  • e) 2
  • f) 3
  • g) 2
  • h) 4
  • i) 3
  • j) 3
  • k) 4
  • l) 2
  • m) 2
  • n) 1

Aufgabe 2

  • a)
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
 
/* weiter Includes, Makros, Funktionsdeklarationen, globale Variablen */
#define die(msg) {perror(msg); exit(EXIT_FAILURE);}
 
static char *cmd[110];
static int error = 0;
static int n_proc = 0;
static int max_proc;
 
int needcompile(char *cfile, char *ofile);
void pjob(char *cfile);
static void sigchld_handler(int sig);
 
/* Funktion main */
int main(int argc, char **argv, char **envp) {
    /* lokale variablen usw. */
    struct sigaction sa;
    DIR *dir;
    struct dirent *dirent;
    int i = 3;
    int status;
 
    /* Aufrufargumente auswerten */
    if(argc != 3) {
        fprintf(stderr, "pmake <Zieldatei> <Anzahl paralleler jobs>\n");
        exit(EXIT_FAILURE);
    }
 
    cmd[0] = "cc";
    cmd[1] = "-o";
    cmd[2] = argv[1];
 
    max_proc = atoi(argv[2]);
 
 
    if(sigisemptyset(&sa.sa_mask) < 0) die("sigemptyset");
    sa.sa_flags = 0;
    sa.sa_handler = sigchld_handler;
    if(sigaction(SIGCHLD, &sa, NULL) < 0) die("sigaction");
 
 
    if((dir = opendir(".")) == NULL) die("opendir");
 
    while(1) {
        int len;
        char object[NAME_MAX+1];
        errno = 0;
 
        if(error) break;
 
        if((dirent = readdir(dir)) == NULL) {
            if(errno == 0) break;
            else {
                perror("readdir");
                continue;
            }
        }
 
        len = strlen(dirent->d_name);
        if(!((dirent->d_name[len-1] == 'c') && (dirent->d_name[len-2] == '.'))) 
            continue;
 
        if((cmd[i] = malloc((NAME_MAX+1) * sizeof(char))) == NULL) die("malloc");
 
        strcpy(cmd[i], dirent->d_name);
        strcpy(object, dirent->d_name);
        object[dirent->d_reclen-1] = 'o';
        if(needcompile(cmd[i], object)) {
            pjob(cmd[i]);
        }
        i++;
    }
 
    /* warten bis alles fertig is ... */
    while(waitpid(-1, &status, WNOHANG) > 0);
 
    cmd[i] = NULL;
 
    execv("/usr/bin/cc", cmd);
    return EXIT_FAILURE;
}
 
void pjob(char *cfile) {
    char *comp[6];
    int pid;
    sigset_t set;
    sigset_t tmp;
 
 
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigprocmask(SIG_BLOCK, &set, &tmp);
 
    /* Zu viele Prozesse? */
    while(n_proc >= max_proc) sigsuspend(&tmp);
 
    switch ((pid = fork())) {
        case -1:
            die("fork");
        case 0:
            comp[0] = "cc";
            comp[1] = "-c";
            comp[2] = cfile;
            comp[3] = "-o";
            if((comp[4] = malloc((NAME_MAX+1) * sizeof(char))) == NULL) die("malloc");
            strcpy(comp[4], cfile);
            comp[4][strlen(cfile)-1] = 'o';
            comp[5] = NULL;
 
            execv("/usr/bin/cc", comp);
            exit(EXIT_FAILURE);
    }
    n_proc++;
    sigprocmask(SIG_UNBLOCK, &set, &tmp);
}
 
int needcompile(char *cfile, char *ofile) {
    struct stat c;
    struct stat o;
 
    if(lstat(cfile, &c) < 0) die("lstat");
    if(lstat(ofile, &o) < 0) {
        if(errno == ENOENT) return 1;
        perror("lstat");
        return 0;
    }
 
    if((int)c.st_mtime > (int)o.st_mtime) return 1;
    return 0;
}
 
static void sigchld_handler(int sig) {
    int status;
    int errno_save = errno;
 
    while(waitpid(-1, &status, WNOHANG) > 0) {
        n_proc--;
        if(status != 0) error = 1;
    }
    errno = errno_save;
}
  • b)
# author: Noya, Sven Pfaller

.PHONY: clean

CFLAGS=-ansi -pedantic -Wall -Werror -D_POSIX_SOURCE -D_XOPEN_SOURCE=500

pmake: pmake.c
	gcc ${CFLAGS} -o pmake pmake.c

clean:
	rm -f pmake.o pmake

Aufgabe 3

Aufgabe 4

  • a)
  • b)
  • c)