diff --git a/Readme.md b/Readme.md index dac0c428b61f6893681ca5a2bb6bbf1bb8102565..6c6a9b2ead73db419508563c921f168f954d2112 100644 --- a/Readme.md +++ b/Readme.md @@ -1,18 +1,5 @@ # Code -## reading / handling strings -printf formats - -fgets -> sscanf - -strncmp - -## parallel processing -fork exec - -### pthread - - ## networking ### client getaddrinfo @@ -107,6 +94,203 @@ int main() { ``` <!-- /include --> +## parallel processing +### fork exec + -> siehe server + +#### signal + +<!-- include (signal.c lang=c) --> +```c +# include "die.h" +# include <signal.h> +# include <sys/types.h> +# include <sys/wait.h> +# include <unistd.h> + +static void sigchldHandler(int sig); +int i; + +int main() { + struct sigaction handleSIGCHLD = + { + .sa_handler = sigchldHandler, + .sa_flags = SA_RESTART, + }; + if( sigaction(SIGCHLD, &handleSIGCHLD, NULL) != 0 ) die("Could not set sigaction"); + + //mask sigchld + sigset_t newMask_Itr; + sigset_t oldMask_Itr; + sigemptyset(&newMask_Itr); + sigaddset(&newMask_Itr, SIGCHLD); + if (sigprocmask(SIG_BLOCK, &newMask_Itr, &oldMask_Itr) == -1) die("sigprocmask"); + + //do critical stuff + + //alte signal mask wiederherstellen + if (sigprocmask(SIG_SETMASK, &oldMask_Itr, NULL) == -1) die("sigprocmask"); + + pid_t pid = fork(); + if(pid < 0) die("fork"); + if(pid == 0) { + sleep(5); + exit(EXIT_SUCCESS); + } + + //passives warten + i = 1; + if (sigprocmask(SIG_BLOCK, &newMask_Itr, &oldMask_Itr) == -1) die("sigprocmask"); + while (i > 0) { + sigsuspend(&oldMask_Itr); + } +} + +static void sigchldHandler(int sig) { + // Collect zombie processes + (void)sig; //unused param + pid_t pid; + int event; + while ((pid = waitpid(-1, &event, WNOHANG)) > 0) { + // collect all zombies (prevent zombies if signal got lost because of masking) + i--; + } +} +``` +<!-- /include --> + +### pthread + +<!-- include (threadpool.c lang=c) --> +```c +# include "die.h" +# include "errno.h" +# include <pthread.h> +# include "jbuffer.h" + +# define POISON 123456 +# define BUFSIZE 32 +# define THREADS 8 + +static BNDBUF *jbuf; + +static void *workerMain(void *param){ + for(int val = bbGet(jbuf); val != POISON; val = bbGet(jbuf)) { + //handle val + printf("%d\n", val); + } + return param; +} + +int main() { + // init jbuf + jbuf = bbCreate(BUFSIZE); + if (jbuf == NULL) die_m("failed to create jbuffer"); + + // create threads + pthread_t tids[THREADS]; + for (int i = 0; i < THREADS; i++) { + //pthread_t thread; + if ( (errno = pthread_create(&tids[i], NULL, workerMain, NULL)) != 0 ) die("pthread_create"); + //if ( (errno = pthread_detach(thread)) != 0 ) die("pthread_detach"); + } + + //put work (z.B. clientSock) in the queue + bbPut(jbuf, 123); + + //kill them all + for (int i = 0; i < THREADS; i++) { + bbPut(jbuf, POISON); + } + for (int i = 0; i < THREADS; i++) { + errno = pthread_join(tids[i], NULL);//void **retval + if (errno != 0) perror("pthread_join()"); + } +} +``` +<!-- /include --> + + +## jbuffer + +<!-- include (jbuffer.c lang=c) --> +```c +# include <stdatomic.h> +# include "jbuffer.h" +# include "sem.h" + +struct BNDBUF +{ + int *buff; + int size; + int insertpos; // next insert pos + SEM *freeSpaceSem; // count of free slots + int extractpos; // next extract pos + SEM *usedSpaceSem; // count of used slots +}; + +BNDBUF *bbCreate(size_t size) { + if(size > __INT_MAX__) return NULL;//to big + + BNDBUF *bb = calloc(1, sizeof(BNDBUF));//initialize everithing with NULL + if(bb == NULL) return NULL;//malloc failed + + bb->buff = malloc(size * sizeof(int)); + if(bb->buff == NULL) {//malloc failed + bbDestroy(bb); + return NULL; + } + bb->size = (int) size; + + //init SEMs + bb->freeSpaceSem = semCreate((int) size); + if(bb->freeSpaceSem == NULL) {//semCreate failed + bbDestroy(bb); + return NULL; + } + + bb->usedSpaceSem = semCreate(0); + if(bb->usedSpaceSem == NULL) {//semCreate failed + bbDestroy(bb); + return NULL; + } + + bb->insertpos = 0; + bb->extractpos = 0; + return bb; +} + +void bbDestroy(BNDBUF *bb) { + if(bb == NULL) return; + free(bb->buff);//each does noting if NULL + semDestroy(bb->freeSpaceSem); + semDestroy(bb->usedSpaceSem); + free(bb); +} + +void bbPut(BNDBUF *bb, int value) { + P(bb->freeSpaceSem); + bb->buff[bb->insertpos] = value; + bb->insertpos++; + if(bb->insertpos >= bb->size) bb->insertpos = 0; + V(bb->usedSpaceSem); +} + +int bbGet(BNDBUF *bb) { + int value, extractpos, newExtractpos; + P(bb->usedSpaceSem); + do{ + extractpos = bb->extractpos; + value = bb->buff[extractpos]; + newExtractpos = extractpos + 1; + if(newExtractpos >= bb->size) newExtractpos = 0; + } while(! atomic_compare_exchange_strong(&(bb->extractpos), &extractpos, newExtractpos)); + V(bb->freeSpaceSem); + return value; +} +``` +<!-- /include --> + ## open File <!-- include (fopen.c lang=c) --> @@ -125,6 +309,188 @@ int main() { ``` <!-- /include --> +## listfiles + +<!-- include (listFiles.c lang=c) --> +```c +# include "die.h" +# include <dirent.h> +# include <stdio.h> +# include <stdlib.h> +# include <sys/stat.h> +# include <string.h> + +# define BASEDIR "." + +int filter(const struct dirent *dir) { + if(dir->d_name[0] == '.') { + return 0;//filter out .files + } + struct stat st; + char name[strlen(BASEDIR) + strlen(dir->d_name)]; + sprintf(name, "%s/%s", BASEDIR, dir->d_name); + if(stat(name, &st) == -1) die("stat");//lstat don't folow symlinks + if(S_ISREG(st.st_mode)) { + return 1; + } + return 0; +} + +/** list files + */ +static void listDir(){ + struct dirent **namelist; //array of dirents + int n = scandir(BASEDIR, &namelist, filter, alphasort);//filter oder NULL + if (n == -1) { + die("scandir"); + } + + while (n--) { + printf("%s/%s\n", BASEDIR, namelist[n]->d_name); + free(namelist[n]); + } + free(namelist); +} + +int main() { + listDir(); +} +``` +<!-- /include --> + + +## reading / handling strings +printf formats + +<!-- include (getline.c lang=c) --> +```c +# include "die.h" +# include <stdio.h> + +static void mygetline() { + char *lineptr = NULL; + size_t lineSize = 0; + ssize_t strLen = 0; + + strLen = getline(&lineptr, &lineSize, stdin); + if(strLen < 0) {//eof + if (ferror(stdin)) die("getline"); + } + free(lineptr); +} + +int main() { + mygetline(); +} +``` +<!-- /include --> + +fgets -> sscanf + +strncmp + +## optional + +### sem + +<!-- include (sem.c lang=c) --> +```c +# include <errno.h> +# include <pthread.h> +# include <stdlib.h> +# include "sem.h" + +struct SEM +{ + pthread_mutex_t m; + pthread_cond_t c; + int value; +}; + +SEM *semCreate(int initVal) { + SEM *sem = malloc(sizeof(SEM)); + if(sem == NULL) return NULL;// malloc failed + int err=0; + err = pthread_mutex_init(&sem->m, NULL); + if(err) { + free(sem); + errno = err; + return NULL; + } + err = pthread_cond_init(&sem->c, NULL); + if (err) { + pthread_mutex_destroy(&sem->m); + free(sem); + errno = err; + return NULL; + } + + sem->value = initVal; + return sem; +} + +void semDestroy(SEM *sem) { + if(sem == NULL) return; + + pthread_cond_destroy(&sem->c);//ignore returned errors + pthread_mutex_destroy(&sem->m);//ignore returned errors + free(sem); +} + +void P(SEM *sem) {//fast mutex has only EINVAL error + pthread_mutex_lock(&sem->m); + while(sem->value <= 0) { + pthread_cond_wait(&sem->c, &sem->m); + } + sem->value--; + + pthread_mutex_unlock(&sem->m); +} + +void V(SEM *sem) {//fast mutex has only EINVAL error + pthread_mutex_lock(&sem->m); + sem->value++; + pthread_cond_signal(&sem->c); + + pthread_mutex_unlock(&sem->m); +} +``` +<!-- /include --> + +### stroulSave + +<!-- include (strtoulSave.c lang=c) --> +```c +# include <errno.h> +# include <stdlib.h> +/** + * @brief strtoul with error checks + * + * @param str String to be parsed + * @param num return param where the unsigned long gets written to (gets only changed on success) + * @return 0 on success, none zero on error + */ +static int strtoulSave(const char *str, unsigned long *num) { + char *endptr; + int eno = errno; + errno = 0; + unsigned long value = strtoul(str, &endptr, 10); + if(errno) return errno; + errno = eno; // restore errno, so we're not unintentionally loosing errors when calling this function + + if (endptr == str) return EINVAL; // no digits found + if(*endptr != '\0') return EINVAL; // contains invalid character + + *num = value; + return 0; +} + +int main(){ + unsigned long num; + strtoulSave("123", &num); +} +``` +<!-- /include --> # RAID * RAID 0 : Daten werden ¨uber mehrere Platten gespeichert diff --git a/Zettel.html b/Zettel.html index c564ffdd547e1aeb03d1ff6503b416780d1d943f..81d2f5987d882e652523229d3f84a97fabfd3ba0 100644 --- a/Zettel.html +++ b/Zettel.html @@ -1,11 +1,4 @@ <link rel="stylesheet" href="node_modules/highlight.js/styles/default.css"><h1>Code</h1> -<h2>reading / handling strings</h2> -<p>printf formats</p> -<p>fgets -> sscanf</p> -<p>strncmp</p> -<h2>parallel processing</h2> -<p>fork exec</p> -<h3>pthread</h3> <h2>networking</h2> <h3>client</h3> <p>getaddrinfo @@ -96,6 +89,192 @@ accept</p> } </code></pre> <p><!-- /include --></p> +<h2>parallel processing</h2> +<h3>fork exec</h3> +<p>-> siehe server</p> +<h4>signal</h4> +<p><!-- include (signal.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"die.h"</span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><signal.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><sys/types.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><sys/wait.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><unistd.h></span></span> + +<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sigchldHandler</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sig)</span></span>; +<span class="hljs-keyword">int</span> i; + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">sigaction</span> <span class="hljs-title">handleSIGCHLD</span> = + {</span> + .sa_handler = sigchldHandler, + .sa_flags = SA_RESTART, + }; + <span class="hljs-keyword">if</span>( sigaction(SIGCHLD, &handleSIGCHLD, <span class="hljs-literal">NULL</span>) != <span class="hljs-number">0</span> ) die(<span class="hljs-string">"Could not set sigaction"</span>); + + <span class="hljs-comment">//mask sigchld</span> + <span class="hljs-keyword">sigset_t</span> newMask_Itr; + <span class="hljs-keyword">sigset_t</span> oldMask_Itr; + sigemptyset(&newMask_Itr); + sigaddset(&newMask_Itr, SIGCHLD); + <span class="hljs-keyword">if</span> (sigprocmask(SIG_BLOCK, &newMask_Itr, &oldMask_Itr) == <span class="hljs-number">-1</span>) die(<span class="hljs-string">"sigprocmask"</span>); + + <span class="hljs-comment">//do critical stuff</span> + + <span class="hljs-comment">//alte signal mask wiederherstellen</span> + <span class="hljs-keyword">if</span> (sigprocmask(SIG_SETMASK, &oldMask_Itr, <span class="hljs-literal">NULL</span>) == <span class="hljs-number">-1</span>) die(<span class="hljs-string">"sigprocmask"</span>); + + <span class="hljs-keyword">pid_t</span> pid = fork(); + <span class="hljs-keyword">if</span>(pid < <span class="hljs-number">0</span>) die(<span class="hljs-string">"fork"</span>); + <span class="hljs-keyword">if</span>(pid == <span class="hljs-number">0</span>) { + sleep(<span class="hljs-number">5</span>); + <span class="hljs-built_in">exit</span>(EXIT_SUCCESS); + } + + <span class="hljs-comment">//passives warten</span> + i = <span class="hljs-number">1</span>; + <span class="hljs-keyword">if</span> (sigprocmask(SIG_BLOCK, &newMask_Itr, &oldMask_Itr) == <span class="hljs-number">-1</span>) die(<span class="hljs-string">"sigprocmask"</span>); + <span class="hljs-keyword">while</span> (i > <span class="hljs-number">0</span>) { + sigsuspend(&oldMask_Itr); + } +} + +<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sigchldHandler</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sig)</span> </span>{ + <span class="hljs-comment">// Collect zombie processes</span> + (<span class="hljs-keyword">void</span>)sig; <span class="hljs-comment">//unused param</span> + <span class="hljs-keyword">pid_t</span> pid; + <span class="hljs-keyword">int</span> event; + <span class="hljs-keyword">while</span> ((pid = waitpid(<span class="hljs-number">-1</span>, &event, WNOHANG)) > <span class="hljs-number">0</span>) { + <span class="hljs-comment">// collect all zombies (prevent zombies if signal got lost because of masking)</span> + i--; + } +} +</code></pre> +<p><!-- /include --></p> +<h3>pthread</h3> +<p><!-- include (threadpool.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"die.h"</span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"errno.h"</span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><pthread.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"jbuffer.h"</span></span> + +<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> POISON 123456</span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> BUFSIZE 32</span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> THREADS 8</span> + +<span class="hljs-keyword">static</span> BNDBUF *jbuf; + +<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> *<span class="hljs-title">workerMain</span><span class="hljs-params">(<span class="hljs-keyword">void</span> *param)</span></span>{ + <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> val = bbGet(jbuf); val != POISON; val = bbGet(jbuf)) { + <span class="hljs-comment">//handle val</span> + <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, val); + } + <span class="hljs-keyword">return</span> param; +} + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-comment">// init jbuf</span> + jbuf = bbCreate(BUFSIZE); + <span class="hljs-keyword">if</span> (jbuf == <span class="hljs-literal">NULL</span>) die_m(<span class="hljs-string">"failed to create jbuffer"</span>); + + <span class="hljs-comment">// create threads</span> + <span class="hljs-keyword">pthread_t</span> tids[THREADS]; + <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < THREADS; i++) { + <span class="hljs-comment">//pthread_t thread;</span> + <span class="hljs-keyword">if</span> ( (errno = pthread_create(&tids[i], <span class="hljs-literal">NULL</span>, workerMain, <span class="hljs-literal">NULL</span>)) != <span class="hljs-number">0</span> ) die(<span class="hljs-string">"pthread_create"</span>); + <span class="hljs-comment">//if ( (errno = pthread_detach(thread)) != 0 ) die("pthread_detach");</span> + } + + <span class="hljs-comment">//put work (z.B. clientSock) in the queue</span> + bbPut(jbuf, <span class="hljs-number">123</span>); + + <span class="hljs-comment">//kill them all</span> + <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < THREADS; i++) { + bbPut(jbuf, POISON); + } + <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < THREADS; i++) { + errno = pthread_join(tids[i], <span class="hljs-literal">NULL</span>);<span class="hljs-comment">//void **retval</span> + <span class="hljs-keyword">if</span> (errno != <span class="hljs-number">0</span>) perror(<span class="hljs-string">"pthread_join()"</span>); + } +} +</code></pre> +<p><!-- /include --></p> +<h2>jbuffer</h2> +<p><!-- include (jbuffer.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><stdatomic.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"jbuffer.h"</span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"sem.h"</span></span> + +<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BNDBUF</span> +{</span> + <span class="hljs-keyword">int</span> *buff; + <span class="hljs-keyword">int</span> <span class="hljs-built_in">size</span>; + <span class="hljs-keyword">int</span> insertpos; <span class="hljs-comment">// next insert pos</span> + SEM *freeSpaceSem; <span class="hljs-comment">// count of free slots</span> + <span class="hljs-keyword">int</span> extractpos; <span class="hljs-comment">// next extract pos</span> + SEM *usedSpaceSem; <span class="hljs-comment">// count of used slots</span> +}; + +<span class="hljs-function">BNDBUF *<span class="hljs-title">bbCreate</span><span class="hljs-params">(<span class="hljs-keyword">size_t</span> <span class="hljs-built_in">size</span>)</span> </span>{ + <span class="hljs-keyword">if</span>(<span class="hljs-built_in">size</span> > __INT_MAX__) <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//to big</span> + + BNDBUF *bb = <span class="hljs-built_in">calloc</span>(<span class="hljs-number">1</span>, <span class="hljs-keyword">sizeof</span>(BNDBUF));<span class="hljs-comment">//initialize everithing with NULL</span> + <span class="hljs-keyword">if</span>(bb == <span class="hljs-literal">NULL</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//malloc failed</span> + + bb->buff = <span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">size</span> * <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>)); + <span class="hljs-keyword">if</span>(bb->buff == <span class="hljs-literal">NULL</span>) {<span class="hljs-comment">//malloc failed</span> + bbDestroy(bb); + <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>; + } + bb-><span class="hljs-built_in">size</span> = (<span class="hljs-keyword">int</span>) <span class="hljs-built_in">size</span>; + + <span class="hljs-comment">//init SEMs</span> + bb->freeSpaceSem = semCreate((<span class="hljs-keyword">int</span>) <span class="hljs-built_in">size</span>); + <span class="hljs-keyword">if</span>(bb->freeSpaceSem == <span class="hljs-literal">NULL</span>) {<span class="hljs-comment">//semCreate failed</span> + bbDestroy(bb); + <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>; + } + + bb->usedSpaceSem = semCreate(<span class="hljs-number">0</span>); + <span class="hljs-keyword">if</span>(bb->usedSpaceSem == <span class="hljs-literal">NULL</span>) {<span class="hljs-comment">//semCreate failed</span> + bbDestroy(bb); + <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>; + } + + bb->insertpos = <span class="hljs-number">0</span>; + bb->extractpos = <span class="hljs-number">0</span>; + <span class="hljs-keyword">return</span> bb; +} + +<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">bbDestroy</span><span class="hljs-params">(BNDBUF *bb)</span> </span>{ + <span class="hljs-keyword">if</span>(bb == <span class="hljs-literal">NULL</span>) <span class="hljs-keyword">return</span>; + <span class="hljs-built_in">free</span>(bb->buff);<span class="hljs-comment">//each does noting if NULL</span> + semDestroy(bb->freeSpaceSem); + semDestroy(bb->usedSpaceSem); + <span class="hljs-built_in">free</span>(bb); +} + +<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">bbPut</span><span class="hljs-params">(BNDBUF *bb, <span class="hljs-keyword">int</span> value)</span> </span>{ + P(bb->freeSpaceSem); + bb->buff[bb->insertpos] = value; + bb->insertpos++; + <span class="hljs-keyword">if</span>(bb->insertpos >= bb-><span class="hljs-built_in">size</span>) bb->insertpos = <span class="hljs-number">0</span>; + V(bb->usedSpaceSem); +} + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">bbGet</span><span class="hljs-params">(BNDBUF *bb)</span> </span>{ + <span class="hljs-keyword">int</span> value, extractpos, newExtractpos; + P(bb->usedSpaceSem); + <span class="hljs-keyword">do</span>{ + extractpos = bb->extractpos; + value = bb->buff[extractpos]; + newExtractpos = extractpos + <span class="hljs-number">1</span>; + <span class="hljs-keyword">if</span>(newExtractpos >= bb-><span class="hljs-built_in">size</span>) newExtractpos = <span class="hljs-number">0</span>; + } <span class="hljs-keyword">while</span>(! atomic_compare_exchange_strong(&(bb->extractpos), &extractpos, newExtractpos)); + V(bb->freeSpaceSem); + <span class="hljs-keyword">return</span> value; +} +</code></pre> +<p><!-- /include --></p> <h2>open File</h2> <p><!-- include (fopen.c lang=c) --></p> <pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"die.h"</span></span> @@ -111,6 +290,173 @@ accept</p> } </code></pre> <p><!-- /include --></p> +<h2>listfiles</h2> +<p><!-- include (listFiles.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"die.h"</span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><dirent.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><stdio.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><stdlib.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><sys/stat.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><string.h></span></span> + +<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> BASEDIR <span class="hljs-meta-string">"."</span></span> + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">filter</span><span class="hljs-params">(<span class="hljs-keyword">const</span> struct dirent *dir)</span> </span>{ + <span class="hljs-keyword">if</span>(dir->d_name[<span class="hljs-number">0</span>] == <span class="hljs-string">'.'</span>) { + <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<span class="hljs-comment">//filter out .files</span> + } + <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stat</span> <span class="hljs-title">st</span>;</span> + <span class="hljs-keyword">char</span> name[<span class="hljs-built_in">strlen</span>(BASEDIR) + <span class="hljs-built_in">strlen</span>(dir->d_name)]; + <span class="hljs-built_in">sprintf</span>(name, <span class="hljs-string">"%s/%s"</span>, BASEDIR, dir->d_name); + <span class="hljs-keyword">if</span>(stat(name, &st) == <span class="hljs-number">-1</span>) die(<span class="hljs-string">"stat"</span>);<span class="hljs-comment">//lstat don't folow symlinks</span> + <span class="hljs-keyword">if</span>(S_ISREG(st.st_mode)) { + <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; + } + <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; +} + +<span class="hljs-comment">/** list files + */</span> +<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">listDir</span><span class="hljs-params">()</span></span>{ + <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">dirent</span> **<span class="hljs-title">namelist</span>;</span> <span class="hljs-comment">//array of dirents</span> + <span class="hljs-keyword">int</span> n = scandir(BASEDIR, &namelist, filter, alphasort);<span class="hljs-comment">//filter oder NULL</span> + <span class="hljs-keyword">if</span> (n == <span class="hljs-number">-1</span>) { + die(<span class="hljs-string">"scandir"</span>); + } + + <span class="hljs-keyword">while</span> (n--) { + <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%s/%s\n"</span>, BASEDIR, namelist[n]->d_name); + <span class="hljs-built_in">free</span>(namelist[n]); + } + <span class="hljs-built_in">free</span>(namelist); +} + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{ + listDir(); +} +</code></pre> +<p><!-- /include --></p> +<h2>reading / handling strings</h2> +<p>printf formats</p> +<p><!-- include (getline.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"die.h"</span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><stdio.h></span></span> + +<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">mygetline</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">char</span> *lineptr = <span class="hljs-literal">NULL</span>; + <span class="hljs-keyword">size_t</span> lineSize = <span class="hljs-number">0</span>; + <span class="hljs-keyword">ssize_t</span> strLen = <span class="hljs-number">0</span>; + + strLen = getline(&lineptr, &lineSize, <span class="hljs-built_in">stdin</span>); + <span class="hljs-keyword">if</span>(strLen < <span class="hljs-number">0</span>) {<span class="hljs-comment">//eof</span> + <span class="hljs-keyword">if</span> (ferror(<span class="hljs-built_in">stdin</span>)) die(<span class="hljs-string">"getline"</span>); + } + <span class="hljs-built_in">free</span>(lineptr); +} + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{ + mygetline(); +} +</code></pre> +<p><!-- /include --></p> +<p>fgets -> sscanf</p> +<p>strncmp</p> +<h2>optional</h2> +<h3>sem</h3> +<p><!-- include (sem.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><errno.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><pthread.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><stdlib.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"sem.h"</span></span> + +<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">SEM</span> +{</span> + <span class="hljs-keyword">pthread_mutex_t</span> m; + <span class="hljs-keyword">pthread_cond_t</span> c; + <span class="hljs-keyword">int</span> value; +}; + +<span class="hljs-function">SEM *<span class="hljs-title">semCreate</span><span class="hljs-params">(<span class="hljs-keyword">int</span> initVal)</span> </span>{ + SEM *sem = <span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(SEM)); + <span class="hljs-keyword">if</span>(sem == <span class="hljs-literal">NULL</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>;<span class="hljs-comment">// malloc failed</span> + <span class="hljs-keyword">int</span> err=<span class="hljs-number">0</span>; + err = pthread_mutex_init(&sem->m, <span class="hljs-literal">NULL</span>); + <span class="hljs-keyword">if</span>(err) { + <span class="hljs-built_in">free</span>(sem); + errno = err; + <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>; + } + err = pthread_cond_init(&sem->c, <span class="hljs-literal">NULL</span>); + <span class="hljs-keyword">if</span> (err) { + pthread_mutex_destroy(&sem->m); + <span class="hljs-built_in">free</span>(sem); + errno = err; + <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>; + } + + sem->value = initVal; + <span class="hljs-keyword">return</span> sem; +} + +<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">semDestroy</span><span class="hljs-params">(SEM *sem)</span> </span>{ + <span class="hljs-keyword">if</span>(sem == <span class="hljs-literal">NULL</span>) <span class="hljs-keyword">return</span>; + + pthread_cond_destroy(&sem->c);<span class="hljs-comment">//ignore returned errors</span> + pthread_mutex_destroy(&sem->m);<span class="hljs-comment">//ignore returned errors</span> + <span class="hljs-built_in">free</span>(sem); +} + +<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">P</span><span class="hljs-params">(SEM *sem)</span> </span>{<span class="hljs-comment">//fast mutex has only EINVAL error</span> + pthread_mutex_lock(&sem->m); + <span class="hljs-keyword">while</span>(sem->value <= <span class="hljs-number">0</span>) { + pthread_cond_wait(&sem->c, &sem->m); + } + sem->value--; + + pthread_mutex_unlock(&sem->m); +} + +<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">V</span><span class="hljs-params">(SEM *sem)</span> </span>{<span class="hljs-comment">//fast mutex has only EINVAL error</span> + pthread_mutex_lock(&sem->m); + sem->value++; + pthread_cond_signal(&sem->c); + + pthread_mutex_unlock(&sem->m); +} +</code></pre> +<p><!-- /include --></p> +<h3>stroulSave</h3> +<p><!-- include (strtoulSave.c lang=c) --></p> +<pre><code class="hljs language-c"><span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><errno.h></span></span> +<span class="hljs-meta"># <span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><stdlib.h></span></span> +<span class="hljs-comment">/** + * @brief strtoul with error checks + * + * @param str String to be parsed + * @param num return param where the unsigned long gets written to (gets only changed on success) + * @return 0 on success, none zero on error + */</span> +<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">strtoulSave</span><span class="hljs-params">(<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *str, <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> *num)</span> </span>{ + <span class="hljs-keyword">char</span> *endptr; + <span class="hljs-keyword">int</span> eno = errno; + errno = <span class="hljs-number">0</span>; + <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> value = strtoul(str, &endptr, <span class="hljs-number">10</span>); + <span class="hljs-keyword">if</span>(errno) <span class="hljs-keyword">return</span> errno; + errno = eno; <span class="hljs-comment">// restore errno, so we're not unintentionally loosing errors when calling this function</span> + + <span class="hljs-keyword">if</span> (endptr == str) <span class="hljs-keyword">return</span> EINVAL; <span class="hljs-comment">// no digits found</span> + <span class="hljs-keyword">if</span>(*endptr != <span class="hljs-string">'\0'</span>) <span class="hljs-keyword">return</span> EINVAL; <span class="hljs-comment">// contains invalid character</span> + + *num = value; + <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; +} + +<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{ + <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> num; + strtoulSave(<span class="hljs-string">"123"</span>, &num); +} +</code></pre> +<p><!-- /include --></p> <h1>RAID</h1> <ul> <li>RAID 0 : Daten werden ¨uber mehrere Platten gespeichert diff --git a/Zettel.md b/Zettel.md index 02f82921a1bd7c0d32b8b071e4feb4604589bbf2..d755b7cb7f87c8ec0fefb8bebcb7d34de44e2496 100644 --- a/Zettel.md +++ b/Zettel.md @@ -1,18 +1,5 @@ # Code -## reading / handling strings -printf formats - -fgets -> sscanf - -strncmp - -## parallel processing -fork exec - -### pthread - - ## networking ### client getaddrinfo @@ -24,10 +11,50 @@ accept !include(accept.c lang=c) +## parallel processing +### fork exec + -> siehe server + +#### signal + +!include(signal.c lang=c) + +### pthread + +!include(threadpool.c lang=c) + + +## jbuffer + +!include(jbuffer.c lang=c) + ## open File !include(fopen.c lang=c) +## listfiles + +!include(listFiles.c lang=c) + + +## reading / handling strings +printf formats + +!include(getline.c lang=c) + +fgets -> sscanf + +strncmp + +## optional + +### sem + +!include(sem.c lang=c) + +### stroulSave + +!include(strtoulSave.c lang=c) # RAID * RAID 0 : Daten werden ¨uber mehrere Platten gespeichert diff --git a/die.h b/die.h index 5ae2a3a260ad5cb8d1a8000ce24bfda5ac7bf7f7..1d6142a40c4095a64e89051cdde81a3154f042ba 100644 --- a/die.h +++ b/die.h @@ -4,7 +4,8 @@ static void die(const char *msg) { perror(msg); exit(EXIT_FAILURE); } +//static //fix unused-function void die_m(const char *msg) { fprintf(stderr, "%s\n", msg); exit(EXIT_FAILURE); -} \ No newline at end of file +} diff --git a/getline.c b/getline.c index bd544d5ad47761e57a34a2ec3b317c79d0a52cd4..a61a1bf5be0e8a1326a98218c9147b5f258fd15e 100644 --- a/getline.c +++ b/getline.c @@ -15,4 +15,4 @@ static void mygetline() { int main() { mygetline(); -} \ No newline at end of file +} diff --git a/jbuffer.c b/jbuffer.c index 3951b2104ed80c6e07d7477f1bd757ac97da22a8..be8c1bdccb9b61f34337fa2669cea22a9b3c8881 100644 --- a/jbuffer.c +++ b/jbuffer.c @@ -70,4 +70,4 @@ int bbGet(BNDBUF *bb) { } while(! atomic_compare_exchange_strong(&(bb->extractpos), &extractpos, newExtractpos)); V(bb->freeSpaceSem); return value; -} \ No newline at end of file +} diff --git a/listFiles.c b/listFiles.c index 8d3684d6e15307ca0e94e27f572a0fe35decbb60..e27e93447c12be956bf2efacbdae674651a8ba8b 100644 --- a/listFiles.c +++ b/listFiles.c @@ -39,4 +39,4 @@ static void listDir(){ int main() { listDir(); -} \ No newline at end of file +} diff --git a/sem.c b/sem.c index 29b7bf0e38dba25e05251fbf008070767e101d7d..b08e0b442408fd8753d62692098dad289d0bf160 100644 --- a/sem.c +++ b/sem.c @@ -56,4 +56,4 @@ void V(SEM *sem) {//fast mutex has only EINVAL error pthread_cond_signal(&sem->c); pthread_mutex_unlock(&sem->m); -} \ No newline at end of file +} diff --git a/signal.c b/signal.c index d8614c715c0b1ca93f5204576c6a247fe76b14c1..a32774dda3407b72d2b5cd22a2874f9990585065 100644 --- a/signal.c +++ b/signal.c @@ -51,4 +51,4 @@ static void sigchldHandler(int sig) { // collect all zombies (prevent zombies if signal got lost because of masking) i--; } -} \ No newline at end of file +} diff --git a/strtoulSave.c b/strtoulSave.c index 801d957cd752ed12af36fc8e07bf09369a4b80cf..e4885a5064ad3c62a7fa856575c1ed313a6c44a1 100644 --- a/strtoulSave.c +++ b/strtoulSave.c @@ -25,4 +25,4 @@ static int strtoulSave(const char *str, unsigned long *num) { int main(){ unsigned long num; strtoulSave("123", &num); -} \ No newline at end of file +} diff --git a/threadpool.c b/threadpool.c index d9358ea584b035bfe4729092db0d2dab2f77665a..edc3562ae53f6a3598178da030e953ae2a5895b8 100644 --- a/threadpool.c +++ b/threadpool.c @@ -41,4 +41,4 @@ int main() { errno = pthread_join(tids[i], NULL);//void **retval if (errno != 0) perror("pthread_join()"); } -} \ No newline at end of file +}