===== 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)