From b71d2051cb8be3288e237cb1ceb8c9b81ed4850e Mon Sep 17 00:00:00 2001
From: iliya <iliya.saroukha@hes-so.ch>
Date: Fri, 3 Nov 2023 15:40:33 +0100
Subject: [PATCH] feat: serie3 finished

---
 serie3/ex4/.gitignore |  2 ++
 serie3/ex4/Makefile   | 26 ++++++++++++++++
 serie3/ex4/ex4.md     | 69 +++++++++++++++++++++++++++++++++++++++++++
 serie3/ex4/prog.c     | 26 ++++++++++++++++
 4 files changed, 123 insertions(+)
 create mode 100644 serie3/ex4/.gitignore
 create mode 100644 serie3/ex4/Makefile
 create mode 100644 serie3/ex4/ex4.md
 create mode 100644 serie3/ex4/prog.c

diff --git a/serie3/ex4/.gitignore b/serie3/ex4/.gitignore
new file mode 100644
index 0000000..b6de771
--- /dev/null
+++ b/serie3/ex4/.gitignore
@@ -0,0 +1,2 @@
+*.o
+prog
diff --git a/serie3/ex4/Makefile b/serie3/ex4/Makefile
new file mode 100644
index 0000000..f702d8a
--- /dev/null
+++ b/serie3/ex4/Makefile
@@ -0,0 +1,26 @@
+CC := clang
+CFLAGS := -g -pedantic -Wall -Wextra -std=c11
+LDFLAGS := -fsanitize=address -fsanitize=leak -fsanitize=undefined -lm -lpthread
+TARGET := prog
+
+all: $(TARGET)
+
+$(TARGET): prog.o
+	@printf "=================== Building executable ===================\n"
+	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
+	@printf "\n"
+
+%.o: %.c
+	@printf "================== Building object files ==================\n"
+	$(CC) $(CFLAGS) -c $<
+	@printf "\n"
+
+
+.PHONY: clean
+
+clean:
+	rm -f *.o $(TARGET)
+
+.PHONY: rebuild
+	
+rebuild: clean all
diff --git a/serie3/ex4/ex4.md b/serie3/ex4/ex4.md
new file mode 100644
index 0000000..2865ccf
--- /dev/null
+++ b/serie3/ex4/ex4.md
@@ -0,0 +1,69 @@
+# Exercice 4
+
+Soit le code suivant :
+
+```c
+#define MAX_STRING_SIZE 256
+
+char *strtoupper(char *string) {
+    static char buffer[MAX_STRING_SIZE];
+    int index;
+    for (index = 0; string[index]; index++) {
+        // on part du principe que toupper est MT-safe et réentrant
+        buffer[index] = toupper(string[index]);
+    }
+    buffer[index] = 0;
+    return buffer;
+}
+```
+
+## Questions
+
+1. Le code est-il réentrant ?
+2. Le code est-il _thread-safe_ ?
+3. Dans la négative, modifiez le code pour qu'il devienne réentrant **et**
+thread-safe. À noter que modifier l'interface est autorisé.
+
+
+## Réponses
+
+1. Le code **n'est pas réentrant** car si l'exécution de la fonction `strtoupper`
+est interrompue pendant son exécution est qu'elle est appellée par cette fois-ci
+avec une autre chaîne de caractères que l'exécution initiale, le buffer pointera
+désormais sur la chaîne de caractères créée sur la base de la seconde exécution
+et non pas sur la première exécution. Une fonction réentrante ne doit pas référencer / 
+retourner de pointeur sur des données statiques ou globales, or dans ce cas elle
+le fait avec la variable `buffer` qui a un "comportement" global mais une visibilité
+locale.
+2. Le code **n'est pas thread-safe** pour la même raison que ci-dessus car la
+variable statique `static char buffer` risque d'être modifiée par l'exécution
+d'un autre thread.
+3.  ```c
+    #include <ctype.h>
+    #include <stdio.h>
+    #include <stdlib.h>
+    
+    #define MAX_STRING_SIZE 256
+    
+    char *strtoupper(char *string) {
+        char *buffer = calloc(MAX_STRING_SIZE, sizeof(char));
+        int index;
+    
+        for (index = 0; string[index]; index++) {
+            buffer[index] = toupper(string[index]);
+        }
+    
+        return buffer;
+    }
+    
+    int main(void) {
+        char *test_str = "Hello World!";
+        char *res = strtoupper(test_str);
+    
+        fprintf(stdout, "Result: %s\n", res);
+    
+        free(res);
+        return EXIT_SUCCESS;
+    }
+    ```
+
diff --git a/serie3/ex4/prog.c b/serie3/ex4/prog.c
new file mode 100644
index 0000000..17d6e5a
--- /dev/null
+++ b/serie3/ex4/prog.c
@@ -0,0 +1,26 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MAX_STRING_SIZE 256
+
+char *strtoupper(char *string) {
+    char *buffer = calloc(MAX_STRING_SIZE, sizeof(char));
+    int index;
+
+    for (index = 0; string[index]; index++) {
+        buffer[index] = toupper(string[index]);
+    }
+
+    return buffer;
+}
+
+int main(void) {
+    char *test_str = "Hello World!";
+    char *res = strtoupper(test_str);
+
+    fprintf(stdout, "Result: %s\n", res);
+
+    free(res);
+    return EXIT_SUCCESS;
+}
-- 
GitLab