[Cheatsheet] CODE-SAMMLUNG
b FINALER STAND!![/b]
Hallo Leute,
ich habe mir heute ein paar Minuten genommen, um die wichtigsten Code-Schnipsel für das Cheatsheet in Form zubringen.
Bitte kommentiert bei Fehlern oder falls ich wichtige Code-Segmente übersehen habe!
LESEN DER ZEILEN VOM CLIENT (Stand: 19. Feb, 11:43 AM)
char buffer[MAX_LINE_LEN+1];
if(fgets(buffer, sizeof(buffer), rx) == NULL) return -1;
char *nach;
char *vor;
if((vor = strtok(buffer, "delimiter")) == NULL) return -1;
if((nach = strok(NULL, "\n")) == NULL) return -1;
if(strcmp(vor, "something")) {
//... do something
}
return -1;
THREADS (Stand: 19. Feb, 11:15 AM)
phtread_t tid;
for(int i = 0; i < MAX_CLIENTS; i++) {
if(pthread_create(&tid, NULL, &somefunction, NULL) != 0) die("pthread_create");
//Auf Thread warten, Ressourcen freigeben und Rückgabewert abfragen: join
if(pthread_join(&tid, NULL) != 0) die("pthread_join");
//Ressourcen automatisch bei Beendigung freigeben
if(pthread_detach(&tid) != 0) die("pthread_detach");
}
DURCHSUCHUNG VON VERZEICHNIS (READDIR) (Stand: 19. Feb, 11:10 AM)
DIR *dir = opendir(path);
if(!dir) {
perror("opendir");
exit(EXIT_FAILURE);
}
struct dirent *dir_entry;
struct stat buf;
while(errno = 0, (dir_entry = readdir(dir)) != NULL) {
if((lstat(dir_entry->d_name, &buf) == -1) || !IS_ISREG(buf.st_mode)) {
continue;
}
//... do something
if(errno != 0) perror("errno");
if(closedir(dir) == -1) perror("closedir");
}
STARTEN VON PROZESSEN (Stand: 19. Feb, 10:44 AM)
for(int i = 0; i < MAX_PROCESS_COUNT; i++){
pid_t pid = fork();
if (pid == (pid_t) 0) { //child
//... do something
} else if (p != (pid_t) -1) { //parents
//... do something
} else {
perror("fork");
}
}
SIGNALBEHANDLUNG (Stand: 19. Feb, 10:15 AM)
static sigset_t block;
sigemptyset(&block);
struct sigaction action = {
.sa_handler = sighandler | SIG_IGN | SIG_DFL,
/* sighandler = selbst geschriebene Signalbehandlung
SIGN_IGN: Signal ignorieren
SIG_DFL: Standard-Signalbehandlung einstellen */
.sa_mask = block,
.sa_flags = SA_RESTART | SA_NOCLDSTOP
/* SA_NOCLDSTOP: SIGCHLD wird nur zugestellt, wenn ein Kindprozess terminiert, nicht wenn er gestoppt wird
SA_RESTART: durch das Signal unterbrochene Systemaufrufe werden automatisch neu aufgesetzt */
};
if (sigaction(SIGCHLD, &action, NULL) == -1) die("action");
sigaddset(&block,SIGCHLD);
BLOCKIERUNG VON SIGNAL (Stand: 19. Feb, 10:15 AM)
sigset_t old, new;
sigemptyset(&new);
sigemptyset(&old);
sigaddset(&new, SIGCHLD);
sigprocmask(SIG_BLOCK, &new, NULL);
//... do something
sigprocmask(SIG_SETMASK, &old, NULL);
WARTEN AUF SIGNAL (Stand: 19. Feb, 10:18 AM)
sigset_t new, old;
sigemptyset(&new);
sigemptyset(&old);
sigaddset(&new, SIGCHLD);
sigprocmask(SIG_BLOCK, &new, NULL);
//(optional: do something)
while (!condition) {
sigsuspend(&old);
}
//(optional: do something)
sigprocmask(SIG_SETMASK, &old, NULL);
SIGNAL-HANDLER (Stand: 19. Feb, 10:18 AM)
int old_errno = errno;
while (waitpid(-1, NULL, WNOHANG) != -1) {
threadcounter--;
//(optional: do something)
}
errno = old_errno;
SERVER: SOCKET ERSTELLEN, VERBINDUNGSANNAHME VORBEREITEN UND VERBINDUNGSANNAHME (Stand: 19. Feb, 9:40 AM)
int listenSock = socket(AF_INET6, SOCK_STREAM, 0);
if(listenSock==-1) die("socket");
struct sockaddr_in6 name = {
.sin6_family = AF_INET6,
.sin6_port = htons(port),
.sin6_addr = in6addr_any,
};
int flag = 1
if (0 != setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) die("setsockopt");
if(-1 == bind(listenSock, (struct sockaddr *) &name, sizeof(name))) die("bind");
if(-1 == listen(listenSock, SOMAXCONN)) die("listen");
for (;;) {
int clientSock = accept(listenSock, NULL, NULL);
if (-1 == client_sock) {
perror("accept");
continue;
}
//... do something
close(clientSock);
}
CLIENT: SOCKET ERSTELLEN UND DNS-ANFRAGE (Stand: 19. Feb, 9:45 AM)
char *host, *port;
struct addrinfo hints = {
.ai_socktype = SOCK_STREAM,
.ai_family = AF_UNSPEC,
.ai_flags = AI_ADDRCONFIG,
};
struct addrinfo *head;
int err = getaddrinfo("xkcd.com", "80", &hints, &head);
if (err != 0) {
if (err = EAI_System) {
fperror("getaddrinfo");
}
else {
fprintf(stderr, getaddrinfo: "%s", gai_strerror(err))
}
}
int sock;
for (curr = head; curr != NULL; curr = curr->ai_next) {
sock = socket(curr->ai_family, curr->ai_socktype, curr->ai_protocol);
if (sock == -1) continue;
if (connect(sock, curr->ai addr, curr->ai addrlen) == 0) break;
close(sock);
}
if (curr == NULL) {
exit(EXIT_FAILURE);
}
FILE* ZUM LESEN UND SCHREIBEN (thread_handler()) (Stand: 19. Feb, 9:52 AM)
for(;;) {
int sock = bbGet();
FILE *rx = fdopen(sock, "r");
if (!rx) {
close(sock);
continue;
}
int sock2 = dup(sock);
if (sock2 < 0) {
close(sock);
continue;
}
FILE *tx = fdopen(sock2, "w");
if(!tx) {
fclose(rx);
close(sock2);
continue;
}
doWork(rx, tx);
fclose(rx);
fclose(tx);
/* ggf. Erstellung eines zwei-dimensionalen Arrays
FILE **farray = calloc(2, sizeof(FILE *));
if (farray) {
farray[0] = rx;
farray[1] = tx;
} */
}
SEMAPHOR (Stand: 19. Feb, 9:20 AM)
(Lösung für Übungsaufgabe entfernt --iridium)
JBUFFER (Stand: 19. Feb, 9:30 AM)
(Lösung für Übungsaufgabe entfernt --iridium)