Sie befinden sich hier: Termine » Prüfungsfragen und Altklausuren » Prüfungen im Bachelor-Studium (1. - 5. Semester) » Lösungsvorschlag

# Lösungsvorschlag

### Aufgabe 2:

a)

```/* Klausur Februar 2014 - Aufgabe 2: mops */

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>

// weitere Includes, Konstanten
// globale Variablen, Funktionsdeklarationen usw.

#define BUFFER_SIZE 64

void *feedPrinter(const char*);
SEM *semCreate(int);
void P(SEM *);
void V(SEM *);

struct SEM {
volatile int val;
};

static int port;
static int buffer[BUFFER_SIZE];
static int in, out;
static SEM *inSem, *outSem;

static void die(const char message[]) {
perror(message);
exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
unsigned int printer;
int sock;

if (argv != 2) {
fprintf(stderr, "usage: ./mops port\n");
return 0;
}

if ((inSem = semCreate(BUFFER_SIZE)) == NULL)
die("semCreate");

if ((outSem = semCreate(0)) == NULL)
die("semCreate");

port = (int) strtol(argv[1]);

if (printer < 0)

printf("%d printer devices found", printer);
if (printer == 0)
return 0;

sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock < 0)
die("socket");

.sin6_family = AF_INET6,
.sin6_port = htons(port),
};

die("bind");
if (listen(sock, SOMAXCONN) != 0)
die("bind");

for (;;) {
int clientSock = accept(sock, NULL, NULL);
if (clientSock < 0)
continue;
P(inSem);
buffer[in] = clientSock;
in = (in + 1) % BUFFER_SIZE
V(outSem);
}
close(sock);
return 0;
}

unsigned int numb;
DIR *dir = opendir("/dev");
if (dir == NULL)
return numb;
struct dirent *ent;
while (errno = 0, (ent = readdir(dir)) != NULL) {
if (ent->d_name[0] == 'l' && ent->d_name[1] == 'p') {
char path[6 + strlen(ent->d_name)];
snprintf(path, "/dev/%s", ent->d_name);
struct stat s;
if (lstat(path, &s) < 0)
return 0;
if (S_ISREG(s.st_mode)) {
if (pthread_create(NULL, NULL, feedPrinter, &ent->d_name) < 0)
return 0;
numb++;
}
}
}
if (errno != 0)
return 0;
return numb;
}

void *feedPrinter(const char device[]) {
FILE *dev = fopen(device, "a");
if (dev == NULL) {
return;
}
for (;;) {
int sock;
P(outSem);
do {
sock = buffer[out];
out = (out + 1) % BUFFER_SIZE;
} while (__sync_compare_and_swap(buffer[out], sock, -1) == false);
V(inSem);
FILE *req;
if ((req = fdopen(sock, "r")) == NULL)
continue;
int c;
while ((c = fgetc(req)) != EOF)
fputc(c, dev);
close(sock);
}
}

SEM *semCreate(int initial_value) {
struct SEM sem = {
.val = initial_value
}
errno = 0;
if ((errno = pthread_mutex_init(sem.m, NULL)) != 0)
return NULL;
if ((errno = pthread_cond_init(sem.c, NULL)) != 0)
return NULL;
return &sem;
}

void P(SEM *sem) {
if ((errno = pthread_mutex_lock(&sem->m)) != 0)
return;
while (sem->val <= 0) {
if ((errno = pthread_cond_wait(&sem->c)) != 0) {
return;
}
}
sem->val--
if ((errno = pthread_mutex_unlock(&sem->m)) != 0)
return;
}

void V(SEM *sem) {
if ((errno = pthread_mutex_lock(&sem->m)) != 0)
return;
sem->val++