From bb6bae6d3149145313e8dbc57c38f5c85345cdb3 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Thu, 28 May 2020 12:25:44 +0200 Subject: ignore zips --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 49fc4a3..a02e442 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ *.d cmake-build-debug/ bootloader.bin -build \ No newline at end of file +build +*.zip -- cgit v1.2.3-54-g00ecf From bc48f521390b360e1e1b131fc670cc3d02dcaf89 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Thu, 28 May 2020 13:16:29 +0200 Subject: init task 3 --- 03_exercise/Makefile | 32 +++++++++ 03_exercise/cli/Makefile | 23 +++++++ 03_exercise/cli/client.c | 13 ++++ 03_exercise/echo_server/Makefile | 22 ++++++ 03_exercise/echo_server/client.c | 47 +++++++++++++ 03_exercise/echo_server/server.c | 56 +++++++++++++++ 03_exercise/srv/Makefile | 23 +++++++ 03_exercise/srv/array.c | 59 ++++++++++++++++ 03_exercise/srv/array.h | 142 +++++++++++++++++++++++++++++++++++++++ 03_exercise/srv/server.c | 16 +++++ 10 files changed, 433 insertions(+) create mode 100644 03_exercise/Makefile create mode 100644 03_exercise/cli/Makefile create mode 100644 03_exercise/cli/client.c create mode 100644 03_exercise/echo_server/Makefile create mode 100644 03_exercise/echo_server/client.c create mode 100644 03_exercise/echo_server/server.c create mode 100644 03_exercise/srv/Makefile create mode 100644 03_exercise/srv/array.c create mode 100644 03_exercise/srv/array.h create mode 100644 03_exercise/srv/server.c diff --git a/03_exercise/Makefile b/03_exercise/Makefile new file mode 100644 index 0000000..8c02dc9 --- /dev/null +++ b/03_exercise/Makefile @@ -0,0 +1,32 @@ +#!/usr/bin/make +.SUFFIXES: +.PHONY: all run pack clean +.SILENT: run + +TAR = cli/client srv/server +PCK = lab-3.zip + +export CFLAGS = -std=gnu11 -c -g -Os -Wall -Werror -MMD -MP + +cli/client: $(wildcard cli/*.c) $(wildcard cli/*.h) + @$(MAKE) -C $(@D) + +srv/server: $(wildcard srv/*.c) $(wildcard srv/*.h) + @$(MAKE) -C $(@D) + +all: $(TAR) + +run: all + srv/server& echo $$! > .srv_pid + echo "Client Ready:" + cli/client + kill `cat .srv_pid` + $(RM) $(RMFILES) .srv_pid + +pack: clean + zip -r $(PCK) cli srv Makefile -x "*/.*" + +clean: + @$(MAKE) -C cli clean + @$(MAKE) -C srv clean + $(RM) $(RMFILES) $(PCK) diff --git a/03_exercise/cli/Makefile b/03_exercise/cli/Makefile new file mode 100644 index 0000000..c09533d --- /dev/null +++ b/03_exercise/cli/Makefile @@ -0,0 +1,23 @@ +#!/usr/bin/make +.SUFFIXES: +.PHONY: all run clean +TAR = client +SRC = $(wildcard *.c) +OBJ = $(SRC:%.c=%.o) + +DEP = $(OBJ:%.o=%.d) +-include $(DEP) + +%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +$(TAR): $(OBJ) + $(CC) $(LFLAGS) $^ -o $@ + +all: $(TAR) + +run: all + ./$(TAR) + +clean: + $(RM) $(RMFILES) $(OBJ) $(TAR) $(DEP) diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c new file mode 100644 index 0000000..48bf724 --- /dev/null +++ b/03_exercise/cli/client.c @@ -0,0 +1,13 @@ +#include +#include + +#define PORT 9000 +#define HOST "127.0.0.1" + +int main() +{ + getc(stdin); + printf("Client Exit\n"); + + return 0; +} diff --git a/03_exercise/echo_server/Makefile b/03_exercise/echo_server/Makefile new file mode 100644 index 0000000..df023d1 --- /dev/null +++ b/03_exercise/echo_server/Makefile @@ -0,0 +1,22 @@ +#!/usr/bin/make +.SUFFIXES: +.PHONY: all run clean +.SILENT: run + +TAR = client server +CFLAGS = -c -Os -Wall -Werror + +%.o: %.c + $(CC) $(CFLAGS) $^ -o $@ + +%: %.o + $(CC) -o $@ $^ + +all: $(TAR) + +run: all + ./server& + ./client + +clean: + $(RM) $(RMFILES) $(TAR) *.o diff --git a/03_exercise/echo_server/client.c b/03_exercise/echo_server/client.c new file mode 100644 index 0000000..a664221 --- /dev/null +++ b/03_exercise/echo_server/client.c @@ -0,0 +1,47 @@ + +#include +#include + +#include +#include +#include +#include + +static inline void die(const char* msg) +{ + perror(msg); + exit(-1); +} + +int main() +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(8000), + .sin_addr.s_addr = inet_addr("127.0.0.1") + }; + char buf[256]; + int cfd; + + if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Couldn't open the socket"); + + if (connect(cfd, (struct sockaddr*) &addr, sizeof(addr)) < 0) + die("Couldn't connect to socket"); + + for (int i = 0; i < 5; ++i) + { + if (write(cfd, "Ping", 4) < 0) + die("Couldn't send message"); + + printf("[send] Ping\n"); + + if (read(cfd, buf, sizeof(buf)) < 0) + die("Couldn't receive message"); + + printf("[recv] %s\n", buf); + } + + close(cfd); + return 0; +} diff --git a/03_exercise/echo_server/server.c b/03_exercise/echo_server/server.c new file mode 100644 index 0000000..faf309c --- /dev/null +++ b/03_exercise/echo_server/server.c @@ -0,0 +1,56 @@ + +#include +#include + +#include +#include +#include +#include + +static inline void die(const char* msg) +{ + perror(msg); + exit(-1); +} + +int main() +{ + struct sockaddr_in srv_addr, cli_addr; + int sockopt = 1; + socklen_t sad_sz = sizeof(struct sockaddr_in); + int sfd, cfd; + ssize_t bytes; + char buf[256]; + + srv_addr.sin_family = AF_INET; + srv_addr.sin_port = htons(8000); + srv_addr.sin_addr.s_addr = INADDR_ANY; + + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Couldn't open the socket"); + + setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char*) &sockopt, sizeof(sockopt)); + + if (bind(sfd, (struct sockaddr*) &srv_addr, sad_sz) < 0) + die("Couldn't bind socket"); + + if (listen(sfd, 1) < 0) + die("Couldn't listen to the socket"); + + cfd = accept(sfd, (struct sockaddr*) &cli_addr, &sad_sz); + if (cfd < 0) + die("Couldn't accept incoming connection"); + + while ((bytes = read(cfd, buf, sizeof(buf))) != 0) + { + if (bytes < 0) + die("Couldn't receive message"); + + if (write(cfd, buf, bytes) < 0) + die("Couldn't send message"); + } + + close(cfd); + close(sfd); + return 0; +} diff --git a/03_exercise/srv/Makefile b/03_exercise/srv/Makefile new file mode 100644 index 0000000..4fede74 --- /dev/null +++ b/03_exercise/srv/Makefile @@ -0,0 +1,23 @@ +#!/usr/bin/make +.SUFFIXES: +.PHONY: all run clean +TAR = server +SRC = $(wildcard *.c) +OBJ = $(SRC:%.c=%.o) + +DEP = $(OBJ:%.o=%.d) +-include $(DEP) + +%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +$(TAR): $(OBJ) + $(CC) $(LFLAGS) $^ -o $@ + +all: $(TAR) + +run: all + ./$(TAR) + +clean: + $(RM) $(RMFILES) $(OBJ) $(TAR) $(DEP) diff --git a/03_exercise/srv/array.c b/03_exercise/srv/array.c new file mode 100644 index 0000000..4f08366 --- /dev/null +++ b/03_exercise/srv/array.c @@ -0,0 +1,59 @@ +/***************************************************************************//** + * @file array.c + * @author Dorian Weber + * @brief Implementation des generalisierten Arrays. + ******************************************************************************/ + +#include "array.h" +#include +#include +#include + +/* ********************************************************* public functions */ + +/* (die runden Klammern um einige Funktionsnamen sind notwendig, da Makros + * gleichen Namens existieren und der Präprozessor diese expandieren würde) */ + +void* (arrayInit)(size_t capacity, size_t size) { + ArrayHdr *hdr = malloc(sizeof(*hdr) + size*capacity); + + if (hdr == NULL) + return NULL; + + hdr->len = 0; + hdr->cap = capacity; + + return hdr + 1; +} + +void arrayRelease(void* self) { + free(((ArrayHdr*) self) - 1); +} + +void* (arrayPush)(void* self, size_t size) { + ArrayHdr *hdr = ((ArrayHdr*) self) - 1; + + if (hdr->len == hdr->cap) { + hdr->cap *= 2; + hdr = realloc(hdr, sizeof(*hdr) + size*hdr->cap); + + if (hdr == NULL) { + fputs("program ran out of heap memory\n", stderr); + exit(-1); + } + } + + ++hdr->len; + return hdr + 1; +} + +void (arrayPop)(void* self) { + ArrayHdr *hdr = ((ArrayHdr*) self) - 1; + assert(hdr->len > 0); + --hdr->len; +} + +/* Symbol für die Inline-Funktionen erzeugen und aus diesem Modul exportieren */ +extern void arrayClear(void* self); +extern int arrayIsEmpty(const void* self); +extern size_t arrayLen(const void* self); diff --git a/03_exercise/srv/array.h b/03_exercise/srv/array.h new file mode 100644 index 0000000..78d21c9 --- /dev/null +++ b/03_exercise/srv/array.h @@ -0,0 +1,142 @@ +/***************************************************************************//** + * @file array.h + * @author Dorian Weber + * @brief Generischer Array-Typ. + * + * @details + * Diese Datei enthält die Schnittstelle eines generischen Array-Typs. Um den + * Element-Typ des Arrays festzulegen, deklariert man eine Variable als Zeiger + * auf den Element-Typ. Diese kann danach initialisiert und so benutzt werden, + * als wäre sie ein Zeiger auf ein Array variabler Länge. + * + * Hier ist ein Nutzungsbeispiel: + * @code + * int *array; + * + * arrayInit(array); + * arrayPush(array) = 1; + * arrayPush(array) = 2; + * arrayPush(array) = 3; + * + * while (!arrayIsEmpty(array)) + * printf("%i\n", arrayPop(array)); + * + * arrayRelease(array); + * @endcode + * + * Viele der genutzten Funktionen sind in Form von Makros implementiert, die die + * Variable, die den Zeiger auf das Array hält, aktualisieren, obwohl es so + * aussieht, als würde sich dieser Wert niemals ändern. Das macht es riskant + * mehr als einen Zeiger auf das Array zu halten, da jede Vergrößerung des + * Arrays alle Zeiger auf und in das Array potentiell invalidiert. Obwohl diese + * Fehlerquelle subtil und äußerst schwer diagnostizierbar ist - es ist eine + * extrem einfache Abstraktion - führt diese Datenstruktur meiner Meinung nach + * trotzdem zu einem massiven Produktivitätsgewinn; man sollte sich nur in etwa + * im Klaren über die unterliegende Implementation sein, um genau die Untermenge + * von Programmiertechniken auszuwählen, die korrekt funktioniert. + ******************************************************************************/ + +#ifndef ARRAY_H_INCLUDED +#define ARRAY_H_INCLUDED + +/* *** includes ************************************************************* */ + +#include + +/* *** structures *********************************************************** */ + +/**@brief Arrayheader. + * + * Diese Struktur wird jedem Array im Speicher vorangestellt und beinhaltet + * Informationen über Kapazität und aktuelle Auslastung des Arrays. Die + * Arrayelemente schließen sich dieser Struktur unmittelbar an, so dass der + * Nutzer von dieser versteckten Information nichts bemerkt. + */ +typedef struct ArrayHdr +{ + size_t len; /**<@brief Anzahl der Array-Elemente. */ + size_t cap; /**<@brief Kapazität des reservierten Speichers. */ +} ArrayHdr; + +/* *** interface ************************************************************ */ + +/**@internal + * @brief Initialisiert und gibt einen Zeiger auf den Start des Arrays zurück. + * @param capacity initiale Kapazität + * @param size Größe der Arrayelemente + * @return ein Zeiger auf den Start des Arrays, falls erfolgreich,\n + * \c NULL im Falle eines Speicherfehlers + */ +extern void* arrayInit(size_t capacity, size_t size); + +/**@brief Initialisiert ein neues Array. + * @param self das Array + * @return 0, falls keine Fehler bei der Initialisierung aufgetreten sind,\n + * -1 ansonsten + */ +#define arrayInit(self) \ + ((self = arrayInit(8, sizeof((self)[0]))) == NULL ? -1 : 0) + +/**@brief Gibt das Array und alle assoziierten Strukturen frei. + * @param self das Array + */ +extern void arrayRelease(void* self); + +/**@internal + * @brief Reserviert Platz für einen neuen Wert im Array. + * @param self das Array + * @param size Größe der Arrayelemente + * @return der neue Zeiger auf den Start des Arrays + */ +extern void* arrayPush(void* self, size_t size); + +/**@brief Legt einen Wert auf das Array. + * @param self das Array + */ +#define arrayPush(self) \ + (self = arrayPush(self, sizeof((self)[0])), (self)+arrayLen(self)-1)[0] + +/**@brief Entfernt das oberste Element des Arrays. + * @param self das Array + */ +extern void arrayPop(void* self); + +/**@brief Entfernt und liefert das oberste Element des Arrays. + * @param self das Array + * @return das oberste Element von \p self + */ +#define arrayPop(self) \ + (arrayPop(self), (self)+arrayLen(self))[0] + +/**@brief Gibt das oberste Element des Arrays zurück. + * @param self das Array + * @return das oberste Element von \p self + */ +#define arrayTop(self) \ + (self)[arrayLen(self) - 1] + +/**@brief Setzt die Länge des Arrays auf 0 zurück. +* @param self das Array +*/ +inline void arrayClear(void* self) { + ((ArrayHdr*) self)[-1].len = 0; +} + +/**@brief Gibt zurück, ob das Array leer ist. + * @param self das Array + * @return 0, falls nicht leer\n + 1, falls leer + */ +inline int arrayIsEmpty(const void* self) { + return ((ArrayHdr*) self)[-1].len == 0; +} + +/**@brief Gibt die Anzahl der Array-Elemente zurück. + * @param self das Array + * @return Anzahl der Elemente des Arrays + */ +inline size_t arrayLen(const void* self) { + return ((ArrayHdr*) self)[-1].len; +} + +#endif /* ARRAY_H_INCLUDED */ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c new file mode 100644 index 0000000..972b11f --- /dev/null +++ b/03_exercise/srv/server.c @@ -0,0 +1,16 @@ +#include +#include +#include + +#define PORT 9000 + +int main() +{ + while (1) + { + printf("[srv]: idle\n"); + sleep(2); + } + + return 0; +} -- cgit v1.2.3-54-g00ecf From 459123928ab5eb8fa3994a7d812ee9ec5838c0f2 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Thu, 28 May 2020 13:59:46 +0200 Subject: erstes gedöns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03_exercise/Makefile | 1 + 03_exercise/cli/client.c | 67 ++++++++++++++++++++++++++++++++++++++---- 03_exercise/srv/server.c | 75 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 128 insertions(+), 15 deletions(-) diff --git a/03_exercise/Makefile b/03_exercise/Makefile index 8c02dc9..dbf4b28 100644 --- a/03_exercise/Makefile +++ b/03_exercise/Makefile @@ -18,6 +18,7 @@ all: $(TAR) run: all srv/server& echo $$! > .srv_pid + sleep 1 echo "Client Ready:" cli/client kill `cat .srv_pid` diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 48bf724..3cd6f1b 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -1,13 +1,68 @@ #include +#include #include +#include +#include +#include +#include + #define PORT 9000 #define HOST "127.0.0.1" -int main() -{ - getc(stdin); - printf("Client Exit\n"); - - return 0; +static inline void die(const char *msg) { + perror(msg); + exit(-1); +} + +int main() { + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(PORT), + .sin_addr.s_addr = inet_addr(HOST) + }; + char buf[256]; + int cfd; + + if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Could not open socket"); + + if (connect(cfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + die("Could not connect to socket"); + + char *line = NULL; + size_t cap = 0; + __ssize_t length; + + while (1) { + if ((length = getline(&line, &cap, stdin)) < 0) { + fprintf(stderr, "Failed to read from STDIN"); + fflush(stderr); + exit(-1); + } + + if (strspn(line, " \n\t") == strlen(line)) { + // skip empty lines - empty being just spaces or tabs + continue; + } + + line[length - 1] = '\0'; // cut the line feed + + if (strcmp(line, "exit") == 0) { + break; + } + + strncpy(buf, line, strlen(line)); + + if (write(cfd, buf, sizeof(buf)) < 0) + die("Could not send message"); + + if (read(cfd, buf, sizeof(buf)) < 0) + die("Could not receive message"); + + printf("$> %s\n", buf); + } + + close(cfd); + return 0; } diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 972b11f..bb2b3ab 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -1,16 +1,73 @@ #include +#include #include + #include +#include +#include +#include #define PORT 9000 -int main() -{ - while (1) - { - printf("[srv]: idle\n"); - sleep(2); - } - - return 0; +static inline void die(const char *msg) { + perror(msg); + exit(-1); +} + +int main() { + struct sockaddr_in srv_addr, cli_addr; + int sockopt = 1; + socklen_t sad_sz = sizeof(struct sockaddr_in); + int sfd, cfd; + ssize_t bytes; + char in_buf[256]; + char out_buf[256]; + + srv_addr.sin_family = AF_INET; + srv_addr.sin_port = htons(PORT); + srv_addr.sin_addr.s_addr = INADDR_ANY; + + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Could not open socket"); + + setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sockopt, sizeof(sockopt)); + + if (bind(sfd, (struct sockaddr *) &srv_addr, sad_sz) < 0) + die("Could not bind socket"); + + if (listen(sfd, 1) < 0) + die("Could not listen on socket"); + + cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); + if (cfd < 0) + die("Could not accept incoming connection"); + + printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); + + while ((bytes = read(cfd, in_buf, sizeof(in_buf))) != 0) { + if (bytes < 0) + die("Couldn't receive message"); + + printf("srv: %s\n", in_buf); + + if (strcmp(in_buf, "get") == 0) { + // TODO: implement get + } else if (strcmp(in_buf, "put") == 0) { + // TODO: implement put + } else if (strcmp(in_buf, "ping") == 0) { + strncpy(out_buf, "pong!", sizeof(out_buf)); + } else { + // TODO: connect our shell implementation + strncpy(out_buf, "got: ", sizeof(out_buf)); + strncpy(out_buf + sizeof("got: "), in_buf, sizeof(out_buf) - sizeof("got: ")); + } + + if (write(cfd, out_buf, sizeof(out_buf)) < 0) + die("Couldn't send message"); + } + + printf("srv: closing down\n"); + + close(cfd); + close(sfd); } -- cgit v1.2.3-54-g00ecf From d6c6df06b0fcfa275cd4a6e3de15cd29f4693088 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 30 May 2020 13:16:49 +0200 Subject: make git shutup --- 03_exercise/cli/client | Bin 0 -> 22816 bytes 03_exercise/srv/server | Bin 0 -> 26256 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 03_exercise/cli/client create mode 100755 03_exercise/srv/server diff --git a/03_exercise/cli/client b/03_exercise/cli/client new file mode 100755 index 0000000..abcfd45 Binary files /dev/null and b/03_exercise/cli/client differ diff --git a/03_exercise/srv/server b/03_exercise/srv/server new file mode 100755 index 0000000..d866493 Binary files /dev/null and b/03_exercise/srv/server differ -- cgit v1.2.3-54-g00ecf From 85131d8acfca55810205af625d65358f006f3de7 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 1 Jun 2020 15:05:36 +0200 Subject: improvements --- 03_exercise/cli/client | Bin 22816 -> 22904 bytes 03_exercise/cli/client.c | 12 ++++++++---- 03_exercise/srv/server | Bin 26256 -> 26256 bytes 03_exercise/srv/server.c | 17 +++++++++++------ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index abcfd45..eb8470f 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 3cd6f1b..a98942d 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -10,6 +10,8 @@ #define PORT 9000 #define HOST "127.0.0.1" +#define BUF_SIZE 256 + static inline void die(const char *msg) { perror(msg); exit(-1); @@ -21,7 +23,7 @@ int main() { .sin_port = htons(PORT), .sin_addr.s_addr = inet_addr(HOST) }; - char buf[256]; + char buf[BUF_SIZE]; int cfd; if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) @@ -35,6 +37,7 @@ int main() { __ssize_t length; while (1) { + printf("%s > ", HOST); if ((length = getline(&line, &cap, stdin)) < 0) { fprintf(stderr, "Failed to read from STDIN"); fflush(stderr); @@ -54,13 +57,14 @@ int main() { strncpy(buf, line, strlen(line)); - if (write(cfd, buf, sizeof(buf)) < 0) + if (write(cfd, buf, BUF_SIZE) < 0) die("Could not send message"); - if (read(cfd, buf, sizeof(buf)) < 0) + if (read(cfd, buf, BUF_SIZE) < 0) die("Could not receive message"); - printf("$> %s\n", buf); + printf("%s\n", buf); + memset(buf, 0, BUF_SIZE); } close(cfd); diff --git a/03_exercise/srv/server b/03_exercise/srv/server index d866493..2402d7b 100755 Binary files a/03_exercise/srv/server and b/03_exercise/srv/server differ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index bb2b3ab..818036a 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -9,6 +9,8 @@ #define PORT 9000 +#define BUF_SIZE 256 + static inline void die(const char *msg) { perror(msg); exit(-1); @@ -20,8 +22,8 @@ int main() { socklen_t sad_sz = sizeof(struct sockaddr_in); int sfd, cfd; ssize_t bytes; - char in_buf[256]; - char out_buf[256]; + char in_buf[BUF_SIZE]; + char out_buf[BUF_SIZE]; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(PORT); @@ -44,11 +46,11 @@ int main() { printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); - while ((bytes = read(cfd, in_buf, sizeof(in_buf))) != 0) { + while ((bytes = read(cfd, in_buf, BUF_SIZE)) != 0) { if (bytes < 0) die("Couldn't receive message"); - printf("srv: %s\n", in_buf); + //printf("srv: %s\n", in_buf); if (strcmp(in_buf, "get") == 0) { // TODO: implement get @@ -58,12 +60,15 @@ int main() { strncpy(out_buf, "pong!", sizeof(out_buf)); } else { // TODO: connect our shell implementation - strncpy(out_buf, "got: ", sizeof(out_buf)); - strncpy(out_buf + sizeof("got: "), in_buf, sizeof(out_buf) - sizeof("got: ")); + memcpy(out_buf, "got: ", sizeof(out_buf)); + memcpy(out_buf + sizeof("got: ") - 1, in_buf, BUF_SIZE - sizeof("got: ") + 1); } if (write(cfd, out_buf, sizeof(out_buf)) < 0) die("Couldn't send message"); + + memset(in_buf, 0, BUF_SIZE); + memset(out_buf, 0, BUF_SIZE); } printf("srv: closing down\n"); -- cgit v1.2.3-54-g00ecf From 74abc79434fe895d0ca863e4d1d6c5c16b54f296 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 1 Jun 2020 15:46:28 +0200 Subject: trying to connect server and shell, weird --- 02_exercise/CMakeLists.txt | 2 +- 03_exercise/.srv_pid | 1 + 03_exercise/cli/client | Bin 22904 -> 23056 bytes 03_exercise/cli/client.c | 14 ++-- 03_exercise/srv/builtins.c | 120 +++++++++++++++++++++++++++++ 03_exercise/srv/builtins.h | 7 ++ 03_exercise/srv/process.c | 169 +++++++++++++++++++++++++++++++++++++++++ 03_exercise/srv/process.h | 30 ++++++++ 03_exercise/srv/prompt_utils.c | 90 ++++++++++++++++++++++ 03_exercise/srv/prompt_utils.h | 10 +++ 03_exercise/srv/server | Bin 26256 -> 58760 bytes 03_exercise/srv/server.c | 12 ++- 03_exercise/srv/shell.c | 121 +++++++++++++++++++++++++++++ 03_exercise/srv/shell.h | 6 ++ 14 files changed, 573 insertions(+), 9 deletions(-) create mode 100644 03_exercise/.srv_pid create mode 100644 03_exercise/srv/builtins.c create mode 100644 03_exercise/srv/builtins.h create mode 100644 03_exercise/srv/process.c create mode 100644 03_exercise/srv/process.h create mode 100644 03_exercise/srv/prompt_utils.c create mode 100644 03_exercise/srv/prompt_utils.h create mode 100644 03_exercise/srv/shell.c create mode 100644 03_exercise/srv/shell.h diff --git a/02_exercise/CMakeLists.txt b/02_exercise/CMakeLists.txt index e47f0ee..82df5d5 100644 --- a/02_exercise/CMakeLists.txt +++ b/02_exercise/CMakeLists.txt @@ -20,7 +20,7 @@ add_sanitizers(shell) add_library(builtin builtins.c) target_compile_options(builtin INTERFACE ${PROJECT_WARNINGS}) -add_library(array array.c) +add_library(array array.c ../03_exercise/srv/shell.h) add_library(prompt_utils prompt_utils.c) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid new file mode 100644 index 0000000..4e6d37a --- /dev/null +++ b/03_exercise/.srv_pid @@ -0,0 +1 @@ +1768723 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index eb8470f..53ba0d8 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index a98942d..527c67c 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -10,7 +10,7 @@ #define PORT 9000 #define HOST "127.0.0.1" -#define BUF_SIZE 256 +#define BUF_SIZE 1024 static inline void die(const char *msg) { perror(msg); @@ -51,20 +51,24 @@ int main() { line[length - 1] = '\0'; // cut the line feed - if (strcmp(line, "exit") == 0) { - break; - } - strncpy(buf, line, strlen(line)); if (write(cfd, buf, BUF_SIZE) < 0) die("Could not send message"); + if (strcmp(line, "exit") == 0) { + free(line); + line = NULL; + break; + } + if (read(cfd, buf, BUF_SIZE) < 0) die("Could not receive message"); printf("%s\n", buf); memset(buf, 0, BUF_SIZE); + free(line); + line = NULL; } close(cfd); diff --git a/03_exercise/srv/builtins.c b/03_exercise/srv/builtins.c new file mode 100644 index 0000000..f5497a3 --- /dev/null +++ b/03_exercise/srv/builtins.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + + +#include "array.h" +#include "builtins.h" + +void handle(int sig) { + /* Do nothing. */ +} + +typedef struct { + pid_t pid; + bool done; +} hack_struct; + +void builtin_wait(process p, bool bind) { + struct sigaction handler; + handler.sa_handler = handle; + sigemptyset(&handler.sa_mask); + handler.sa_flags = 0; + + hack_struct *pcs; + arrayInit(pcs); + + size_t i = 1; + bool error = false; + while (!error && p.argv[i] != NULL) { + char *end; + hack_struct pc; + pc.pid = strtol(p.argv[i], &end, 10); + pc.done = false; + if (*end != '\0') { + fprintf(stderr, "Not a valid pid: %s\n", p.argv[i]); + error = true; + break; + } + arrayPush(pcs) = pc; + ++i; + } + + if (error || arrayLen(pcs) == 0) { + printf("plz giv pid\n"); + arrayRelease(pcs); + return; + } + + int options = WUNTRACED; + if (!bind) { + options |= WNOHANG; + } + + int done_count = 0; + while (done_count != arrayLen(pcs)) { + for (int j = 0; j < arrayLen(pcs); ++j) { + int status; + hack_struct *current_pc = &j[pcs]; + if (current_pc->done) { + continue; + } + + if (bind) { + printf("Resuming %ld...\n", (long) current_pc->pid); + }/* else { + printf("Waiting for %ld...\n", (long) current_pc->pid); + }*/ + // install signal handler without SA_RESTART, so waitpid gets interrupted + sigaction(SIGINT, &handler, NULL); + pid_t res; + if ((res = waitpid(current_pc->pid, &status, options)) < 0) { + if (EINTR == errno) { + // cancelled by ctrl-c + if (bind) { + current_pc->done = true; + ++done_count; + kill(current_pc->pid, SIGKILL); + waitpid(current_pc->pid, &status, options); + printf("Killed [%ld]\n", (long) current_pc->pid); + } else { + kill(current_pc->pid, SIGCONT); + } + } else { + perror("Could not wait for process"); + ++done_count; + current_pc->done = true; + } + } else if (res == 0) { + // wait terminated because nohang + } else { + current_pc->done = true; + ++done_count; + if (bind) { + printf("[%i] ", WEXITSTATUS(status)); + } else { + printf("[%i] TERMINATED\n", current_pc->pid); + if (WIFEXITED(status)) { + printf("[%i] exited normally with status: %i\n", current_pc->pid, + WEXITSTATUS(status)); + } else if (WIFSTOPPED(status)) { + printf("[%i] was stopped by signal: %s\n", current_pc->pid, + strsignal(WSTOPSIG(status))); + } else if (WIFSIGNALED(status)) { + printf("[%i] was terminated by signal: %s\n", current_pc->pid, + strsignal(WTERMSIG(status))); + } else { + printf("[%i] exited (not sure why), exit status: %i\n", current_pc->pid, + WEXITSTATUS(status)); + } + } + } + signal(SIGINT, SIG_IGN); + } + } + + arrayRelease(pcs); +} diff --git a/03_exercise/srv/builtins.h b/03_exercise/srv/builtins.h new file mode 100644 index 0000000..43571f7 --- /dev/null +++ b/03_exercise/srv/builtins.h @@ -0,0 +1,7 @@ +#ifndef BUILTINS_H +#define BUILTINS_H + +#include "process.h" +void builtin_wait(process p, bool bind); + +#endif \ No newline at end of file diff --git a/03_exercise/srv/process.c b/03_exercise/srv/process.c new file mode 100644 index 0000000..c5be8c3 --- /dev/null +++ b/03_exercise/srv/process.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include + +#include "array.h" +#include "process.h" + + +// given a substring of a line tries to parse out as much information as possible +int parse_command(char const *line, char const *end, process *p) { + char *part; + char **local_parts; + if (arrayInit(part) != 0 || arrayInit(local_parts) != 0) { + fprintf(stderr, "Failed to prepare new part / parts array whilst parsing line"); + return -1; + } + + for (size_t i = 0; line + i < end; ++i) { + char c; + switch (c = line[i]) { + default: + arrayPush(part) = c; + break; + case ' ': + case '\t': + case '\0': + if (arrayLen(part) == 0) + continue; + + arrayPush(part) = '\0'; + arrayPush(local_parts) = part; + arrayInit(part); + } + } + + if (arrayLen(part) == 0) { + arrayRelease(part); + } else { + arrayPush(part) = '\0'; + arrayPush(local_parts) = part; + } + + arrayPush(local_parts) = NULL; + p->argc = arrayLen(local_parts) - 1; + p->argv = local_parts; + + return 0; +} + +int parse_line(char const *const line, process **processes) { + // splits the line at | and then parses the commands + int ret_code; + + if (arrayInit(*processes) != 0) { + perror("Failed to initialize processes array"); + return -1; + } + + bool done = false; + char const *cursor = line; + while (!done) { + process p = {.argv = NULL, .argc = 0, .in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true}; + char const *end = strchr(cursor, '|'); + + if (end == NULL) { + done = true; + end = line + strlen(line); + } + + if ((ret_code = parse_command(cursor, end, &p)) != 0) { + return ret_code; + } + + arrayPush(*processes) = p; + cursor = end + 1; + } + + size_t p_len = arrayLen(*processes); + process *last = *processes + (p_len - 1); + + // linking up all processes as we currently only have pipes for multiple commands + for (size_t i = 0; i < p_len - 1; ++i) { + int fds[2]; + if (pipe(fds) != 0) { + perror("Failed to create pipe"); + return -1; + } + (*processes)[i].out_fd = fds[1]; + (*processes)[i + 1].in_fd = fds[0]; + } + + // setting all processes to non blocking when + if (strcmp(last->argv[last->argc - 1], "&") == 0) { + arrayPop(last->argv) = NULL; + last->argc = last->argc - 1; + last->argv[last->argc] = NULL; + + for (size_t i = 0; i < p_len; ++i) { + (*processes)[i].blocking = false; + } + } + + return ret_code; +} + +int exec_command(process p) { + int status; + + if ((p.pid = fork()) == 0) { + if (p.in_fd != 0) { + dup2(p.in_fd, 0); + close(p.in_fd); + } + if(p.in_fd == 0 && !p.blocking) { + close(0); + } + + if (p.out_fd != 0) { + dup2(p.out_fd, 1); + close(p.out_fd); + } + + execvp(p.argv[0], p.argv); + fprintf(stderr, "command not found: \"%s\"\n", p.argv[0]); + fflush(stderr); + exit(-1); + } + + if (p.pid < 0) { + fprintf(stderr, "no fork\n"); + exit(-2); + } + + if (p.in_fd != 0) { + close(p.in_fd); + } + + if (p.out_fd != 0) { + close(p.out_fd); + } + + if (!p.blocking) + printf("[%i]\n", p.pid); + + if (waitpid(p.pid, &status, p.blocking ? 0 : WNOHANG) < 0) { + fprintf(stderr, "wait error'ed out\n"); + } + + return WEXITSTATUS(status); +} + +void free_processes(process **pr) { + process *processes = *pr; + while (!arrayIsEmpty(processes)) { + process p = arrayPop(processes); + while (!arrayIsEmpty(p.argv)) { + char *tmp = arrayTop(p.argv); + if (tmp) { + arrayRelease(tmp); + } + arrayPop(p.argv) = NULL; + } + arrayRelease(p.argv); + } + arrayRelease(processes); + *pr = NULL; +} \ No newline at end of file diff --git a/03_exercise/srv/process.h b/03_exercise/srv/process.h new file mode 100644 index 0000000..6e9208c --- /dev/null +++ b/03_exercise/srv/process.h @@ -0,0 +1,30 @@ +#ifndef SHELL_PROCESS_H +#define SHELL_PROCESS_H + +#include +#include + +typedef struct { + char **argv; + size_t argc; + int in_fd; + int out_fd; + int pid; + bool blocking; +} process; + +/* + * Parses the given line and creates an array of processes at *processes + * Expects tail -F file | grep panic & to mean that both processes should + * run in the background + */ +int parse_line(char const *line, process **processes); + +/* + * returns the return code of the executed program + */ +int exec_command(process p); + +void free_processes(process **processes); + +#endif // SHELL_PROCESS_H diff --git a/03_exercise/srv/prompt_utils.c b/03_exercise/srv/prompt_utils.c new file mode 100644 index 0000000..751a81b --- /dev/null +++ b/03_exercise/srv/prompt_utils.c @@ -0,0 +1,90 @@ +#include +#include + +#include "array.h" +#include "prompt_utils.h" + +char const *relative_path(char const *const from_dir, char const *const to_dir) { + // easiest cases first + { + if (strcmp(from_dir, to_dir) == 0) { + char *return_value = malloc(2); + strcpy(return_value, "."); + return return_value; + } + } + { + if (strcmp("/", from_dir) == 0) { + char *return_value = malloc(strlen(to_dir) + 2); + return_value[0] = '.'; + memcpy(return_value + 1, to_dir, strlen(to_dir) + 1); + return return_value; + } + } + + // splitting path into pieces so we can do strcmp on each of them + size_t const *const from_dir_indices = get_separator_indices(from_dir, '/'); + size_t const *const to_dir_indices = get_separator_indices(to_dir, '/'); + + size_t from_dir_len = arrayLen(from_dir_indices); + size_t to_dir_len = arrayLen(to_dir_indices); + + // finding the longest common substring + size_t array_len = from_dir_len < to_dir_len ? from_dir_len : to_dir_len; + size_t i = 0; + size_t common_position = 0; + for (; i < array_len - 1; ++i) { + if (from_dir_indices[i + 1] != to_dir_indices[i + 1]) { + break; + } + size_t index = from_dir_indices[i]; + size_t count = from_dir_indices[i + 1] - from_dir_indices[i]; + if (strncmp(from_dir + index, to_dir + index, count) != 0) { + break; + } + common_position = from_dir_indices[i + 1]; + } + + size_t levels_up = from_dir_len - i - 1; + char *return_value; + if (levels_up == 0) { + // equal dirs for whole length of path and not equal => subdir + size_t length = strlen(to_dir + common_position) + strlen("./") + 1; + return_value = malloc(length * sizeof(char)); + strcpy(return_value, "."); + strcat(return_value, to_dir + common_position); + } else { + char const *const go_up = "/.."; + size_t length = strlen(to_dir + common_position) + strlen("..") + + strlen(go_up) * (levels_up - 1) + 1; + return_value = malloc(length * sizeof(char)); + strcpy(return_value, ".."); + for (size_t j = 0; j < levels_up - 1; ++j) { + strcat(return_value, go_up); + } + if (strcmp("/", to_dir) != 0) { + strcat(return_value, to_dir + common_position); + } + } + + arrayRelease((void *)from_dir_indices); + arrayRelease((void *)to_dir_indices); + + return return_value; +} + +size_t *get_separator_indices(char const *const text, char seperator) { + size_t *indices; + arrayInit(indices); + char const *current = text; + if (strchr(current, seperator) == NULL) { + arrayRelease(indices); + return NULL; + } + while ((current = strchr(current, seperator)) != NULL) { + arrayPush(indices) = (size_t) (current - text); + ++current; + } + arrayPush(indices) = strlen(text); + return indices; +} diff --git a/03_exercise/srv/prompt_utils.h b/03_exercise/srv/prompt_utils.h new file mode 100644 index 0000000..36d065d --- /dev/null +++ b/03_exercise/srv/prompt_utils.h @@ -0,0 +1,10 @@ +#ifndef PROMPT_UTILS_H_INCLUDED +#define PROMPT_UTILS_H_INCLUDED + +// returns the relative path to get from the `from_dir` to the `to_dir` +char const *relative_path(char const *from_dir, char const *to_dir); + +// returns the position of each occurrence of the separator +size_t *get_separator_indices(char const *text, char separator); + +#endif // PROMPT_UTILS_H_INCLUDED diff --git a/03_exercise/srv/server b/03_exercise/srv/server index 2402d7b..232330a 100755 Binary files a/03_exercise/srv/server and b/03_exercise/srv/server differ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 818036a..5c23196 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -7,6 +7,8 @@ #include #include +#include "shell.h" + #define PORT 9000 #define BUF_SIZE 256 @@ -21,9 +23,9 @@ int main() { int sockopt = 1; socklen_t sad_sz = sizeof(struct sockaddr_in); int sfd, cfd; - ssize_t bytes; + /*ssize_t bytes; char in_buf[BUF_SIZE]; - char out_buf[BUF_SIZE]; + char out_buf[BUF_SIZE];*/ srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(PORT); @@ -46,6 +48,8 @@ int main() { printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); + int status = shell(cfd); + /* while ((bytes = read(cfd, in_buf, BUF_SIZE)) != 0) { if (bytes < 0) die("Couldn't receive message"); @@ -69,10 +73,12 @@ int main() { memset(in_buf, 0, BUF_SIZE); memset(out_buf, 0, BUF_SIZE); - } + }*/ printf("srv: closing down\n"); close(cfd); close(sfd); + + return status; } diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c new file mode 100644 index 0000000..a32fc5f --- /dev/null +++ b/03_exercise/srv/shell.c @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "array.h" +#include "process.h" +#include "prompt_utils.h" +#include "builtins.h" + +#define BUF_SIZE 256 + +process *processes; + +const char * const get_current_dir_name(); + +void signal_handler(int signal) { + if (signal == SIGINT) { + for (size_t i = 0; i < arrayLen(processes); ++i) { + pid_t pid = processes[i].pid; + if (pid != 0) { + kill(pid, SIGINT); + } + } + } +} + +int shell(int in_fd) { + setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + + dup2(in_fd, 1); + dup2(in_fd, 2); + + // I don't think the shell should exit on SIG_TERM + if (signal(SIGINT, SIG_IGN) == SIG_ERR) { + perror("Couldn't ignore sigterm"); + exit(errno); + } + + printf("Welcome! Available built-ins are:\n" + "cd: `cd ` - if no path is given, return to the current dir\n" + "wait: `wait pid1 ... pidN` - wait on the processes and report their exit conditions\n" + "fg: `fg pid` - pulls a process from the background back in the foreground\n" + "\n" + "You can put processes in the background using `&`\n" + "And with `|` you can pipe the output from one process to the input of another\n" + ); + + char const *const original_wd = get_current_dir_name(); + + bool done = false; + while (!done) { + char line[BUF_SIZE]; + + for (int i = 0; i < BUF_SIZE; ++i) { + read(in_fd, line + i, 1); + if (line[i] == '\n') { + line[i] = 0; + break; + } + } + + if (strspn(line, " \n\t") == strlen(line)) { + // skip empty lines - empty being just spaces or tabs + continue; + } + + processes = NULL; + parse_line(line, &processes); + + if (strcmp(processes[0].argv[0], "cd") == 0) { + if (arrayLen(processes) != 1) { + perror("Can't chain cd with other processes"); + } + int ret; + switch (arrayLen(processes[0].argv)) { + case 3: + ret = chdir(processes[0].argv[1]); + break; + case 2: + ret = chdir(original_wd); + break; + default: + fprintf(stderr, "usage: cd \n"); + fflush(stderr); + ret = -1; + } + + if (ret) + printf("[%i] ", ret); + + } else if (strcmp(processes[0].argv[0], "exit") == 0) { + done = true; + } else if (strcmp(processes[0].argv[0], "wait") == 0) { + builtin_wait(processes[0], false); + } else if (strcmp(processes[0].argv[0], "fg") == 0) { + // same behaviour as wait, just bind to shell again (i.e. terminate process on ctrl-c) + builtin_wait(processes[0], true); + } else { + if (arrayLen(processes) != 0 && processes[arrayLen(processes) - 1].blocking) { + signal(SIGINT, signal_handler); + } + for (size_t i = 0; i < arrayLen(processes); ++i) { + int ret = exec_command(processes[i]); + if (ret) + printf("[%i] ", ret); + } + signal(SIGINT, SIG_IGN); + } + + free_processes(&processes); + } + + free((void *) original_wd); + + return 0; +} diff --git a/03_exercise/srv/shell.h b/03_exercise/srv/shell.h new file mode 100644 index 0000000..3c79844 --- /dev/null +++ b/03_exercise/srv/shell.h @@ -0,0 +1,6 @@ +#ifndef BETRIEBSYSTEME_SHELL_H +#define BETRIEBSYSTEME_SHELL_H + +int shell(int in_fd); + +#endif //BETRIEBSYSTEME_SHELL_H -- cgit v1.2.3-54-g00ecf From e1520589de17d08c4bde37f1198f18d012a1f377 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 6 Jun 2020 14:06:00 +0200 Subject: basic shell works - sometimes goes out of sync (running current command only after issueing the next) --- 03_exercise/.srv_pid | 2 +- 03_exercise/cli/client | Bin 23056 -> 23640 bytes 03_exercise/cli/client.c | 39 +++++++++++++----- 03_exercise/echo_server/server.c | 85 +++++++++++++++++++-------------------- 03_exercise/srv/server | Bin 58760 -> 58856 bytes 03_exercise/srv/shell.c | 18 +++++---- CMakeLists.txt | 2 + 7 files changed, 85 insertions(+), 61 deletions(-) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index 4e6d37a..ed33336 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -1768723 +618929 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 53ba0d8..c57cade 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 527c67c..83b4dec 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -10,7 +12,21 @@ #define PORT 9000 #define HOST "127.0.0.1" -#define BUF_SIZE 1024 +#define BUF_SIZE 2048 + +int cfd; + +/* Signal Handler for SIGINT */ +void sigintHandler(int sig_num) { + errno = 0; + if (fcntl(cfd, F_GETFD) != -1 || errno != EBADF) { + write(cfd, "exit\n", 6); + close(cfd); + } + printf("Terminating client\n"); + fflush(stdout); + exit(-1); +} static inline void die(const char *msg) { perror(msg); @@ -23,8 +39,7 @@ int main() { .sin_port = htons(PORT), .sin_addr.s_addr = inet_addr(HOST) }; - char buf[BUF_SIZE]; - int cfd; + char buf[BUF_SIZE]; if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) die("Could not open socket"); @@ -36,8 +51,14 @@ int main() { size_t cap = 0; __ssize_t length; + if (read(cfd, buf, BUF_SIZE) < 0) + die("Could not receive message"); + + printf("%s\n$> ", buf); + memset(buf, 0, BUF_SIZE); + while (1) { - printf("%s > ", HOST); + //printf("[C] awaiting command\n"); if ((length = getline(&line, &cap, stdin)) < 0) { fprintf(stderr, "Failed to read from STDIN"); fflush(stderr); @@ -49,14 +70,14 @@ int main() { continue; } - line[length - 1] = '\0'; // cut the line feed + strncpy(buf, line, strlen(line) + 1); - strncpy(buf, line, strlen(line)); + //printf("[C] pre send: \"%s\"\n", buf); - if (write(cfd, buf, BUF_SIZE) < 0) + if (write(cfd, buf, strlen(line)) < 0) die("Could not send message"); - if (strcmp(line, "exit") == 0) { + if (strcmp(line, "exit\n") == 0) { free(line); line = NULL; break; @@ -65,7 +86,7 @@ int main() { if (read(cfd, buf, BUF_SIZE) < 0) die("Could not receive message"); - printf("%s\n", buf); + printf("%s$> ", buf); memset(buf, 0, BUF_SIZE); free(line); line = NULL; diff --git a/03_exercise/echo_server/server.c b/03_exercise/echo_server/server.c index faf309c..5f647c1 100644 --- a/03_exercise/echo_server/server.c +++ b/03_exercise/echo_server/server.c @@ -7,50 +7,47 @@ #include #include -static inline void die(const char* msg) -{ - perror(msg); - exit(-1); +static inline void die(const char *msg) { + perror(msg); + exit(-1); } -int main() -{ - struct sockaddr_in srv_addr, cli_addr; - int sockopt = 1; - socklen_t sad_sz = sizeof(struct sockaddr_in); - int sfd, cfd; - ssize_t bytes; - char buf[256]; - - srv_addr.sin_family = AF_INET; - srv_addr.sin_port = htons(8000); - srv_addr.sin_addr.s_addr = INADDR_ANY; - - if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - die("Couldn't open the socket"); - - setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char*) &sockopt, sizeof(sockopt)); - - if (bind(sfd, (struct sockaddr*) &srv_addr, sad_sz) < 0) - die("Couldn't bind socket"); - - if (listen(sfd, 1) < 0) - die("Couldn't listen to the socket"); - - cfd = accept(sfd, (struct sockaddr*) &cli_addr, &sad_sz); - if (cfd < 0) - die("Couldn't accept incoming connection"); - - while ((bytes = read(cfd, buf, sizeof(buf))) != 0) - { - if (bytes < 0) - die("Couldn't receive message"); - - if (write(cfd, buf, bytes) < 0) - die("Couldn't send message"); - } - - close(cfd); - close(sfd); - return 0; +int main() { + struct sockaddr_in srv_addr, cli_addr; + int sockopt = 1; + socklen_t sad_sz = sizeof(struct sockaddr_in); + int sfd, cfd; + ssize_t bytes; + char buf[256]; + + srv_addr.sin_family = AF_INET; + srv_addr.sin_port = htons(8000); + srv_addr.sin_addr.s_addr = INADDR_ANY; + + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Couldn't open the socket"); + + setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sockopt, sizeof(sockopt)); + + if (bind(sfd, (struct sockaddr *) &srv_addr, sad_sz) < 0) + die("Couldn't bind socket"); + + if (listen(sfd, 1) < 0) + die("Couldn't listen to the socket"); + + cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); + if (cfd < 0) + die("Couldn't accept incoming connection"); + + while ((bytes = read(cfd, buf, sizeof(buf))) != 0) { + if (bytes < 0) + die("Couldn't receive message"); + + if (write(cfd, buf, bytes) < 0) + die("Couldn't send message"); + } + + close(cfd); + close(sfd); + return 0; } diff --git a/03_exercise/srv/server b/03_exercise/srv/server index 232330a..efe2660 100755 Binary files a/03_exercise/srv/server and b/03_exercise/srv/server differ diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index a32fc5f..74586c7 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -11,7 +11,7 @@ #include "prompt_utils.h" #include "builtins.h" -#define BUF_SIZE 256 +#define BUF_SIZE 2048 process *processes; @@ -55,19 +55,19 @@ int shell(int in_fd) { bool done = false; while (!done) { char line[BUF_SIZE]; + __ssize_t length; - for (int i = 0; i < BUF_SIZE; ++i) { - read(in_fd, line + i, 1); - if (line[i] == '\n') { - line[i] = 0; - break; - } + if ((length = read(in_fd, line, BUF_SIZE)) < 0) { + fprintf(stderr, "Failed to read from STDIN"); + fflush(stderr); + exit(-1); } if (strspn(line, " \n\t") == strlen(line)) { // skip empty lines - empty being just spaces or tabs continue; } + line[length - 1] = '\0'; // cut the line feed processes = NULL; parse_line(line, &processes); @@ -92,6 +92,8 @@ int shell(int in_fd) { if (ret) printf("[%i] ", ret); + else + printf("%s\n", get_current_dir_name()); } else if (strcmp(processes[0].argv[0], "exit") == 0) { done = true; @@ -115,6 +117,8 @@ int shell(int in_fd) { free_processes(&processes); } + printf("Disconnecting..."); + free((void *) original_wd); return 0; diff --git a/CMakeLists.txt b/CMakeLists.txt index 41de2c8..5d0441e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set(CLANG_WARNINGS # (ie printf) -Werror ) + set(GCC_WARNINGS ${CLANG_WARNINGS} -Wmisleading-indentation # warn if indentation implies blocks where blocks @@ -37,4 +38,5 @@ set(GCC_WARNINGS -Wlogical-op # warn about logical operations being used where bitwise were # probably wanted ) + set(PROJECT_WARNINGS ${GCC_WARNINGS}) -- cgit v1.2.3-54-g00ecf From d5aa7933f42de1ef374feefe063dae724d059817 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 6 Jun 2020 15:24:59 +0200 Subject: broken shit --- 03_exercise/.srv_pid | 2 +- 03_exercise/cli/client | Bin 23640 -> 27408 bytes 03_exercise/cli/client.c | 73 ++++++++++++++++++++++++++++++++++++++++++++-- 03_exercise/srv/process.c | 42 +++++++++++++------------- 03_exercise/srv/server | Bin 58856 -> 60872 bytes 03_exercise/srv/shell.c | 53 +++++++++++++++++++++++++++++---- 6 files changed, 141 insertions(+), 29 deletions(-) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index ed33336..f376adb 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -618929 +892256 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index c57cade..8da5d5a 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 83b4dec..d64dd62 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -33,6 +33,54 @@ static inline void die(const char *msg) { exit(-1); } +int write_all(int sock, char *buffer, int size) { + int nwrite, sent = 0; + + while (sent < size) { + if ((nwrite = write(sock, buffer + sent, size - sent)) < 0) { + perror("Write"); + exit(1); + } + + sent += nwrite; + } + + return sent; +} + +void send_file(int server_fd, char *path) { + char buffer[512]; + int file_fd; + + if ((file_fd = open(path, O_RDONLY)) == -1) { perror("Open"); } + + FILE *file = fdopen(file_fd, "r"); + + fseek(file, 0L, SEEK_END); + long int sz = ftell(file); + fseek(file, 0L, SEEK_SET); + + int length = snprintf(NULL, 0, "%ld", sz); + char msg[length + 1 + 3]; + sprintf(msg, "< ", buf); + printf("%s\n", buf); memset(buf, 0, BUF_SIZE); while (1) { + printf("$> "); //printf("[C] awaiting command\n"); if ((length = getline(&line, &cap, stdin)) < 0) { fprintf(stderr, "Failed to read from STDIN"); @@ -70,6 +119,26 @@ int main() { continue; } + char cmd[4]; + char path[BUF_SIZE - 3]; + memcpy(cmd, line, 3); + cmd[3] = 0; + memcpy(path, line + 4, BUF_SIZE - 4); + path[strlen(path) - 1] = 0; + printf("cmd: \"%s\"\n", cmd); + printf("path: \"%s\"\n", path); + if (strcmp(cmd, "put") == 0) { + if (strlen(path) == 0) { + fprintf(stderr, "path missing\n"); + } else { + printf("got put with %s\n", path); + send_file(cfd, path); + } + free(line); + line = NULL; + continue; + } + strncpy(buf, line, strlen(line) + 1); //printf("[C] pre send: \"%s\"\n", buf); @@ -86,7 +155,7 @@ int main() { if (read(cfd, buf, BUF_SIZE) < 0) die("Could not receive message"); - printf("%s$> ", buf); + printf("%s", buf); memset(buf, 0, BUF_SIZE); free(line); line = NULL; diff --git a/03_exercise/srv/process.c b/03_exercise/srv/process.c index c5be8c3..fe66a66 100644 --- a/03_exercise/srv/process.c +++ b/03_exercise/srv/process.c @@ -20,25 +20,25 @@ int parse_command(char const *line, char const *end, process *p) { for (size_t i = 0; line + i < end; ++i) { char c; switch (c = line[i]) { - default: - arrayPush(part) = c; - break; - case ' ': - case '\t': - case '\0': - if (arrayLen(part) == 0) - continue; - - arrayPush(part) = '\0'; - arrayPush(local_parts) = part; - arrayInit(part); + default: + arrayPush(part) = c; + break; + case ' ': + case '\t': + case '\0': + if (arrayLen(part) == 0) + continue; + + arrayPush(part) = '\0'; + arrayPush(local_parts) = part; + arrayInit(part); } } if (arrayLen(part) == 0) { arrayRelease(part); } else { - arrayPush(part) = '\0'; + arrayPush(part) = '\0'; arrayPush(local_parts) = part; } @@ -51,22 +51,22 @@ int parse_command(char const *line, char const *end, process *p) { int parse_line(char const *const line, process **processes) { // splits the line at | and then parses the commands - int ret_code; + int ret_code; if (arrayInit(*processes) != 0) { perror("Failed to initialize processes array"); return -1; } - bool done = false; + bool done = false; char const *cursor = line; while (!done) { - process p = {.argv = NULL, .argc = 0, .in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true}; - char const *end = strchr(cursor, '|'); + process p = {.argv = NULL, .argc = 0, .in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true}; + char const *end = strchr(cursor, '|'); if (end == NULL) { done = true; - end = line + strlen(line); + end = line + strlen(line); } if ((ret_code = parse_command(cursor, end, &p)) != 0) { @@ -87,7 +87,7 @@ int parse_line(char const *const line, process **processes) { perror("Failed to create pipe"); return -1; } - (*processes)[i].out_fd = fds[1]; + (*processes)[i].out_fd = fds[1]; (*processes)[i + 1].in_fd = fds[0]; } @@ -113,7 +113,7 @@ int exec_command(process p) { dup2(p.in_fd, 0); close(p.in_fd); } - if(p.in_fd == 0 && !p.blocking) { + if (p.in_fd == 0 && !p.blocking) { close(0); } @@ -156,7 +156,7 @@ void free_processes(process **pr) { while (!arrayIsEmpty(processes)) { process p = arrayPop(processes); while (!arrayIsEmpty(p.argv)) { - char *tmp = arrayTop(p.argv); + char *tmp = arrayTop(p.argv); if (tmp) { arrayRelease(tmp); } diff --git a/03_exercise/srv/server b/03_exercise/srv/server index efe2660..69edeea 100755 Binary files a/03_exercise/srv/server and b/03_exercise/srv/server differ diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 74586c7..792a26c 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -15,7 +16,49 @@ process *processes; -const char * const get_current_dir_name(); +int write_all(int sock, char *buffer, int size) { + int nwrite, sent = 0; + + while (sent < size) { + if ((nwrite = write(sock, buffer + sent, size - sent)) < 0) { + perror("Write"); + exit(1); + } + + sent += nwrite; + } + + return sent; +} + +void receive_file(int sock, char *path, int size) { + char buffer[512]; + int file_fd; + int nread, received; + + if ((file_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { perror("Open"); } + + while (true) { + received = 0; + + /* Read all data */ + while (received < size) { + if ((nread = read(sock, buffer + received, size - received)) < 0) { + perror("Read"); + //pthread_exit(NULL); + exit(1); + } + + received += nread; + } + + if (strncmp(buffer, "end", 4) == 0) { break; } + + write_all(file_fd, buffer, strlen(buffer) + 1); + } +} + +const char *const get_current_dir_name(); void signal_handler(int signal) { if (signal == SIGINT) { @@ -54,7 +97,7 @@ int shell(int in_fd) { bool done = false; while (!done) { - char line[BUF_SIZE]; + char line[BUF_SIZE]; __ssize_t length; if ((length = read(in_fd, line, BUF_SIZE)) < 0) { @@ -107,9 +150,9 @@ int shell(int in_fd) { signal(SIGINT, signal_handler); } for (size_t i = 0; i < arrayLen(processes); ++i) { - int ret = exec_command(processes[i]); - if (ret) - printf("[%i] ", ret); + /*int ret = */exec_command(processes[i]); + /*if (ret) + printf("[%i] ", ret);*/ } signal(SIGINT, SIG_IGN); } -- cgit v1.2.3-54-g00ecf From 178cbf7c04639cd24b7a1eb70d532fb64b9f908d Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 6 Jun 2020 15:25:07 +0200 Subject: mend --- 03_exercise/test | 1 + 1 file changed, 1 insertion(+) create mode 100644 03_exercise/test diff --git a/03_exercise/test b/03_exercise/test new file mode 100644 index 0000000..eb1ae45 --- /dev/null +++ b/03_exercise/test @@ -0,0 +1 @@ +... -- cgit v1.2.3-54-g00ecf From 2821f125c91c192cdd28997e78f366f2db2d39c4 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 6 Jun 2020 17:19:55 +0200 Subject: stuff works --- 03_exercise/.srv_pid | 2 +- 03_exercise/CMakeLists.txt | 19 ++++++ 03_exercise/cli/client | Bin 27408 -> 28384 bytes 03_exercise/cli/client.c | 154 ++++++++++++++++++++++++++------------------- 03_exercise/srv/server | Bin 60872 -> 0 bytes 03_exercise/srv/server.c | 6 +- 03_exercise/srv/shell.c | 19 +++--- CMakeLists.txt | 1 + 8 files changed, 121 insertions(+), 80 deletions(-) create mode 100644 03_exercise/CMakeLists.txt delete mode 100755 03_exercise/srv/server diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index f376adb..ab09251 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -892256 +1493889 diff --git a/03_exercise/CMakeLists.txt b/03_exercise/CMakeLists.txt new file mode 100644 index 0000000..a03d39b --- /dev/null +++ b/03_exercise/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5) + +project(remote_shell C) + +set(CMAKE_C_COMPILER gcc) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED True) +add_compile_definitions(_GNU_SOURCE) + +find_package(Sanitizers) + +add_executable(client cli/client.c) +add_executable(server srv/prompt_utils.c srv/array.c srv/shell.c srv/process.c srv/server.c srv/builtins.c) + +target_compile_options(client INTERFACE ${PROJECT_WARNINGS}) +target_compile_options(server INTERFACE ${PROJECT_WARNINGS}) + +add_sanitizers(client) +add_sanitizers(server) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 8da5d5a..0fcf5c1 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index d64dd62..c1bc5d1 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -8,20 +8,21 @@ #include #include #include +#include #define PORT 9000 #define HOST "127.0.0.1" #define BUF_SIZE 2048 -int cfd; +int sock; /* Signal Handler for SIGINT */ void sigintHandler(int sig_num) { errno = 0; - if (fcntl(cfd, F_GETFD) != -1 || errno != EBADF) { - write(cfd, "exit\n", 6); - close(cfd); + if (fcntl(sock, F_GETFD) != -1 || errno != EBADF) { + write(sock, "exit\n", 6); + close(sock); } printf("Terminating client\n"); fflush(stdout); @@ -81,86 +82,109 @@ void send_file(int server_fd, char *path) { close(file_fd); } +#define BREAK 1 +#define CONTINUE 2 + +int parse(int server_sock, char *buffer, ssize_t length) { + char cmd[4]; + char path[BUF_SIZE - 3]; + memcpy(cmd, buffer, 3); + cmd[3] = 0; + memcpy(path, buffer + 4, BUF_SIZE - 4); + path[strlen(path) - 1] = 0; + if (strcmp(cmd, "put") == 0) { + if (strlen(path) == 0) { + fprintf(stderr, "path missing\n"); + } else { + printf("got put with %s\n", path); + send_file(sock, path); + } + return CONTINUE; + } + + buffer[length] = '\0'; + + if (strspn(buffer, " \n\t") == strlen(buffer)) { + // skip empty lines - empty being just spaces or tabs + return CONTINUE; + } + + if (write(server_sock, buffer, strlen(buffer)) < 0) + die("Could not send message"); + + if (strcmp(buffer, "exit\n") == 0) { + return BREAK; + } + + return 0; +} + +void read_stdin(int *done); + +void read_server_sock(int *done); + int main() { + setvbuf(stdout, NULL, _IONBF, 0); + struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = inet_addr(HOST) }; - char buf[BUF_SIZE]; - if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) die("Could not open socket"); - if (connect(cfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) die("Could not connect to socket"); - char *line = NULL; - size_t cap = 0; - __ssize_t length; + signal(SIGINT, &sigintHandler); - if (read(cfd, buf, BUF_SIZE) < 0) - die("Could not receive message"); + pid_t pid = fork(); - printf("%s\n", buf); - memset(buf, 0, BUF_SIZE); - - while (1) { - printf("$> "); - //printf("[C] awaiting command\n"); - if ((length = getline(&line, &cap, stdin)) < 0) { - fprintf(stderr, "Failed to read from STDIN"); - fflush(stderr); - exit(-1); - } + int done = 0; + if (pid == 0) { + read_stdin(&done); + } else { + read_server_sock(&done); + } - if (strspn(line, " \n\t") == strlen(line)) { - // skip empty lines - empty being just spaces or tabs - continue; - } + close(sock); + return 0; +} - char cmd[4]; - char path[BUF_SIZE - 3]; - memcpy(cmd, line, 3); - cmd[3] = 0; - memcpy(path, line + 4, BUF_SIZE - 4); - path[strlen(path) - 1] = 0; - printf("cmd: \"%s\"\n", cmd); - printf("path: \"%s\"\n", path); - if (strcmp(cmd, "put") == 0) { - if (strlen(path) == 0) { - fprintf(stderr, "path missing\n"); - } else { - printf("got put with %s\n", path); - send_file(cfd, path); +void read_server_sock(int *done) { + char server_buffer[BUF_SIZE]; + ssize_t length; + + while (!*done) { + if ((length = read(sock, server_buffer, BUF_SIZE)) > 0) { + server_buffer[length] = '\0'; + printf("%s", server_buffer); + if (server_buffer[length - 1] == '\n') { + printf("$> "); + fflush(stdout); } - free(line); - line = NULL; - continue; } + } +} - strncpy(buf, line, strlen(line) + 1); - - //printf("[C] pre send: \"%s\"\n", buf); - - if (write(cfd, buf, strlen(line)) < 0) - die("Could not send message"); - if (strcmp(line, "exit\n") == 0) { - free(line); - line = NULL; - break; +void read_stdin(int *done) { + char stdinp_buffer[BUF_SIZE]; + ssize_t length; + + while (!*done) { + if ((length = read(STDIN_FILENO, stdinp_buffer, BUF_SIZE)) > 0) { + switch (parse(sock, stdinp_buffer, length)) { + case CONTINUE: + continue; + case BREAK: + *done = 1; + break; + default: + break; + } } - - if (read(cfd, buf, BUF_SIZE) < 0) - die("Could not receive message"); - - printf("%s", buf); - memset(buf, 0, BUF_SIZE); - free(line); - line = NULL; } - - close(cfd); - return 0; } diff --git a/03_exercise/srv/server b/03_exercise/srv/server deleted file mode 100755 index 69edeea..0000000 Binary files a/03_exercise/srv/server and /dev/null differ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 5c23196..8527b83 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -50,7 +50,7 @@ int main() { int status = shell(cfd); /* - while ((bytes = read(cfd, in_buf, BUF_SIZE)) != 0) { + while ((bytes = read(sock, in_buf, BUF_SIZE)) != 0) { if (bytes < 0) die("Couldn't receive message"); @@ -68,14 +68,14 @@ int main() { memcpy(out_buf + sizeof("got: ") - 1, in_buf, BUF_SIZE - sizeof("got: ") + 1); } - if (write(cfd, out_buf, sizeof(out_buf)) < 0) + if (write(sock, out_buf, sizeof(out_buf)) < 0) die("Couldn't send message"); memset(in_buf, 0, BUF_SIZE); memset(out_buf, 0, BUF_SIZE); }*/ - printf("srv: closing down\n"); + //printf("srv: closing down\n"); close(cfd); close(sfd); diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 792a26c..449905b 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -58,8 +58,6 @@ void receive_file(int sock, char *path, int size) { } } -const char *const get_current_dir_name(); - void signal_handler(int signal) { if (signal == SIGINT) { for (size_t i = 0; i < arrayLen(processes); ++i) { @@ -75,14 +73,8 @@ int shell(int in_fd) { setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); - dup2(in_fd, 1); - dup2(in_fd, 2); - - // I don't think the shell should exit on SIG_TERM - if (signal(SIGINT, SIG_IGN) == SIG_ERR) { - perror("Couldn't ignore sigterm"); - exit(errno); - } + dup2(in_fd, STDOUT_FILENO); + dup2(in_fd, STDERR_FILENO); printf("Welcome! Available built-ins are:\n" "cd: `cd ` - if no path is given, return to the current dir\n" @@ -94,12 +86,14 @@ int shell(int in_fd) { ); char const *const original_wd = get_current_dir_name(); + //char const *prompt = relative_path(original_wd, original_wd); bool done = false; while (!done) { char line[BUF_SIZE]; __ssize_t length; + fflush(stdout); if ((length = read(in_fd, line, BUF_SIZE)) < 0) { fprintf(stderr, "Failed to read from STDIN"); fflush(stderr); @@ -112,6 +106,10 @@ int shell(int in_fd) { } line[length - 1] = '\0'; // cut the line feed + if (strlen(line) == 0) { + continue; + } + processes = NULL; parse_line(line, &processes); @@ -154,7 +152,6 @@ int shell(int in_fd) { /*if (ret) printf("[%i] ", ret);*/ } - signal(SIGINT, SIG_IGN); } free_processes(&processes); diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d0441e..5a4192a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) add_subdirectory(02_exercise) +add_subdirectory(03_exercise) set(CLANG_WARNINGS -Wall -- cgit v1.2.3-54-g00ecf From 9629104f494a441681fd28295f98531682875fc7 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sun, 7 Jun 2020 12:51:27 +0200 Subject: put works --- 03_exercise/.srv_pid | 2 +- 03_exercise/cli/client | Bin 28384 -> 28360 bytes 03_exercise/cli/client.c | 41 ++++++++++++++------------- 03_exercise/srv/server.c | 27 ------------------ 03_exercise/srv/shell.c | 72 ++++++++++++++++++++++++++++++++++++----------- 5 files changed, 78 insertions(+), 64 deletions(-) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index ab09251..8dcdde2 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -1493889 +2202992 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 0fcf5c1..34d1d01 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index c1bc5d1..052dabd 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -50,36 +50,38 @@ int write_all(int sock, char *buffer, int size) { } void send_file(int server_fd, char *path) { - char buffer[512]; - int file_fd; - - if ((file_fd = open(path, O_RDONLY)) == -1) { perror("Open"); } - - FILE *file = fdopen(file_fd, "r"); + printf("Trying to send \"%s\" to remote...\n", path); + char buffer[BUF_SIZE]; + memset(buffer, 0, BUF_SIZE); + int tmp_fd, file_fd; + if ((tmp_fd = open(path, O_RDONLY)) == -1) { perror("Open"); } + FILE *file = fdopen(tmp_fd, "r"); fseek(file, 0L, SEEK_END); long int sz = ftell(file); fseek(file, 0L, SEEK_SET); + fclose(file); + close(tmp_fd); + if ((file_fd = open(path, O_RDONLY)) == -1) { perror("Open"); } int length = snprintf(NULL, 0, "%ld", sz); - char msg[length + 1 + 3]; - sprintf(msg, "< 0) { printf("Sent %i bytes\n", write_all(server_fd, buffer, strlen(buffer) + 1)); } - fclose(file); + if (errno) + perror("wad"); + close(file_fd); + + printf("done.\n"); } #define BREAK 1 @@ -143,7 +145,7 @@ int main() { pid_t pid = fork(); int done = 0; - if (pid == 0) { + if (pid != 0) { read_stdin(&done); } else { read_server_sock(&done); @@ -175,6 +177,7 @@ void read_stdin(int *done) { ssize_t length; while (!*done) { + memset(stdinp_buffer, 0, BUF_SIZE); if ((length = read(STDIN_FILENO, stdinp_buffer, BUF_SIZE)) > 0) { switch (parse(sock, stdinp_buffer, length)) { case CONTINUE: diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 8527b83..11f7482 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -49,33 +49,6 @@ int main() { printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); int status = shell(cfd); - /* - while ((bytes = read(sock, in_buf, BUF_SIZE)) != 0) { - if (bytes < 0) - die("Couldn't receive message"); - - //printf("srv: %s\n", in_buf); - - if (strcmp(in_buf, "get") == 0) { - // TODO: implement get - } else if (strcmp(in_buf, "put") == 0) { - // TODO: implement put - } else if (strcmp(in_buf, "ping") == 0) { - strncpy(out_buf, "pong!", sizeof(out_buf)); - } else { - // TODO: connect our shell implementation - memcpy(out_buf, "got: ", sizeof(out_buf)); - memcpy(out_buf + sizeof("got: ") - 1, in_buf, BUF_SIZE - sizeof("got: ") + 1); - } - - if (write(sock, out_buf, sizeof(out_buf)) < 0) - die("Couldn't send message"); - - memset(in_buf, 0, BUF_SIZE); - memset(out_buf, 0, BUF_SIZE); - }*/ - - //printf("srv: closing down\n"); close(cfd); close(sfd); diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 449905b..aea1a68 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -38,24 +38,21 @@ void receive_file(int sock, char *path, int size) { if ((file_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { perror("Open"); } - while (true) { - received = 0; - - /* Read all data */ - while (received < size) { - if ((nread = read(sock, buffer + received, size - received)) < 0) { - perror("Read"); - //pthread_exit(NULL); - exit(1); - } + received = 0; - received += nread; + /* Read all data */ + while (received < size) { + if ((nread = read(sock, buffer + received, size - received)) < 0) { + perror("Read"); + //pthread_exit(NULL); + exit(1); } - if (strncmp(buffer, "end", 4) == 0) { break; } - - write_all(file_fd, buffer, strlen(buffer) + 1); + received += nread; } + + write_all(file_fd, buffer, strlen(buffer) + 1); + close(file_fd); } void signal_handler(int signal) { @@ -69,6 +66,44 @@ void signal_handler(int signal) { } } +bool check_put(char *buffer, int sock) { + // "< Date: Sun, 7 Jun 2020 13:02:54 +0200 Subject: works better? maybe? --- 03_exercise/cli/client | Bin 28360 -> 28360 bytes 03_exercise/cli/client.c | 14 ++++++++++---- 03_exercise/test | Bin 4 -> 5 bytes 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 34d1d01..0935c2b 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 052dabd..e5f2f84 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -55,14 +55,20 @@ void send_file(int server_fd, char *path) { memset(buffer, 0, BUF_SIZE); int tmp_fd, file_fd; - if ((tmp_fd = open(path, O_RDONLY)) == -1) { perror("Open"); } + if ((tmp_fd = open(path, O_RDONLY)) == -1) { + perror("Open"); + return; + } FILE *file = fdopen(tmp_fd, "r"); fseek(file, 0L, SEEK_END); long int sz = ftell(file); fseek(file, 0L, SEEK_SET); fclose(file); close(tmp_fd); - if ((file_fd = open(path, O_RDONLY)) == -1) { perror("Open"); } + if ((file_fd = open(path, O_RDONLY)) == -1) { + perror("Open"); + return; + } int length = snprintf(NULL, 0, "%ld", sz); sprintf(buffer, "< 0) { switch (parse(sock, stdinp_buffer, length)) { case CONTINUE: + printf("$> "); continue; case BREAK: *done = 1; diff --git a/03_exercise/test b/03_exercise/test index eb1ae45..b4098bc 100644 Binary files a/03_exercise/test and b/03_exercise/test differ -- cgit v1.2.3-54-g00ecf From 6333c6510ae56b65a2f36bde55c8618a08260e10 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sun, 7 Jun 2020 15:03:56 +0200 Subject: more fixes --- 03_exercise/cli/client | Bin 28360 -> 28464 bytes 03_exercise/cli/client.c | 9 ++++++--- 03_exercise/srv/shell.c | 12 ++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 0935c2b..c593e95 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index e5f2f84..ea4eda9 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -16,6 +16,7 @@ #define BUF_SIZE 2048 int sock; +pid_t pid; /* Signal Handler for SIGINT */ void sigintHandler(int sig_num) { @@ -26,6 +27,7 @@ void sigintHandler(int sig_num) { } printf("Terminating client\n"); fflush(stdout); + kill(pid, SIGKILL); exit(-1); } @@ -147,10 +149,10 @@ int main() { signal(SIGINT, &sigintHandler); - pid_t pid = fork(); + pid = fork(); int done = 0; - if (pid == 0) { + if (pid != 0) { read_stdin(&done); } else { read_server_sock(&done); @@ -174,6 +176,7 @@ void read_server_sock(int *done) { } } } + kill(pid, SIGKILL); } @@ -186,7 +189,6 @@ void read_stdin(int *done) { if ((length = read(STDIN_FILENO, stdinp_buffer, BUF_SIZE)) > 0) { switch (parse(sock, stdinp_buffer, length)) { case CONTINUE: - printf("$> "); continue; case BREAK: *done = 1; @@ -196,4 +198,5 @@ void read_stdin(int *done) { } } } + kill(pid, SIGKILL); } diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index aea1a68..5d7d33d 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -12,6 +12,8 @@ #include "prompt_utils.h" #include "builtins.h" +char *get_current_dir_name(void); + #define BUF_SIZE 2048 process *processes; @@ -51,7 +53,9 @@ void receive_file(int sock, char *path, int size) { received += nread; } - write_all(file_fd, buffer, strlen(buffer) + 1); + if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { + printf("successfully wrote to remote file \"%s/%s\"\n", get_current_dir_name(), path); + } close(file_fd); } @@ -120,7 +124,7 @@ int shell(int in_fd) { "And with `|` you can pipe the output from one process to the input of another\n" ); - char const *const original_wd = ".";//get_current_dir_name(); + char const *const original_wd = get_current_dir_name(); //char const *prompt = relative_path(original_wd, original_wd); bool done = false; @@ -172,7 +176,7 @@ int shell(int in_fd) { if (ret) printf("[%i] ", ret); else - printf("%s\n", "."/*get_current_dir_name()*/); + printf("%s\n", get_current_dir_name()); } else if (strcmp(processes[0].argv[0], "exit") == 0) { done = true; @@ -197,7 +201,7 @@ int shell(int in_fd) { printf("Disconnecting..."); - //free((void *) original_wd); + free((void *) original_wd); return 0; } -- cgit v1.2.3-54-g00ecf From 0940e27cb8dc9829130e141c599efee780cc4d67 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 10:52:06 +0200 Subject: stuff works, i think --- 03_exercise/cli/client | Bin 28464 -> 30912 bytes 03_exercise/cli/client.c | 284 +++++++++++++++++++++++++++++++---------------- 03_exercise/srv/shell.c | 79 +++++++++++-- 03_exercise/test | Bin 5 -> 0 bytes 4 files changed, 257 insertions(+), 106 deletions(-) delete mode 100644 03_exercise/test diff --git a/03_exercise/cli/client b/03_exercise/cli/client index c593e95..ecaa0d8 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index ea4eda9..f3a4479 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -9,40 +9,201 @@ #include #include #include +#include #define PORT 9000 #define HOST "127.0.0.1" #define BUF_SIZE 2048 -int sock; +#define BREAK 1 +#define CONTINUE 2 + +int server_sock; pid_t pid; /* Signal Handler for SIGINT */ +void sigintHandler(int sig_num); + +static inline void die(char const *msg); + +int write_all(int target_sock, char *buffer, size_t size); + +void send_file(char *path); + +int parse(char *buffer, ssize_t length); + +void read_stdin(); + +_Noreturn void read_server_sock(); + +int main() { + setvbuf(stdout, NULL, _IONBF, 0); + + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(PORT), + .sin_addr.s_addr = inet_addr(HOST) + }; + + if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Could not open socket"); + + if (connect(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) + die("Could not connect to socket"); + + signal(SIGINT, &sigintHandler); + + pid = fork(); + + if (pid != 0) { + read_stdin(); + } else { + read_server_sock(); + } + + close(server_sock); + return 0; +} + +void receive_file(int recv_sock, char *path, int size) { + char buffer[512]; + int file_fd; + int received; + + if ((file_fd = open(path, (O_WRONLY | O_CREAT | O_TRUNC), 0644)) == -1) { perror("Open"); } + + received = 0; + + /* Read all data */ + while (received < size) { + int nread; + if ((nread = read(recv_sock, buffer + received, size - received)) < 0) { + perror("Read"); + //pthread_exit(NULL); + exit(1); + } + + received += nread; + } + + if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { + printf("successfully got remote file \"%s\"\n", path); + } + + close(file_fd); +} + +bool check_get(char *buffer) { + // "< 0) { + server_buffer[length] = '\0'; + + // get issued, as it seems + if (check_get(server_buffer)) { + printf("$> "); + fflush(stdout); + continue; + } + + printf("%s", server_buffer); + if (length == 1 && server_buffer[length - 1] == '\n') { + printf("$> "); + fflush(stdout); + } + } + } +} + +void read_stdin() { + char stdin_buffer[BUF_SIZE]; + + bool done = false; + while (!done) { + ssize_t length; + memset(stdin_buffer, 0, BUF_SIZE); + if ((length = read(STDIN_FILENO, stdin_buffer, BUF_SIZE)) > 0) { + switch (parse(stdin_buffer, length)) { + case CONTINUE: + continue; + case BREAK: + done = true; + break; + default: + break; + } + } + } + kill(pid, SIGKILL); +} + void sigintHandler(int sig_num) { + (void) sig_num; errno = 0; - if (fcntl(sock, F_GETFD) != -1 || errno != EBADF) { - write(sock, "exit\n", 6); - close(sock); + if (fcntl(server_sock, F_GETFD) != -1 || errno != EBADF) { + write(server_sock, "exit\n", 6); + close(server_sock); } - printf("Terminating client\n"); - fflush(stdout); - kill(pid, SIGKILL); - exit(-1); + errno = 0; + die("Terminating client\n"); } -static inline void die(const char *msg) { +static inline void die(char const *msg) { perror(msg); + kill(pid, SIGKILL); exit(-1); } -int write_all(int sock, char *buffer, int size) { - int nwrite, sent = 0; +int write_all(int target_sock, char *buffer, size_t size) { + int sent = 0; while (sent < size) { - if ((nwrite = write(sock, buffer + sent, size - sent)) < 0) { - perror("Write"); - exit(1); + int nwrite; + if ((nwrite = write(target_sock, buffer + sent, size - sent)) < 0) { + die("Write"); } sent += nwrite; @@ -51,7 +212,7 @@ int write_all(int sock, char *buffer, int size) { return sent; } -void send_file(int server_fd, char *path) { +void send_file(char *path) { printf("Trying to send \"%s\" to remote...\n", path); char buffer[BUF_SIZE]; memset(buffer, 0, BUF_SIZE); @@ -72,16 +233,18 @@ void send_file(int server_fd, char *path) { return; } - int length = snprintf(NULL, 0, "%ld", sz); + int length = snprintf(NULL, 0, "%ld", sz); sprintf(buffer, "< 0) { - printf("Sent %i bytes\n", write_all(server_fd, buffer, strlen(buffer) + 1)); + printf("Sent %i bytes\n", write_all(server_sock, buffer, strlen(buffer) + 1)); } if (errno) @@ -92,10 +255,7 @@ void send_file(int server_fd, char *path) { printf("done.\n"); } -#define BREAK 1 -#define CONTINUE 2 - -int parse(int server_sock, char *buffer, ssize_t length) { +int parse(char *buffer, ssize_t length) { char cmd[4]; char path[BUF_SIZE - 3]; memcpy(cmd, buffer, 3); @@ -106,7 +266,7 @@ int parse(int server_sock, char *buffer, ssize_t length) { if (strlen(path) == 0) { fprintf(stderr, "path missing\n"); } else { - send_file(sock, path); + send_file(path); } return CONTINUE; } @@ -121,82 +281,10 @@ int parse(int server_sock, char *buffer, ssize_t length) { if (write(server_sock, buffer, strlen(buffer)) < 0) die("Could not send message"); + // TODO: exit should only close the connection (cleanly), NOT terminate the server if (strcmp(buffer, "exit\n") == 0) { return BREAK; } return 0; -} - -void read_stdin(int *done); - -void read_server_sock(int *done); - -int main() { - setvbuf(stdout, NULL, _IONBF, 0); - - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(PORT), - .sin_addr.s_addr = inet_addr(HOST) - }; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - die("Could not open socket"); - - if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) - die("Could not connect to socket"); - - signal(SIGINT, &sigintHandler); - - pid = fork(); - - int done = 0; - if (pid != 0) { - read_stdin(&done); - } else { - read_server_sock(&done); - } - - close(sock); - return 0; -} - -void read_server_sock(int *done) { - char server_buffer[BUF_SIZE]; - ssize_t length; - - while (!*done) { - if ((length = read(sock, server_buffer, BUF_SIZE)) > 0) { - server_buffer[length] = '\0'; - printf("%s", server_buffer); - if (server_buffer[length - 1] == '\n') { - printf("$> "); - fflush(stdout); - } - } - } - kill(pid, SIGKILL); -} - - -void read_stdin(int *done) { - char stdinp_buffer[BUF_SIZE]; - ssize_t length; - - while (!*done) { - memset(stdinp_buffer, 0, BUF_SIZE); - if ((length = read(STDIN_FILENO, stdinp_buffer, BUF_SIZE)) > 0) { - switch (parse(sock, stdinp_buffer, length)) { - case CONTINUE: - continue; - case BREAK: - *done = 1; - break; - default: - break; - } - } - } - kill(pid, SIGKILL); -} +} \ No newline at end of file diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 5d7d33d..7a90945 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -18,13 +18,13 @@ char *get_current_dir_name(void); process *processes; -int write_all(int sock, char *buffer, int size) { +int write_all(int target_sock, char *buffer, size_t size) { int nwrite, sent = 0; while (sent < size) { - if ((nwrite = write(sock, buffer + sent, size - sent)) < 0) { + if ((nwrite = write(target_sock, buffer + sent, size - sent)) < 0) { perror("Write"); - exit(1); + return -1; } sent += nwrite; @@ -54,11 +54,60 @@ void receive_file(int sock, char *path, int size) { } if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { - printf("successfully wrote to remote file \"%s/%s\"\n", get_current_dir_name(), path); + printf("successfully wrote to remote file \"%s/%s\"", get_current_dir_name(), path); + printf("\n"); + } else { + printf("error writing remote file \"%s/%s\"", get_current_dir_name(), path); + printf("\n"); } + close(file_fd); } +void send_file(int client_fd, char *path) { + printf("Trying to get \"%s\" from remote...\n", path); + char buffer[BUF_SIZE]; + memset(buffer, 0, BUF_SIZE); + int tmp_fd, file_fd; + + if ((tmp_fd = open(path, O_RDONLY)) == -1) { + perror("Open"); + return; + } + FILE *file = fdopen(tmp_fd, "r"); + fseek(file, 0L, SEEK_END); + long int sz = ftell(file); + fseek(file, 0L, SEEK_SET); + fclose(file); + close(tmp_fd); + if ((file_fd = open(path, O_RDONLY)) == -1) { + perror("Open"); + return; + } + + int length = snprintf(NULL, 0, "%ld", sz); + sprintf(buffer, "< 0) { + /*printf("Sent %i bytes\n", */write_all(client_fd, buffer, strlen(buffer) + 1)/*)*/; + } + + if (errno) + perror("wad"); + + close(file_fd); + + //printf("done.\n"); +} + void signal_handler(int signal) { if (signal == SIGINT) { for (size_t i = 0; i < arrayLen(processes); ++i) { @@ -121,8 +170,9 @@ int shell(int in_fd) { "fg: `fg pid` - pulls a process from the background back in the foreground\n" "\n" "You can put processes in the background using `&`\n" - "And with `|` you can pipe the output from one process to the input of another\n" + "And with `|` you can pipe the output from one process to the input of another" ); + printf("\n$> "); char const *const original_wd = get_current_dir_name(); //char const *prompt = relative_path(original_wd, original_wd); @@ -158,6 +208,7 @@ int shell(int in_fd) { if (strcmp(processes[0].argv[0], "cd") == 0) { if (arrayLen(processes) != 1) { perror("Can't chain cd with other processes"); + printf("\n"); } int ret; switch (arrayLen(processes[0].argv)) { @@ -168,18 +219,28 @@ int shell(int in_fd) { ret = chdir(original_wd); break; default: - fprintf(stderr, "usage: cd \n"); + fprintf(stderr, "usage: cd "); + fprintf(stderr, "\n"); fflush(stderr); ret = -1; } if (ret) printf("[%i] ", ret); - else - printf("%s\n", get_current_dir_name()); + else { + printf("%s", get_current_dir_name()); + printf("\n"); + } } else if (strcmp(processes[0].argv[0], "exit") == 0) { done = true; + } else if (strcmp(processes[0].argv[0], "get") == 0) { + if (arrayLen(processes[0].argv) != 3) { + printf("please provide a file name to get!"); + printf("\n"); + } else { + send_file(in_fd, processes[0].argv[1]); + } } else if (strcmp(processes[0].argv[0], "wait") == 0) { builtin_wait(processes[0], false); } else if (strcmp(processes[0].argv[0], "fg") == 0) { @@ -194,12 +255,14 @@ int shell(int in_fd) { /*if (ret) printf("[%i] ", ret);*/ } + printf("\n"); } free_processes(&processes); } printf("Disconnecting..."); + printf("\n"); free((void *) original_wd); diff --git a/03_exercise/test b/03_exercise/test deleted file mode 100644 index b4098bc..0000000 Binary files a/03_exercise/test and /dev/null differ -- cgit v1.2.3-54-g00ecf From 685d32641209b2671b154f52046d6bfd63bd9531 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 13:24:09 +0200 Subject: put und get gehen, jetzt sogar wirklich, glaube ich --- 03_exercise/cli/client | Bin 30912 -> 31152 bytes 03_exercise/cli/client.c | 41 +++++++++++++++++++++++++++-------------- 03_exercise/srv/shell.c | 37 ++++++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index ecaa0d8..56618d6 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index f3a4479..9ae6c0a 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -19,6 +19,8 @@ #define BREAK 1 #define CONTINUE 2 +char *get_current_dir_name(void); + int server_sock; pid_t pid; @@ -56,39 +58,50 @@ int main() { pid = fork(); - if (pid != 0) { + if (pid == 0) { read_stdin(); } else { read_server_sock(); } close(server_sock); + kill(pid, SIGKILL); + return 0; } void receive_file(int recv_sock, char *path, int size) { - char buffer[512]; + char buffer[BUF_SIZE]; int file_fd; int received; if ((file_fd = open(path, (O_WRONLY | O_CREAT | O_TRUNC), 0644)) == -1) { perror("Open"); } + if (size == 0) { + // just touch + close(file_fd); + return; + } + received = 0; /* Read all data */ while (received < size) { int nread; - if ((nread = read(recv_sock, buffer + received, size - received)) < 0) { - perror("Read"); - //pthread_exit(NULL); - exit(1); + if ((nread = read(recv_sock, buffer, BUF_SIZE)) > 0) { + if (write_all(file_fd, buffer, nread) != nread) { + break; + } + received += nread; } - - received += nread; } - if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { - printf("successfully got remote file \"%s\"\n", path); + if (received == size) { + printf("successfully got remote file \"%s/%s\"", get_current_dir_name(), path); + printf("\n"); + } else { + printf("error getting remote file \"%s/%s\"", get_current_dir_name(), path); + printf("\n"); } close(file_fd); @@ -102,7 +115,7 @@ bool check_get(char *buffer) { cmd[3] = 0; if (strcmp(cmd, "< 0) { - printf("Sent %i bytes\n", write_all(server_sock, buffer, strlen(buffer) + 1)); + size_t count; + while ((count = read(file_fd, buffer, sizeof(buffer))) > 0) { + printf("Sent %i bytes\n", write_all(server_sock, buffer, count)); } if (errno) diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 7a90945..cd053b6 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -33,31 +33,37 @@ int write_all(int target_sock, char *buffer, size_t size) { return sent; } -void receive_file(int sock, char *path, int size) { - char buffer[512]; +void receive_file(int recv_sock, char *path, int size) { + char buffer[BUF_SIZE]; int file_fd; - int nread, received; + int received; + + if ((file_fd = open(path, (O_WRONLY | O_CREAT | O_TRUNC), 0644)) == -1) { perror("Open"); } - if ((file_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { perror("Open"); } + if (size == 0) { + // just touch + close(file_fd); + return; + } received = 0; /* Read all data */ while (received < size) { - if ((nread = read(sock, buffer + received, size - received)) < 0) { - perror("Read"); - //pthread_exit(NULL); - exit(1); + int nread; + if ((nread = read(recv_sock, buffer, BUF_SIZE)) > 0) { + if (write_all(file_fd, buffer, nread) != nread) { + break; + } + received += nread; } - - received += nread; } - if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { - printf("successfully wrote to remote file \"%s/%s\"", get_current_dir_name(), path); + if (received == size) { + printf("successfully wrote to remote file \"%s/%s\"\n", get_current_dir_name(), path); printf("\n"); } else { - printf("error writing remote file \"%s/%s\"", get_current_dir_name(), path); + printf("error writing remote file \"%s/%s\"\n", get_current_dir_name(), path); printf("\n"); } @@ -96,8 +102,9 @@ void send_file(int client_fd, char *path) { memset(buffer, 0, BUF_SIZE); errno = 0; - while (read(file_fd, buffer, sizeof(buffer)) > 0) { - /*printf("Sent %i bytes\n", */write_all(client_fd, buffer, strlen(buffer) + 1)/*)*/; + size_t count; + while ((count = read(file_fd, buffer, sizeof(buffer))) > 0) { + /*printf("Sent %i bytes\n", */write_all(client_fd, buffer, count)/*)*/; } if (errno) -- cgit v1.2.3-54-g00ecf From fb3b792ba17afb41e9662fd3b60492f0c12fa0f0 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 13:38:05 +0200 Subject: first kinda ready stand, with comment in shell.c explaining a bit --- 03_exercise/srv/shell.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index cd053b6..b93030f 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -12,6 +12,23 @@ #include "prompt_utils.h" #include "builtins.h" +/* + * READ ME + * sorry für den unaufgeräumten Code hier :/ + * + * What works: + * - remote shell, weitesgehend die funktionalität der vorhergehenden aufgabe (damit auch pipes und background, + * auch wenn wir das nicht ausführlich getestet haben) + * - get und put für dateien + * What doesn't work: + * - mehrere clients an einem server + * Known bugs: + * - exit beendet nicht nur die client-server connection und setzt den server wieder in einen wartenden zustand, + * sondern terminiert ebenfalls den server + * - das erkennen, wann eine neue prompt geprintet werden muss ist aktuell sehr hacky client seitig implementiert, + * scheitert teilweise - die eingabe geht trzd ganz normal, es wird nur keine prompt angezeigt + */ + char *get_current_dir_name(void); #define BUF_SIZE 2048 @@ -24,6 +41,7 @@ int write_all(int target_sock, char *buffer, size_t size) { while (sent < size) { if ((nwrite = write(target_sock, buffer + sent, size - sent)) < 0) { perror("Write"); + printf("\n"); return -1; } @@ -38,7 +56,10 @@ void receive_file(int recv_sock, char *path, int size) { int file_fd; int received; - if ((file_fd = open(path, (O_WRONLY | O_CREAT | O_TRUNC), 0644)) == -1) { perror("Open"); } + if ((file_fd = open(path, (O_WRONLY | O_CREAT | O_TRUNC), 0644)) == -1) { + perror("Open"); + printf("\n"); + } if (size == 0) { // just touch @@ -78,6 +99,7 @@ void send_file(int client_fd, char *path) { if ((tmp_fd = open(path, O_RDONLY)) == -1) { perror("Open"); + printf("\n"); return; } FILE *file = fdopen(tmp_fd, "r"); @@ -88,10 +110,11 @@ void send_file(int client_fd, char *path) { close(tmp_fd); if ((file_fd = open(path, O_RDONLY)) == -1) { perror("Open"); + printf("\n"); return; } - int length = snprintf(NULL, 0, "%ld", sz); + int length = snprintf(NULL, 0, "%ld", sz); sprintf(buffer, "< Date: Mon, 8 Jun 2020 13:43:03 +0200 Subject: fixes --- 03_exercise/cli/client.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 9ae6c0a..dbec3eb 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -196,7 +196,7 @@ void sigintHandler(int sig_num) { (void) sig_num; errno = 0; if (fcntl(server_sock, F_GETFD) != -1 || errno != EBADF) { - write(server_sock, "exit\n", 6); + (void) write(server_sock, "exit\n", 6); close(server_sock); } errno = 0; @@ -251,7 +251,10 @@ void send_file(char *path) { printf("[c] \"%s\"\n", buffer); - write(server_sock, buffer, strlen(buffer)); + if (write(server_sock, buffer, strlen(buffer)) != strlen(buffer)) { + perror("write header"); + return; + } memset(buffer, 0, BUF_SIZE); errno = 0; -- cgit v1.2.3-54-g00ecf From 8da29ff1661c8ad5bcaf136648159ba4efbea0a8 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 13:44:44 +0200 Subject: 2 fliegen mit einer klappe? --- 03_exercise/cli/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index dbec3eb..67731f4 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -193,10 +193,10 @@ void read_stdin() { } void sigintHandler(int sig_num) { - (void) sig_num; errno = 0; if (fcntl(server_sock, F_GETFD) != -1 || errno != EBADF) { - (void) write(server_sock, "exit\n", 6); + sig_num = write(server_sock, "exit\n", 6); + (void) sig_num; close(server_sock); } errno = 0; -- cgit v1.2.3-54-g00ecf From c63acb5f04dfb3667e2de6d752e08ffb658b46b8 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 13:45:54 +0200 Subject: fixes2 --- 03_exercise/srv/shell.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index b93030f..38c5f9d 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -118,7 +118,10 @@ void send_file(int client_fd, char *path) { sprintf(buffer, "< Date: Mon, 8 Jun 2020 14:54:40 +0200 Subject: some changes in the vm --- 02_exercise/CMakeLists.txt | 2 -- 03_exercise/CMakeLists.txt | 3 --- 03_exercise/cli/client | Bin 31152 -> 35192 bytes 03_exercise/cli/client.c | 16 +++++++++++++--- 03_exercise/srv/shell.c | 4 ++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/02_exercise/CMakeLists.txt b/02_exercise/CMakeLists.txt index 82df5d5..c5ef1e1 100644 --- a/02_exercise/CMakeLists.txt +++ b/02_exercise/CMakeLists.txt @@ -7,7 +7,6 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED True) add_compile_definitions(_GNU_SOURCE) - find_package(Sanitizers) add_executable(prog prog.c) @@ -15,7 +14,6 @@ add_executable(prog prog.c) add_executable(shell shell.c) target_link_libraries(shell PRIVATE array prompt_utils process builtin) target_compile_options(shell INTERFACE ${PROJECT_WARNINGS}) -add_sanitizers(shell) add_library(builtin builtins.c) target_compile_options(builtin INTERFACE ${PROJECT_WARNINGS}) diff --git a/03_exercise/CMakeLists.txt b/03_exercise/CMakeLists.txt index a03d39b..e72de65 100644 --- a/03_exercise/CMakeLists.txt +++ b/03_exercise/CMakeLists.txt @@ -14,6 +14,3 @@ add_executable(server srv/prompt_utils.c srv/array.c srv/shell.c srv/process.c s target_compile_options(client INTERFACE ${PROJECT_WARNINGS}) target_compile_options(server INTERFACE ${PROJECT_WARNINGS}) - -add_sanitizers(client) -add_sanitizers(server) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 56618d6..4450079 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 67731f4..22f4e61 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -70,7 +70,7 @@ int main() { return 0; } -void receive_file(int recv_sock, char *path, int size) { +void receive_file(int recv_sock, char *path, size_t size, char *start_buf, size_t start_buf_len) { char buffer[BUF_SIZE]; int file_fd; int received; @@ -85,6 +85,17 @@ void receive_file(int recv_sock, char *path, int size) { received = 0; + if (start_buf) { + // there was part of the file already in the "packet" which was supposed to contain only the header + // put that into the file too + if (write_all(file_fd, start_buf, start_buf_len) != start_buf_len) { + perror("write start buf"); + printf("\n"); + return; + } + received += start_buf_len; + } + /* Read all data */ while (received < size) { int nread; @@ -138,9 +149,8 @@ bool check_get(char *buffer) { char path[strlen(rest) + 1]; memcpy(path, rest, strlen(rest)); path[strlen(rest)] = 0; - path[strlen(rest) - 1] = 0; - receive_file(server_sock, path, file_size); + receive_file(server_sock, path, file_size, &(buffer[i+2]), strlen(&(buffer[i+2]))); return true; } diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 38c5f9d..0419f35 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -116,14 +116,14 @@ void send_file(int client_fd, char *path) { int length = snprintf(NULL, 0, "%ld", sz); sprintf(buffer, "< Date: Mon, 8 Jun 2020 14:56:34 +0200 Subject: force flush after header write --- 03_exercise/srv/shell.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 0419f35..95c9982 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include #include "array.h" #include "process.h" @@ -123,7 +126,12 @@ void send_file(int client_fd, char *path) { return; } - usleep(250); + int flag = 1; + // force flush + setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); + flag = 0; + + usleep(150); memset(buffer, 0, BUF_SIZE); @@ -156,16 +164,16 @@ void signal_handler(int signal) { bool check_put(char *buffer, int sock) { // "< Date: Mon, 8 Jun 2020 15:02:03 +0200 Subject: seems to work now --- 03_exercise/srv/shell.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 95c9982..686b169 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include #include -- cgit v1.2.3-54-g00ecf From 7ab92ebb3424e904ee78862683eb65fb60d878f6 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 17:30:18 +0200 Subject: multiple clients --- 03_exercise/.srv_pid | 2 +- 03_exercise/cli/client | Bin 35192 -> 31992 bytes 03_exercise/srv/server.c | 62 +++++++++++++++++++++++++++++++++++------------ 03_exercise/srv/shell.c | 27 ++++----------------- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index 8dcdde2..156e8ad 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -2202992 +341971 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 4450079..95db5c3 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 11f7482..67fe21c 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -9,6 +9,18 @@ #include "shell.h" +/* + * READ ME + * What works: + * - remote shell, weitesgehend die funktionalität der vorhergehenden aufgabe (damit auch pipes und background, + * auch wenn wir das nicht ausführlich getestet haben) + * - get und put für dateien + * - mehrere clients an einem server + * Known bugs: + * - das erkennen, wann eine neue prompt geprintet werden muss ist aktuell sehr hacky client-seitig implementiert, + * scheitert teilweise - die eingabe geht trzd ganz normal, es wird nur keine prompt angezeigt + */ + #define PORT 9000 #define BUF_SIZE 256 @@ -19,13 +31,13 @@ static inline void die(const char *msg) { } int main() { + setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + struct sockaddr_in srv_addr, cli_addr; - int sockopt = 1; - socklen_t sad_sz = sizeof(struct sockaddr_in); - int sfd, cfd; - /*ssize_t bytes; - char in_buf[BUF_SIZE]; - char out_buf[BUF_SIZE];*/ + int sockopt = 1; + socklen_t sad_sz = sizeof(struct sockaddr_in); + int sfd; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(PORT); @@ -42,16 +54,36 @@ int main() { if (listen(sfd, 1) < 0) die("Could not listen on socket"); - cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); - if (cfd < 0) - die("Could not accept incoming connection"); - - printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); - - int status = shell(cfd); + while (1) { + int cfd, pid; + cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); + if (cfd < 0) { + perror("Could not accept incoming connection"); + break; + } + + // fork new process + pid = fork(); + if (pid < 0) { + perror("ERROR in new process creation"); + } + + if (pid == 0) { + // child process + close(sfd); + + printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); + int status = shell(cfd); + fprintf(stdout, "srv: client disconnected: %s (%d)\n", inet_ntoa(cli_addr.sin_addr), status); + fflush(stdout); + close(cfd); + } else { + // parent process + close(cfd); + } + } - close(cfd); close(sfd); - return status; + return 0; } diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 686b169..c7155c6 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -13,26 +13,8 @@ #include "array.h" #include "process.h" -#include "prompt_utils.h" #include "builtins.h" -/* - * READ ME - * sorry für den unaufgeräumten Code hier :/ - * - * What works: - * - remote shell, weitesgehend die funktionalität der vorhergehenden aufgabe (damit auch pipes und background, - * auch wenn wir das nicht ausführlich getestet haben) - * - get und put für dateien - * What doesn't work: - * - mehrere clients an einem server - * Known bugs: - * - exit beendet nicht nur die client-server connection und setzt den server wieder in einen wartenden zustand, - * sondern terminiert ebenfalls den server - * - das erkennen, wann eine neue prompt geprintet werden muss ist aktuell sehr hacky client seitig implementiert, - * scheitert teilweise - die eingabe geht trzd ganz normal, es wird nur keine prompt angezeigt - */ - char *get_current_dir_name(void); #define BUF_SIZE 2048 @@ -202,8 +184,8 @@ bool check_put(char *buffer, int sock) { } int shell(int in_fd) { - setvbuf(stderr, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); + int stdoutCopy = dup(STDOUT_FILENO); + int stderrCopy = dup(STDERR_FILENO); dup2(in_fd, STDOUT_FILENO); dup2(in_fd, STDERR_FILENO); @@ -305,8 +287,9 @@ int shell(int in_fd) { free_processes(&processes); } - printf("Disconnecting..."); - printf("\n"); + // reset output + dup2(STDOUT_FILENO, stdoutCopy); + dup2(STDERR_FILENO, stderrCopy); free((void *) original_wd); -- cgit v1.2.3-54-g00ecf From 3c13b7ad6bc7a1a3b84d27c8c9fd4c8da1d2112f Mon Sep 17 00:00:00 2001 From: vm Date: Mon, 8 Jun 2020 17:43:47 +0200 Subject: get works again? --- 02_exercise/CMakeLists.txt | 2 -- 03_exercise/.srv_pid | 2 +- 03_exercise/CMakeLists.txt | 4 +-- 03_exercise/cli/client | Bin 31992 -> 35192 bytes 03_exercise/echo_server/Makefile | 22 ---------------- 03_exercise/echo_server/client.c | 47 ---------------------------------- 03_exercise/echo_server/server.c | 53 --------------------------------------- 03_exercise/srv/shell.c | 11 ++++++-- 8 files changed, 11 insertions(+), 130 deletions(-) delete mode 100644 03_exercise/echo_server/Makefile delete mode 100644 03_exercise/echo_server/client.c delete mode 100644 03_exercise/echo_server/server.c diff --git a/02_exercise/CMakeLists.txt b/02_exercise/CMakeLists.txt index c5ef1e1..6bc45c6 100644 --- a/02_exercise/CMakeLists.txt +++ b/02_exercise/CMakeLists.txt @@ -7,8 +7,6 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED True) add_compile_definitions(_GNU_SOURCE) -find_package(Sanitizers) - add_executable(prog prog.c) add_executable(shell shell.c) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index 156e8ad..af9bc34 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -341971 +4125 diff --git a/03_exercise/CMakeLists.txt b/03_exercise/CMakeLists.txt index e72de65..aaac1eb 100644 --- a/03_exercise/CMakeLists.txt +++ b/03_exercise/CMakeLists.txt @@ -7,10 +7,8 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED True) add_compile_definitions(_GNU_SOURCE) -find_package(Sanitizers) - add_executable(client cli/client.c) add_executable(server srv/prompt_utils.c srv/array.c srv/shell.c srv/process.c srv/server.c srv/builtins.c) target_compile_options(client INTERFACE ${PROJECT_WARNINGS}) -target_compile_options(server INTERFACE ${PROJECT_WARNINGS}) +target_compile_options(server INTERFACE ${PROJECT_WARNINGS}) \ No newline at end of file diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 95db5c3..4450079 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/echo_server/Makefile b/03_exercise/echo_server/Makefile deleted file mode 100644 index df023d1..0000000 --- a/03_exercise/echo_server/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/make -.SUFFIXES: -.PHONY: all run clean -.SILENT: run - -TAR = client server -CFLAGS = -c -Os -Wall -Werror - -%.o: %.c - $(CC) $(CFLAGS) $^ -o $@ - -%: %.o - $(CC) -o $@ $^ - -all: $(TAR) - -run: all - ./server& - ./client - -clean: - $(RM) $(RMFILES) $(TAR) *.o diff --git a/03_exercise/echo_server/client.c b/03_exercise/echo_server/client.c deleted file mode 100644 index a664221..0000000 --- a/03_exercise/echo_server/client.c +++ /dev/null @@ -1,47 +0,0 @@ - -#include -#include - -#include -#include -#include -#include - -static inline void die(const char* msg) -{ - perror(msg); - exit(-1); -} - -int main() -{ - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(8000), - .sin_addr.s_addr = inet_addr("127.0.0.1") - }; - char buf[256]; - int cfd; - - if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - die("Couldn't open the socket"); - - if (connect(cfd, (struct sockaddr*) &addr, sizeof(addr)) < 0) - die("Couldn't connect to socket"); - - for (int i = 0; i < 5; ++i) - { - if (write(cfd, "Ping", 4) < 0) - die("Couldn't send message"); - - printf("[send] Ping\n"); - - if (read(cfd, buf, sizeof(buf)) < 0) - die("Couldn't receive message"); - - printf("[recv] %s\n", buf); - } - - close(cfd); - return 0; -} diff --git a/03_exercise/echo_server/server.c b/03_exercise/echo_server/server.c deleted file mode 100644 index 5f647c1..0000000 --- a/03_exercise/echo_server/server.c +++ /dev/null @@ -1,53 +0,0 @@ - -#include -#include - -#include -#include -#include -#include - -static inline void die(const char *msg) { - perror(msg); - exit(-1); -} - -int main() { - struct sockaddr_in srv_addr, cli_addr; - int sockopt = 1; - socklen_t sad_sz = sizeof(struct sockaddr_in); - int sfd, cfd; - ssize_t bytes; - char buf[256]; - - srv_addr.sin_family = AF_INET; - srv_addr.sin_port = htons(8000); - srv_addr.sin_addr.s_addr = INADDR_ANY; - - if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - die("Couldn't open the socket"); - - setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sockopt, sizeof(sockopt)); - - if (bind(sfd, (struct sockaddr *) &srv_addr, sad_sz) < 0) - die("Couldn't bind socket"); - - if (listen(sfd, 1) < 0) - die("Couldn't listen to the socket"); - - cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); - if (cfd < 0) - die("Couldn't accept incoming connection"); - - while ((bytes = read(cfd, buf, sizeof(buf))) != 0) { - if (bytes < 0) - die("Couldn't receive message"); - - if (write(cfd, buf, bytes) < 0) - die("Couldn't send message"); - } - - close(cfd); - close(sfd); - return 0; -} diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index c7155c6..74c492b 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -100,6 +100,13 @@ void send_file(int client_fd, char *path) { return; } + int flag = 1; + // force flush + flag = 1; + setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); + flag = 0; + setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); + int length = snprintf(NULL, 0, "%ld", sz); sprintf(buffer, "< Date: Mon, 8 Jun 2020 17:53:34 +0200 Subject: fixed stuff --- 03_exercise/.srv_pid | 2 +- 03_exercise/cli/client | Bin 35192 -> 35352 bytes 03_exercise/cli/client.c | 1 + 03_exercise/srv/shell.c | 3 +++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index af9bc34..d344ba0 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -4125 +5015 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 4450079..208702c 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index 22f4e61..e42151a 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -301,6 +301,7 @@ int parse(char *buffer, ssize_t length) { if (strspn(buffer, " \n\t") == strlen(buffer)) { // skip empty lines - empty being just spaces or tabs + printf("$> "); return CONTINUE; } diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 74c492b..b956d3c 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -111,13 +111,16 @@ void send_file(int client_fd, char *path) { sprintf(buffer, "< Date: Mon, 8 Jun 2020 17:58:31 +0200 Subject: removed an extra debug statement --- 03_exercise/cli/client | Bin 35352 -> 0 bytes 03_exercise/cli/client.c | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100755 03_exercise/cli/client diff --git a/03_exercise/cli/client b/03_exercise/cli/client deleted file mode 100755 index 208702c..0000000 Binary files a/03_exercise/cli/client and /dev/null differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index e42151a..6447034 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -259,7 +259,7 @@ void send_file(char *path) { sprintf(buffer, "< Date: Mon, 8 Jun 2020 18:03:46 +0200 Subject: packed on vm --- 03_exercise/lab-3.zip | Bin 0 -> 29468 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 03_exercise/lab-3.zip diff --git a/03_exercise/lab-3.zip b/03_exercise/lab-3.zip new file mode 100644 index 0000000..67f99a9 Binary files /dev/null and b/03_exercise/lab-3.zip differ -- cgit v1.2.3-54-g00ecf