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

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Nächste Überarbeitung
Vorherige Überarbeitung
jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:sep2006 [03.09.2007 13:15] – angelegt Der Ichjahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:sep2006 [10.12.2008 06:33] (aktuell) 83.171.166.47
Zeile 5: Zeile 5:
   * a) 2   * a) 2
   * b) 3   * b) 3
-  * c) 3 (?) +  * c) 4 
-  * d) 2 +  * d) 3 
-  * e) 2 (?) +  * e) 2 
-  * f) 3 (?) +  * f) 3 
-  * g) **?** +  * g) 2 
-  * h) 1+  * h) 4
   * i) 3   * i) 3
   * j) 3   * j) 3
-  * k) 4 (?)+  * k) 4
   * l) 2   * l) 2
   * m) 2   * m) 2
-  * n) **?**+  * n) 1
  
 ==== Aufgabe 2 ==== ==== Aufgabe 2 ====
Zeile 23: Zeile 23:
  
 <code c> <code c>
 +#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;
 +}
 </code> </code>
  
   * b)   * b)
  
 +<code>
 +# 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
 +
 +</code>
 ==== Aufgabe 3 ==== ==== Aufgabe 3 ====