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

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
jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:sep2005 [05.09.2007 10:12] 131.188.30.85jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:sep2005 [07.09.2007 00:37] (aktuell) Raim
Zeile 15: Zeile 15:
   * k) 3   * k) 3
   * l) 3   * l) 3
-  * m) 3 (Natürlich ist das möglich, man muß eben ggf. umorganisieren; also ist 3 falsch und damit die richtige Antwort.)+  * m) 3 (Natürlich ist das möglich, man muß eben ggf. umorganisieren; also ist die 3 unwahr -> richtig.)
   * n) 2   * n) 2
  
Zeile 22: Zeile 22:
   * a)   * a)
  
 +sem.c:
 <code c> <code c>
 +#include <stdlib.h>
 +#include <stdio.h>
 +#include "sem.h"
 +
 +SEM *sem_init(int n) {
 +    SEM *s;
 +    s = (SEM *) malloc(sizeof(SEM));
 +    if (s == NULL) {
 +        perror("malloc");
 +        exit(EXIT_FAILURE);
 +    }
 +    pthread_mutex_init(&s->m, NULL);
 +    pthread_cond_init(&s->c, NULL);
 +    s->s = n;
 +
 +    return s;
 +}
 +
 +void P(SEM *s) {
 +    pthread_mutex_lock(&s->m);
 +    while (s->s < 1) {
 +        pthread_cond_wait(&s->c, &s->m);
 +    }
 +    s->s--;
 +    pthread_mutex_unlock(&s->m);
 +}
 +
 +void V(SEM *s) {
 +    pthread_mutex_lock(&s->m);
 +    s->s++;
 +    pthread_cond_broadcast(&s->c);
 +    pthread_mutex_unlock(&s->m);
 +}
 +</code>
 +
 +fdserver.c:
 +<code c>
 +#include <errno.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <sys/types.h>
 +#include <sys/socket.h>
 +#include <arpa/inet.h>
 +#include <netinet/in.h>
 +#include <dirent.h>
 +#include <sys/stat.h>
 +#include <pthread.h>
 +#include <string.h>
 +
 +#include "sem.h"
 +
 +#define NTHREAD 25
 +
 +void *serve(void *arg);
 +void handle(FILE *socket, char path[]);
 +void fhandle(FILE *socket, char path[]);
 +void dhandle(FILE *socket, char path[]);
 +
 +struct bufinfo {
 +    SEM *sem_full;
 +    SEM *sem_free;
 +    pthread_mutex_t lock;
 +
 +    int socks[NTHREAD];
 +    int writep;
 +    int readp;
 +};
 +
 +int main(int argc, char *argv[]) {
 +    struct bufinfo b;
 +    pthread_t tid[NTHREAD];
 +    int i;
 +    int sock;
 +    struct sockaddr_in saddr;
 +    
 +    b.writep = 0;
 +    b.readp = 0;
 +    b.sem_full = sem_init(0);
 +    b.sem_free = sem_init(NTHREAD);
 +    pthread_mutex_init(&b.lock, NULL);
 +
 +    for (i = 0; i < NTHREAD; i++) {
 +        pthread_create(&tid[i], NULL, serve, &b);
 +    }
 +
 +    sock = socket(PF_INET, SOCK_STREAM, 0);
 +    if (sock == -1) {
 +        perror("socket");
 +        return EXIT_FAILURE;
 +    }
 +    
 +    saddr.sin_family = AF_INET;
 +    saddr.sin_port = argc > 1 ? htons(atoi(argv[1])) : htons(31337);
 +    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
 +
 +    if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) {
 +        perror("bind");
 +        return EXIT_FAILURE;
 +    }
 +    if (listen(sock, 20) == -1) {
 +        perror("listen");
 +        return EXIT_FAILURE;
 +    }
 +
 +    while (1) {
 +        int clsock;
 +        struct sockaddr clsaddr;
 +        socklen_t clsaddr_len = sizeof(clsaddr);
 +
 +        clsock = accept(sock, &clsaddr, &clsaddr_len);
 +        if (clsock == -1) {
 +            perror("accept");
 +            continue;
 +        }
 +        
 +        P(b.sem_free);
 +        b.socks[b.writep] = clsock;
 +        b.writep = (b.writep + 1) % NTHREAD;
 +        V(b.sem_full);
 +
 +    }
 +
 +    return 0;
 +}
 +
 +void *serve(void *arg) {
 +    struct bufinfo *b = (struct bufinfo *) arg;
 +    int s;
 +    FILE *fd;
 +    char buffer[1024+2];
 +    
 +    P(b->sem_full);
 +    pthread_mutex_lock(&b->lock); 
 +    s = b->socks[b->readp];
 +    b->readp = (b->readp + 1) % NTHREAD;
 +    pthread_mutex_unlock(&b->lock);
 +    V(b->sem_free);
 +
 +    fd = fdopen(s, "r+");
 +
 +    while (fgets(buffer, 1024+2, fd) != NULL) {
 +        buffer[strlen(buffer)-1] = '\0';
 +        handle(fd, buffer);
 +    }
 +
 +    return NULL;
 +}
 +
 +void handle(FILE *socket, char path[]) {
 +    struct stat statinfo;
 +
 +    if (stat(path, &statinfo) == -1) {
 +        fprintf(socket, "%s\n", strerror(errno));
 +        return;
 +    }
 +
 +    if (S_ISDIR(statinfo.st_mode)) {
 +        dhandle(socket, path);
 +    } else if (S_ISREG(statinfo.st_mode)) {
 +        fhandle(socket, path);
 +    } else {
 +        fprintf(socket, "Error: Something special, but not a file or directory\n");
 +        return;
 +    }
 +}
 +
 +void fhandle(FILE *socket, char path[]) {
 +    char buf[1024+2];
 +    FILE *fd;
 +
 +    fd = fopen(path, "r");
 +    if (fd == NULL) {
 +        fprintf(socket, "%s\n", strerror(errno));
 +        return;
 +    }
 +
 +    while (fgets(buf, 1024+2, fd) != NULL) {
 +        if (fputs(buf, socket) == EOF) {
 +            perror("errno");
 +            return;
 +        }
 +    } 
 +}
 +
 +void dhandle(FILE *socket, char path[]) {
 +    DIR *dir;
 +    struct dirent entry;
 +    struct dirent *result;
 +    int err;
 +
 +    dir = opendir(path);
 +    if (dir == NULL) {
 +       fprintf(socket, "Error: %s\n", strerror(errno));
 +    }
 +
 +    while(((err = readdir_r(dir, &entry, &result)) == 0) && result != NULL) {
 +        fprintf(socket, "%s\n", entry.d_name);
 +    }
 +}
 </code> </code>