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

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
Letzte ÜberarbeitungBeide Seiten, nächste Überarbeitung
jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:sep2006 [03.09.2007 14:49] Airhardtjahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:sep2006 [09.09.2007 12:45] 88.65.122.61
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
 +
 +</code>
 ==== Aufgabe 3 ==== ==== Aufgabe 3 ====