===== 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 #include #include #include #include #include #include #include #include #include /* 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 \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)