Du befindest dich hier: FSI Informatik » jahrgaenge » 2006 » "Muster"-Lösungen » "Muster"-Lösungen zu Klausuren aus Softwaresysteme 1 » Vordiplomsklausuren » März 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:mar2005 [05.09.2007 09:53] 131.188.30.85jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2005 [08.09.2007 19:17] (aktuell) 89.58.27.191
Zeile 71: Zeile 71:
  port = atoi(argv[1]);  port = atoi(argv[1]);
  
- /* Ein Signal-Handler für SIGCHLD (ein Kindprozess stirbt) wird installiert. So können Zombies mit waitpid abgeholt werden. /*+ /* Ein Signal-Handler für SIGCHLD (ein Kindprozess stirbt) wird installiert. So können Zombies mit waitpid abgeholt werden. */
  action.sa_handler = sighandler;  action.sa_handler = sighandler;
  sigemtpyset(&action.sa_mask);  sigemtpyset(&action.sa_mask);
Zeile 186: Zeile 186:
 } }
  
 +</code>
 +
 +Alternative Lösung: Diese schreibt die angeforderte Information auch wieder auf den socket zurück
 +
 +<code c>
 +#include <sys/types.h>
 +#include <sys/socket.h>
 +#include <netinet/in.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <dirent.h>
 +#include <stdio.h>
 +#include <errno.h>
 +#include <signal.h>
 +#include <unistd.h>
 +#include <sys/wait.h>
 +
 +/* fehlende includes */
 +#include <sys/stat.h>
 +#include <string.h>
 +
 +#define DEFAULT_PORT 31337
 +
 +static void serve(int socket);
 +static void prattr(char *filename);
 +static void sigchld_handler_install(void);
 +static void sigchld_handler(int sig);
 +
 +int main(int argc, char *argv[]) {
 +    int sock;
 +    unsigned short port;
 +    struct sockaddr_in saddr;
 +
 +    if (argc > 1) {
 +        port = atoi(argv[1]);
 +    } else {
 +        port = DEFAULT_PORT;
 +    }
 +
 +    sigchld_handler_install();
 +
 +    sock = socket(PF_INET, SOCK_STREAM, 0);
 +    if (sock < 0) {
 +        perror("socket");
 +        return EXIT_FAILURE;
 +    }
 +    
 +    saddr.sin_family = AF_INET;
 +    saddr.sin_addr.s_addr = htonl(INADDR_ANY); 
 +    saddr.sin_port = htons(port);
 +
 +    if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) {
 +        perror("bind");
 +        return EXIT_FAILURE;
 +    }
 +
 +    if (listen(sock, 5) == -1) {
 +        perror("listen");
 +        return EXIT_FAILURE;
 +    }
 +    
 +    printf("Listening on port %d\n", port);
 +    
 +    while (1) {
 +        pid_t pid;
 +        int clsock;
 +        struct sockaddr clsaddr;
 +        socklen_t clsaddr_len = sizeof(clsaddr);
 +
 +        clsock = accept(sock, &clsaddr, &clsaddr_len);
 +        if (clsock == -1) {
 +            perror("accept");
 +            continue;
 +        }
 +
 +        switch(pid = fork()) {
 +            case -1:
 +                /* error */
 +                perror("fork");
 +                return EXIT_FAILURE;
 +
 +                break;
 +            case 0:
 +                /* child */
 +                close(sock);
 +
 +                serve(clsock);
 +
 +                close(clsock);
 +                exit(EXIT_SUCCESS);
 +
 +                break;
 +            case 1:
 +                /* parent */
 +                close(clsock);
 +
 +                break;
 +        }
 +    }
 +
 +    return EXIT_SUCCESS;
 +}
 +
 +static void serve(int socket) {
 +    char file[128+2];
 +    FILE *fd = fdopen(socket, "r+");
 +
 +    if (dup2(socket, fileno(stdout)) == -1) {
 +        perror("dup2");
 +        exit(EXIT_FAILURE);
 +    }
 +
 +    while(fgets(file, 128+2, fd) != NULL) {
 +        file[strlen(file)-1] = '\0';
 +
 +        prattr(file);
 +    }
 +}
 +
 +static void prattr(char *filename) {
 +    struct stat statbuf;
 +
 +    if (stat(filename, &statbuf) == -1) {
 +        printf("%s %s\n", filename, strerror(errno));
 +    } else {
 +        if (S_ISDIR(statbuf.st_mode)) {
 +            printf("%s D\n", filename);
 +        } else if (S_ISREG(statbuf.st_mode)) {
 +            printf("%s F %ld\n", filename, (unsigned long) statbuf.st_size);
 +        } else {
 +            printf("%s X\n", filename);
 +        }
 +    }
 +    fclose(fd);
 +}
 +
 +static void sigchld_handler_install(void) {
 +    struct sigaction sa;
 +    
 +    sigemptyset(&sa.sa_mask);
 +    sa.sa_handler = sigchld_handler;
 +    sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
 +    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
 +        perror("sigaction");
 +        exit(EXIT_FAILURE);
 +    }
 +}
 +
 +static void sigchld_handler(int sig) {
 +    int errsvr;
 +    int status;
 +    pid_t pid;
 +
 +    errsvr = errno;
 +
 +    while((pid = waitpid(-1, &status, WNOHANG)) != 0) {
 +        if (pid == -1) {
 +            if (errno == ECHILD) {
 +                break;
 +            }
 +            perror("waitpid");
 +            break;
 +        }
 +    }
 +
 +    errno = errsvr;
 +}
 </code> </code>
  
Zeile 191: Zeile 358:
  
 <code> <code>
-fileattrd: fileattrd.+fileattrd: fileattrd.o
- gcc -fileattrd fileattrd.c+
  
-.PHONY clean+.PHONYclean
 clean: clean:
- rm -rf fileattrd+ $(RM) fileattrd fileattrd.o 
 + 
 +#restliche regeln sind alle implizit vorhanden
  
 </code> </code>