From b89a3ed932cd3fadb3a726643b8c1fda94f73412 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 19 Jun 2025 16:45:14 -0600 Subject: [PATCH 01/41] Initial commit --- Makefile | 0 main.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Makefile create mode 100644 main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/main.c b/main.c new file mode 100644 index 0000000..e69de29 From 45e289dd3ac31a3311d1622ecce14828c6b751fd Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Fri, 20 Jun 2025 16:34:53 -0600 Subject: [PATCH 02/41] added basic single threaded program --- Makefile | 12 +++++ main.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) diff --git a/Makefile b/Makefile index e69de29..1bf9676 100644 --- a/Makefile +++ b/Makefile @@ -0,0 +1,12 @@ +CC = gcc +CFLAGS = -g +CPPFLAGS = -Wall -Wextra -pedantic -std=gnu90 + +chatty: main.o + $(CC) $(CFLAGS) -o chatty main.o -lpthread + +main.o: main.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o main.o main.c + +clean: + rm -f *.o chatty diff --git a/main.c b/main.c index e69de29..78149dd 100644 --- a/main.c +++ b/main.c @@ -0,0 +1,133 @@ +/* + * A simple chat program by Dane MacFadden + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXBUFSIZE 30 + +/* Socket variables */ +int socketfd, socketfd_send; + +/* Address info */ +struct addrinfo hints, remote_hints; +struct addrinfo *servinfo, *remote_servinfo; /* points to results */ + +char *remote_machine, *local_port, *remote_port; + +void *input(void *arg) { + printf("Thread made it!\n"); + //while (1) { + /* + * Accept input + */ + //} + return 0; +} + +int main(int argc, char* argv[]) { + pthread_t input_thread; + char *msg = "Test"; + struct addrinfo *p, *q; + int status; +/* + if (argc != 4) { + printf("Wrong number of arguments\n"); + return -1; + } +*/ + + local_port = argv[1]; + remote_machine = argv[2]; + remote_port = argv[3]; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + if ((status = getaddrinfo(NULL, local_port, &hints, &servinfo)) != 0) { + fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); + exit(1); + } + + /* Create socket */ + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((socketfd = socket(p->ai_family, + p->ai_socktype, + p->ai_protocol)) == -1) { + perror("listener: socket"); + continue; + } + + /* Set socket to nonblocking */ + fcntl(socketfd, F_SETFL, O_NONBLOCK); + + /* Bind */ + if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { + close(socketfd); + perror("listener: bind"); + continue; + } + + break; + } + if (p == NULL) { + fprintf(stderr, "listener: failed to bind socket\n"); + return 2; + } + else { + servinfo = p; + } + + /* Get remote info */ + memset(&remote_hints, 0, sizeof(remote_hints)); + remote_hints.ai_family = AF_INET; + remote_hints.ai_socktype = SOCK_DGRAM; + + if ((status = getaddrinfo(remote_machine, remote_port, &remote_hints, + &remote_servinfo)) != 0) { + fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); + exit(1); + } + for (q = remote_servinfo; q != NULL; q = q->ai_next) { + /* Create socket */ + if ((socketfd_send = socket(q->ai_family, + q->ai_socktype, + q->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + + break; + } + + if (q == NULL) { + fprintf(stderr, "talker: failed to create socket\n"); + return 2; + } + else { + remote_servinfo = q; + } + + + pthread_create(&input_thread, NULL, input, (void*) msg); + + pthread_join(input_thread, NULL); + return 0; +} + From 4d56ad394c039967de1dc235148484d9fd4ad304 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Fri, 20 Jun 2025 20:44:20 -0600 Subject: [PATCH 03/41] changed to TCP --- main.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/main.c b/main.c index 78149dd..e52ee02 100644 --- a/main.c +++ b/main.c @@ -20,36 +20,37 @@ #define MAXBUFSIZE 30 -/* Socket variables */ int socketfd, socketfd_send; -/* Address info */ struct addrinfo hints, remote_hints; -struct addrinfo *servinfo, *remote_servinfo; /* points to results */ +struct addrinfo *servinfo, *remote_servinfo; char *remote_machine, *local_port, *remote_port; void *input(void *arg) { - printf("Thread made it!\n"); - //while (1) { + while (1) { /* * Accept input */ - //} + } return 0; } +void *sender(void *arg) { + return 0; +} + int main(int argc, char* argv[]) { - pthread_t input_thread; - char *msg = "Test"; + pthread_t input_thread, send_thread, receive_thread; + char *msg; struct addrinfo *p, *q; - int status; -/* + int status; + int yes = 1; + if (argc != 4) { printf("Wrong number of arguments\n"); return -1; } -*/ local_port = argv[1]; remote_machine = argv[2]; @@ -57,10 +58,10 @@ int main(int argc, char* argv[]) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; + hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - if ((status = getaddrinfo(NULL, local_port, &hints, &servinfo)) != 0) { + if ((status = getaddrinfo(remote_machine, local_port, &hints, &servinfo)) != 0) { fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); exit(1); } @@ -74,9 +75,6 @@ int main(int argc, char* argv[]) { continue; } - /* Set socket to nonblocking */ - fcntl(socketfd, F_SETFL, O_NONBLOCK); - /* Bind */ if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { close(socketfd); @@ -97,7 +95,7 @@ int main(int argc, char* argv[]) { /* Get remote info */ memset(&remote_hints, 0, sizeof(remote_hints)); remote_hints.ai_family = AF_INET; - remote_hints.ai_socktype = SOCK_DGRAM; + remote_hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(remote_machine, remote_port, &remote_hints, &remote_servinfo)) != 0) { From 1ebfafa0d16739f63f1f6effbb3bdfd644c3de7a Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Fri, 20 Jun 2025 22:51:25 -0600 Subject: [PATCH 04/41] added logic to determine who's client and who's server --- main.c | 127 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/main.c b/main.c index e52ee02..5cce76f 100644 --- a/main.c +++ b/main.c @@ -20,7 +20,7 @@ #define MAXBUFSIZE 30 -int socketfd, socketfd_send; +int socketfd; struct addrinfo hints, remote_hints; struct addrinfo *servinfo, *remote_servinfo; @@ -56,72 +56,81 @@ int main(int argc, char* argv[]) { remote_machine = argv[2]; remote_port = argv[3]; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; + if (atoi(local_port) < atoi(remote_port)) { + /* Congrats, you're the server */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; - if ((status = getaddrinfo(remote_machine, local_port, &hints, &servinfo)) != 0) { - fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); - exit(1); - } - - /* Create socket */ - for (p = servinfo; p != NULL; p = p->ai_next) { - if ((socketfd = socket(p->ai_family, - p->ai_socktype, - p->ai_protocol)) == -1) { - perror("listener: socket"); - continue; + if ((status = getaddrinfo(NULL, local_port, &hints, &servinfo)) != 0) { + fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); + exit(1); } - - /* Bind */ - if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { - close(socketfd); - perror("listener: bind"); - continue; - } - - break; - } - if (p == NULL) { - fprintf(stderr, "listener: failed to bind socket\n"); - return 2; - } - else { - servinfo = p; - } - - /* Get remote info */ - memset(&remote_hints, 0, sizeof(remote_hints)); - remote_hints.ai_family = AF_INET; - remote_hints.ai_socktype = SOCK_STREAM; - - if ((status = getaddrinfo(remote_machine, remote_port, &remote_hints, - &remote_servinfo)) != 0) { - fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); - exit(1); - } - for (q = remote_servinfo; q != NULL; q = q->ai_next) { + /* Create socket */ - if ((socketfd_send = socket(q->ai_family, - q->ai_socktype, - q->ai_protocol)) == -1) { - perror("talker: socket"); - continue; + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((socketfd = socket(p->ai_family, + p->ai_socktype, + p->ai_protocol)) == -1) { + perror("listener: socket"); + continue; + } + + /* Bind */ + if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { + close(socketfd); + perror("listener: bind"); + continue; + } + + break; + } + if (p == NULL) { + fprintf(stderr, "listener: failed to bind socket\n"); + return 2; + } + else { + servinfo = p; } - - break; - } - - if (q == NULL) { - fprintf(stderr, "talker: failed to create socket\n"); - return 2; } else { - remote_servinfo = q; + /* You're the client */ + /* Get remote info */ + memset(&remote_hints, 0, sizeof(remote_hints)); + remote_hints.ai_family = AF_INET; + remote_hints.ai_socktype = SOCK_STREAM; + + if ((status = getaddrinfo(remote_machine, remote_port, &remote_hints, + &remote_servinfo)) != 0) { + fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); + exit(1); + } + for (q = remote_servinfo; q != NULL; q = q->ai_next) { + /* Create socket */ + if ((socketfd = socket(q->ai_family, + q->ai_socktype, + q->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + + break; + } + + if (q == NULL) { + fprintf(stderr, "talker: failed to create socket\n"); + return 2; + } + else { + remote_servinfo = q; + } } + + + + pthread_create(&input_thread, NULL, input, (void*) msg); From 6b6745bf2e9358951283e94298543492b5dd0b8c Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Fri, 20 Jun 2025 23:54:58 -0600 Subject: [PATCH 05/41] added stuff for server side --- main.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 5cce76f..f28ac81 100644 --- a/main.c +++ b/main.c @@ -56,6 +56,7 @@ int main(int argc, char* argv[]) { remote_machine = argv[2]; remote_port = argv[3]; + if (atoi(local_port) < atoi(remote_port)) { /* Congrats, you're the server */ memset(&hints, 0, sizeof(hints)); @@ -93,6 +94,27 @@ int main(int argc, char* argv[]) { else { servinfo = p; } + + freeaddrinfo(servinfo); + if (listen(socketfd, BACKLOG) == -1) { + perror("listen"); + exit(1); + } + + while (1) { + sin_size = sizeof their_addr; + confd = accept(socketfd, (struct sockaddr *)&their_addr, &sin_size); + if (confd == -1) { + perror("accept"); + continue; + } + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, sizeof s); + printf("server: got connection from %s\n", s); + + } + } else { /* You're the client */ @@ -128,11 +150,10 @@ int main(int argc, char* argv[]) { } - - - - pthread_create(&input_thread, NULL, input, (void*) msg); + + + pthread_join(input_thread, NULL); return 0; From 71f9a5962390b0f7513c8fd78bdae917a2b4fda2 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sat, 21 Jun 2025 12:32:01 -0600 Subject: [PATCH 06/41] fixed compiler errors --- main.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index f28ac81..c757886 100644 --- a/main.c +++ b/main.c @@ -19,13 +19,7 @@ #include #define MAXBUFSIZE 30 - -int socketfd; - -struct addrinfo hints, remote_hints; -struct addrinfo *servinfo, *remote_servinfo; - -char *remote_machine, *local_port, *remote_port; +#define BACKLOG 10 void *input(void *arg) { while (1) { @@ -40,11 +34,25 @@ void *sender(void *arg) { return 0; } +void *get_in_addr(struct sockaddr *sa) { + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + int main(int argc, char* argv[]) { pthread_t input_thread, send_thread, receive_thread; - char *msg; + socklen_t sin_size; struct addrinfo *p, *q; - int status; + struct addrinfo hints, remote_hints; + struct addrinfo *servinfo, *remote_servinfo; + struct sockaddr_storage their_addr; + char s[INET6_ADDRSTRLEN]; + char *msg; + char *remote_machine, *local_port, *remote_port; + int status, socketfd, confd; int yes = 1; if (argc != 4) { @@ -56,7 +64,6 @@ int main(int argc, char* argv[]) { remote_machine = argv[2]; remote_port = argv[3]; - if (atoi(local_port) < atoi(remote_port)) { /* Congrats, you're the server */ memset(&hints, 0, sizeof(hints)); From b11fa9d2ab99750c62b2145c31e638806c2ac4b1 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sat, 21 Jun 2025 21:03:05 -0600 Subject: [PATCH 07/41] added client --- main.c | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/main.c b/main.c index c757886..e4a01aa 100644 --- a/main.c +++ b/main.c @@ -46,8 +46,8 @@ int main(int argc, char* argv[]) { pthread_t input_thread, send_thread, receive_thread; socklen_t sin_size; struct addrinfo *p, *q; - struct addrinfo hints, remote_hints; - struct addrinfo *servinfo, *remote_servinfo; + struct addrinfo hints; + struct addrinfo *servinfo; struct sockaddr_storage their_addr; char s[INET6_ADDRSTRLEN]; char *msg; @@ -56,7 +56,8 @@ int main(int argc, char* argv[]) { int yes = 1; if (argc != 4) { - printf("Wrong number of arguments\n"); + printf("Wrong number of arguments. Usage: ./chatty \ + \n"); return -1; } @@ -81,21 +82,21 @@ int main(int argc, char* argv[]) { if ((socketfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { - perror("listener: socket"); + perror("Server: socket"); continue; } /* Bind */ if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { close(socketfd); - perror("listener: bind"); + perror("Server: bind"); continue; } break; } if (p == NULL) { - fprintf(stderr, "listener: failed to bind socket\n"); + fprintf(stderr, "Server: failed to bind socket\n"); return 2; } else { @@ -110,15 +111,17 @@ int main(int argc, char* argv[]) { while (1) { sin_size = sizeof their_addr; + printf("Waiting for connection...\n"); confd = accept(socketfd, (struct sockaddr *)&their_addr, &sin_size); if (confd == -1) { perror("accept"); continue; } - inet_ntop(their_addr.ss_family, - get_in_addr((struct sockaddr *)&their_addr), - s, sizeof s); - printf("server: got connection from %s\n", s); + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, + sizeof s); + printf("Getting chatty with %s\n", s); } @@ -126,42 +129,47 @@ int main(int argc, char* argv[]) { else { /* You're the client */ /* Get remote info */ - memset(&remote_hints, 0, sizeof(remote_hints)); - remote_hints.ai_family = AF_INET; - remote_hints.ai_socktype = SOCK_STREAM; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; - if ((status = getaddrinfo(remote_machine, remote_port, &remote_hints, - &remote_servinfo)) != 0) { + if ((status = getaddrinfo(remote_machine, remote_port, &hints, + &servinfo)) != 0) { fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); exit(1); } - for (q = remote_servinfo; q != NULL; q = q->ai_next) { + for (q = servinfo; q != NULL; q = q->ai_next) { /* Create socket */ if ((socketfd = socket(q->ai_family, q->ai_socktype, q->ai_protocol)) == -1) { - perror("talker: socket"); + perror("Client: socket"); continue; } + inet_ntop(q->ai_family, get_in_addr((struct sockaddr *)q->ai_addr), + s, sizeof s); + printf("Client: attempting connection to %s\n", s); + if (connect(socketfd, q->ai_addr, q->ai_addrlen) == -1) { + perror("Client: connect"); + close(socketfd); + continue; + } break; } if (q == NULL) { - fprintf(stderr, "talker: failed to create socket\n"); + fprintf(stderr, "Client: failed to create socket\n"); return 2; } else { - remote_servinfo = q; + servinfo = q; } } pthread_create(&input_thread, NULL, input, (void*) msg); - - - pthread_join(input_thread, NULL); return 0; } From f6520fa7c0137847c41c475d7617da8040c4bf7a Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sat, 21 Jun 2025 23:06:32 -0600 Subject: [PATCH 08/41] added message to confirm connection --- main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index e4a01aa..5f63282 100644 --- a/main.c +++ b/main.c @@ -165,7 +165,8 @@ int main(int argc, char* argv[]) { else { servinfo = q; } - } + printf("Connected!\n"); + } pthread_create(&input_thread, NULL, input, (void*) msg); From aba9dcdd93a5557067e43d8c59e2cdc36d5a4b17 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sun, 22 Jun 2025 13:45:34 -0600 Subject: [PATCH 09/41] changed socket options and removed infinite loop --- main.c | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/main.c b/main.c index 5f63282..2012a44 100644 --- a/main.c +++ b/main.c @@ -85,7 +85,12 @@ int main(int argc, char* argv[]) { perror("Server: socket"); continue; } - + /* Allow reuse of socket despite binding */ + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, + sizeof(int)) == -1) { + perror("setsockopt"); + exit(1); + } /* Bind */ if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { close(socketfd); @@ -109,21 +114,17 @@ int main(int argc, char* argv[]) { exit(1); } - while (1) { - sin_size = sizeof their_addr; - printf("Waiting for connection...\n"); - confd = accept(socketfd, (struct sockaddr *)&their_addr, &sin_size); - if (confd == -1) { - perror("accept"); - continue; - } - inet_ntop(their_addr.ss_family, - get_in_addr((struct sockaddr *)&their_addr), - s, - sizeof s); - printf("Getting chatty with %s\n", s); - - } + sin_size = sizeof their_addr; + printf("Waiting for connection...\n"); + confd = accept(socketfd, (struct sockaddr *)&their_addr, &sin_size); + if (confd == -1) { + perror("accept"); + } + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, + sizeof s); + printf("Getting chatty with %s\n", s); } else { @@ -146,15 +147,15 @@ int main(int argc, char* argv[]) { perror("Client: socket"); continue; } - inet_ntop(q->ai_family, get_in_addr((struct sockaddr *)q->ai_addr), - s, sizeof s); - printf("Client: attempting connection to %s\n", s); + inet_ntop(q->ai_family, get_in_addr((struct sockaddr *)q->ai_addr), + s, sizeof s); + printf("Client: attempting connection to %s\n", s); - if (connect(socketfd, q->ai_addr, q->ai_addrlen) == -1) { - perror("Client: connect"); - close(socketfd); - continue; - } + if (connect(socketfd, q->ai_addr, q->ai_addrlen) == -1) { + perror("Client: connect"); + close(socketfd); + continue; + } break; } @@ -168,10 +169,10 @@ int main(int argc, char* argv[]) { printf("Connected!\n"); } - +/* pthread_create(&input_thread, NULL, input, (void*) msg); - pthread_join(input_thread, NULL); +*/ return 0; } From d55f3828badc9d1e23e19f3ca79bd7753547d0bb Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sun, 22 Jun 2025 13:46:57 -0600 Subject: [PATCH 10/41] fixed typo --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 2012a44..3365c13 100644 --- a/main.c +++ b/main.c @@ -86,7 +86,7 @@ int main(int argc, char* argv[]) { continue; } /* Allow reuse of socket despite binding */ - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, + if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); From b0371b34443975742159fc2c23b82f6ba78d589a Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sun, 22 Jun 2025 15:32:52 -0600 Subject: [PATCH 11/41] Send test --- main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 3365c13..6f9ea86 100644 --- a/main.c +++ b/main.c @@ -52,7 +52,7 @@ int main(int argc, char* argv[]) { char s[INET6_ADDRSTRLEN]; char *msg; char *remote_machine, *local_port, *remote_port; - int status, socketfd, confd; + int status, socketfd, confd, len; int yes = 1; if (argc != 4) { @@ -125,7 +125,8 @@ int main(int argc, char* argv[]) { s, sizeof s); printf("Getting chatty with %s\n", s); - + len = strlen("test"); + send(confd, "test", len, 0); } else { /* You're the client */ From bd8be851bc09447291c91066764c132066b16d78 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sun, 22 Jun 2025 15:39:56 -0600 Subject: [PATCH 12/41] added send and recv --- main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.c b/main.c index 6f9ea86..6746bcc 100644 --- a/main.c +++ b/main.c @@ -54,6 +54,7 @@ int main(int argc, char* argv[]) { char *remote_machine, *local_port, *remote_port; int status, socketfd, confd, len; int yes = 1; + char *buf; if (argc != 4) { printf("Wrong number of arguments. Usage: ./chatty \ @@ -168,6 +169,9 @@ int main(int argc, char* argv[]) { servinfo = q; } printf("Connected!\n"); + + recv(socketfd, &buf, 20, 0); + printf("%s\n", buf); } /* From b38ec3479979149a1374a6c022029f9053d1e663 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sun, 22 Jun 2025 15:43:45 -0600 Subject: [PATCH 13/41] allocate mem for buffer --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 6746bcc..27a7d32 100644 --- a/main.c +++ b/main.c @@ -169,7 +169,7 @@ int main(int argc, char* argv[]) { servinfo = q; } printf("Connected!\n"); - + buf = calloc(4, sizeof(char)); recv(socketfd, &buf, 20, 0); printf("%s\n", buf); } From c511bbeb640757c351d042a4593d374c377aeb0b Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Sun, 22 Jun 2025 15:48:53 -0600 Subject: [PATCH 14/41] sending and receiving working --- main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.c b/main.c index 27a7d32..26dfbc9 100644 --- a/main.c +++ b/main.c @@ -54,7 +54,7 @@ int main(int argc, char* argv[]) { char *remote_machine, *local_port, *remote_port; int status, socketfd, confd, len; int yes = 1; - char *buf; + char buf[10]; if (argc != 4) { printf("Wrong number of arguments. Usage: ./chatty \ @@ -169,7 +169,6 @@ int main(int argc, char* argv[]) { servinfo = q; } printf("Connected!\n"); - buf = calloc(4, sizeof(char)); recv(socketfd, &buf, 20, 0); printf("%s\n", buf); } From b224cacd0560fa7a5f589cadd3a5f4674bac1dd1 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Mon, 23 Jun 2025 14:08:11 -0600 Subject: [PATCH 15/41] added list for holding messages --- liblist.a | Bin 0 -> 17660 bytes list.h | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 18 +++--- 3 files changed, 179 insertions(+), 7 deletions(-) create mode 100644 liblist.a create mode 100644 list.h diff --git a/liblist.a b/liblist.a new file mode 100644 index 0000000000000000000000000000000000000000..927feaf174ad7085b4deb5d8c28b931d37c7494c GIT binary patch literal 17660 zcmeHOeQaFEao=~RBab@q%d#X=QmmtFN%V*KWtyfG*``8Erffx4ZKq)k+v1TtlZ-?j zeLNbnVZ{dG6q3_67T_QTLbMWs0&WVoaf39DBfv83qShZRf&@t2B0&8|T{uON4@5zP zBuzTM*_p?^;axvG|SeT#jwf$4YIbS=Nlggp|agUJl<7{wnzF6eS{dtT5 zSMSSD7asRr*k8>1$^*rzX?Kh|btE@Fo-fXI6lk!*@#*R5>+bLA?dqZ->h9|5>!tFR z{(c#tk=0M{JGeg)MKnyFB6qu6

#opgE{>b--)pqOPQ5qussC*H`+XOoHuT5) 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 literal 0 HcmV?d00001 diff --git a/list.h b/list.h new file mode 100644 index 0000000..dd2bef3 --- /dev/null +++ b/list.h @@ -0,0 +1,168 @@ +/* + Dane MacFadden + dgm288 + 11283087 + + James Hom + jhh318 + 11287431 +*/ + +#ifndef __LIST_H__ +#define __LIST_H__ + + +typedef struct node { + void *data; + struct node *next; + struct node *previous; +} NODE; + +typedef struct list { + + int size; + NODE *current; + NODE *head; + NODE *tail; + +} LIST; + +/* + Create empty list + Returns: Pointer to new empty list if successful, NULL pointer otherwise + */ +LIST *ListCreate(); + + +/* Returns the number of items contained by the list */ +int ListCount(LIST *list); + + +/* + Returns pointer to first item in the list and makes it the current item + list: Pointer to a list + Returns: Pointer to first item in the list +*/ +void *ListFirst(LIST *list); + + +/* + Return pointer to last item in list + list: Pointer to a list + Returns: Pointer to last item in list +*/ +void *ListLast(LIST *list); + + +/* + Return next item in the list + list: Pointer to a list + Returns: Pointer to next item in list +*/ + +void *ListNext(LIST *list); + + +/* + Return previous item in list + list: Pointer to a list + Returns: Pointer to last item +*/ +void *ListPrev(LIST *list); + + +/* Get current item in list + list: Pointer to list + Returns: Pointer to last item +*/ +void *ListCurr(LIST *list); + + +/* + Add item to list after current item, + switch current item to the item we just added. + If current item is at the end, item is added at the end. + list: List pointer + item: Pointer to an item to add to the list + Returns: 0 if successful, -1 otherwise +*/ +int ListAdd(LIST *list, void *item); + + +/* + Insert an item right before the current item. + If current is the start of the list, add to the start. + list: Pointer to list + item: Pointer to item to add + Returns: 0 if successful, -1 otherwise + */ +int ListInsert(LIST *list, void *item); + + +/* + Add an item to the end of the list + list: Pointer to list + item: Pointer to item to add + Returns: 0 if successful, -1 otherwise +*/ +int ListAppend(LIST *list, void *item); + + +/* + Add item to the front of the list + list: Pointer to list + item: Pointer to item to add + Returns: 0 if successful, -1 otherwise +*/ +int ListPrepend(LIST *list, void *item); + +/* + Delete current item from list and make next item current + list: Pointer to list + Returns: Deleted item +*/ +void *ListRemove(LIST *list); + + +/* + Adds list2 to the end of list1 + Current pointer set to current pointer of list1 + List2 ceases to exist + list1: Pointer to list1 + list2: Pointer to list2 +*/ +void ListConcat(LIST *list1, LIST *list2); + +/* + Deletes list + list: Pointer to list + itemFree: routine that frees an item +*/ +void ListFree(LIST *list, void (*itemFree)(void *)); + + +/* + Returns last item and takes it out of the list + list: Pointer to list + Returns: Pointer to last item that was just deleted from list +*/ +void *ListTrim(LIST *list); + + +/* + Search list starting at current item. + Finishes at end of list or when a match is found + list: Pointer to list + comparator: Routine that returns 0 + if the item and comparisonArg don't match, + or 1 if they do. If a match is found the current pointer + is left at the matched item + If no match is found, + current pointer is left at the end + Returns: Pointer to matching item if found, otherwise NULL pointer +*/ +void *ListSearch(LIST *list, int (*comparator)(void *, void *), void *comparisonArg); + +#endif + + diff --git a/main.c b/main.c index 26dfbc9..8a76e91 100644 --- a/main.c +++ b/main.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #define MAXBUFSIZE 30 #define BACKLOG 10 @@ -31,7 +31,12 @@ void *input(void *arg) { } void *sender(void *arg) { - return 0; + + return 0; +} + +void *receiver(void *arg) { + return 0; } void *get_in_addr(struct sockaddr *sa) { @@ -126,8 +131,6 @@ int main(int argc, char* argv[]) { s, sizeof s); printf("Getting chatty with %s\n", s); - len = strlen("test"); - send(confd, "test", len, 0); } else { /* You're the client */ @@ -169,14 +172,15 @@ int main(int argc, char* argv[]) { servinfo = q; } printf("Connected!\n"); - recv(socketfd, &buf, 20, 0); - printf("%s\n", buf); } /* pthread_create(&input_thread, NULL, input, (void*) msg); pthread_join(input_thread, NULL); -*/ +*/ + + close(socketfd); + close(confd); return 0; } From dbd18f9270bb90f5d46b5279cd10528d029d8d85 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 24 Jun 2025 12:56:04 -0600 Subject: [PATCH 16/41] add readme small list changes --- README.md | 5 +++++ main.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d71e959 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +Chatty is a simple, multithreaded chat program by Dane MacFadden. +It's inspired by an assignment I did in university that was a similar project +and is intended to be an exercise in networked and multithreaded programming. +Check out Beej's guide to network programming (and his other guides) if you want +to build something similar. Much of my code is based on his client and server. diff --git a/main.c b/main.c index 8a76e91..82f4f3a 100644 --- a/main.c +++ b/main.c @@ -21,6 +21,8 @@ #define MAXBUFSIZE 30 #define BACKLOG 10 +LIST *receivelist, *sendlist; + void *input(void *arg) { while (1) { /* @@ -59,7 +61,6 @@ int main(int argc, char* argv[]) { char *remote_machine, *local_port, *remote_port; int status, socketfd, confd, len; int yes = 1; - char buf[10]; if (argc != 4) { printf("Wrong number of arguments. Usage: ./chatty \ @@ -71,6 +72,9 @@ int main(int argc, char* argv[]) { remote_machine = argv[2]; remote_port = argv[3]; + receivelist = ListCreate(); + sendlist = ListCreate(); + if (atoi(local_port) < atoi(remote_port)) { /* Congrats, you're the server */ memset(&hints, 0, sizeof(hints)); From c467c345c5d877d6ece8c6b2bf5d8b6155dbf93b Mon Sep 17 00:00:00 2001 From: DaneMacFadden <31639805+DaneMacFadden@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:57:09 -0600 Subject: [PATCH 17/41] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d71e959..4bdc543 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,4 @@ It's inspired by an assignment I did in university that was a similar project and is intended to be an exercise in networked and multithreaded programming. Check out Beej's guide to network programming (and his other guides) if you want to build something similar. Much of my code is based on his client and server. +Shoutout James for helping me write the list library back in the day. From 3a40ecc2aa43be47621003c21a13866d68c3f2a9 Mon Sep 17 00:00:00 2001 From: DaneMacFadden <31639805+DaneMacFadden@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:57:31 -0600 Subject: [PATCH 18/41] Update list.h --- list.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/list.h b/list.h index dd2bef3..be4ca04 100644 --- a/list.h +++ b/list.h @@ -1,11 +1,6 @@ /* Dane MacFadden - dgm288 - 11283087 - James Hom - jhh318 - 11287431 */ #ifndef __LIST_H__ From 52644a10c85cced0fbd7585e7d5e8411a8428ec4 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 24 Jun 2025 16:46:10 -0600 Subject: [PATCH 19/41] accept input from user --- main.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/main.c b/main.c index 82f4f3a..4c1009f 100644 --- a/main.c +++ b/main.c @@ -16,19 +16,21 @@ #include #include #include -#include +/*#include "list.h"*/ #define MAXBUFSIZE 30 #define BACKLOG 10 -LIST *receivelist, *sendlist; +/*LIST *receivelist, *sendlist;*/ void *input(void *arg) { - while (1) { - /* - * Accept input - */ - } + char msg[512]; + + while (1) { + printf("Type a message: "); + scanf("%s", msg); + printf("%s", msg); + } return 0; } @@ -71,12 +73,11 @@ int main(int argc, char* argv[]) { local_port = argv[1]; remote_machine = argv[2]; remote_port = argv[3]; - - receivelist = ListCreate(); + + /*receivelist = ListCreate(); sendlist = ListCreate(); - +*/ if (atoi(local_port) < atoi(remote_port)) { - /* Congrats, you're the server */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; @@ -87,7 +88,6 @@ int main(int argc, char* argv[]) { exit(1); } - /* Create socket */ for (p = servinfo; p != NULL; p = p->ai_next) { if ((socketfd = socket(p->ai_family, p->ai_socktype, @@ -95,13 +95,11 @@ int main(int argc, char* argv[]) { perror("Server: socket"); continue; } - /* Allow reuse of socket despite binding */ if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } - /* Bind */ if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { close(socketfd); perror("Server: bind"); @@ -137,8 +135,6 @@ int main(int argc, char* argv[]) { printf("Getting chatty with %s\n", s); } else { - /* You're the client */ - /* Get remote info */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; @@ -149,7 +145,6 @@ int main(int argc, char* argv[]) { exit(1); } for (q = servinfo; q != NULL; q = q->ai_next) { - /* Create socket */ if ((socketfd = socket(q->ai_family, q->ai_socktype, q->ai_protocol)) == -1) { @@ -177,14 +172,11 @@ int main(int argc, char* argv[]) { } printf("Connected!\n"); } - -/* pthread_create(&input_thread, NULL, input, (void*) msg); pthread_join(input_thread, NULL); -*/ close(socketfd); - close(confd); + close(confd); return 0; } From d1f38e397e006435fea60e24b66662bcc6645cae Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Wed, 25 Jun 2025 13:16:22 -0600 Subject: [PATCH 20/41] added list files to redesign library for this project --- list_adders.c | 13 +++++++++++++ list_movers.c | 0 list_removers.c | 0 3 files changed, 13 insertions(+) create mode 100644 list_adders.c create mode 100644 list_movers.c create mode 100644 list_removers.c diff --git a/list_adders.c b/list_adders.c new file mode 100644 index 0000000..d6a7576 --- /dev/null +++ b/list_adders.c @@ -0,0 +1,13 @@ +#include + +LIST *ListCreate(); + +int ListAdd(); + +int ListInsert(); + +int ListPrepend(); + +int ListAppend(); + +int ListConcat(); diff --git a/list_movers.c b/list_movers.c new file mode 100644 index 0000000..e69de29 diff --git a/list_removers.c b/list_removers.c new file mode 100644 index 0000000..e69de29 From c002c78b9adebc6b6b0bab3bdee2830aeb603fd6 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 8 Jul 2025 20:05:01 -0600 Subject: [PATCH 21/41] updated list lib --- list.h | 160 ++++++++++++++---------------- list_adders.c | 130 ++++++++++++++++++++++-- list_movers.c | 40 ++++++++ list_removers.c | 81 +++++++++++++++ list_remvoers.c | 0 listtest.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 10 +- 7 files changed, 579 insertions(+), 97 deletions(-) create mode 100644 list_remvoers.c create mode 100644 listtest.c diff --git a/list.h b/list.h index be4ca04..a5a8db8 100644 --- a/list.h +++ b/list.h @@ -6,7 +6,6 @@ #ifndef __LIST_H__ #define __LIST_H__ - typedef struct node { void *data; struct node *next; @@ -22,57 +21,51 @@ typedef struct list { } LIST; -/* - Create empty list - Returns: Pointer to new empty list if successful, NULL pointer otherwise +/* + * Create an empty list + * Return: Pointer to new empty list */ -LIST *ListCreate(); +LIST *ListCreate(void); - -/* Returns the number of items contained by the list */ +/* + * Get the number of items in the list + * Return: Integer containing number of items + */ int ListCount(LIST *list); - /* - Returns pointer to first item in the list and makes it the current item - list: Pointer to a list - Returns: Pointer to first item in the list -*/ + * Get the first item in the list and make it the current item + * list: Pointer to a list + * Return: Pointer to head's data + */ void *ListFirst(LIST *list); - /* - Return pointer to last item in list - list: Pointer to a list - Returns: Pointer to last item in list -*/ + * Get the last item in the list and make it the current item + * list: Pointer to a list + * Return: Pointer to tail's data + */ void *ListLast(LIST *list); - -/* - Return next item in the list - list: Pointer to a list - Returns: Pointer to next item in list -*/ - +/* Get the item in the list after the cursor and make the cursor point to it + * list: Pointer to a list + * Return: Pointer to next item's data + */ void *ListNext(LIST *list); - /* - Return previous item in list - list: Pointer to a list - Returns: Pointer to last item -*/ + * Get the item before the cursor and set the cursor to it. + * list: Pointer to a list + * Return: Pointer to previous item's data + */ void *ListPrev(LIST *list); - /* Get current item in list - list: Pointer to list - Returns: Pointer to last item + * list: Pointer to list + * Return: Pointer to current item's data */ void *ListCurr(LIST *list); - /* Add item to list after current item, switch current item to the item we just added. @@ -83,80 +76,75 @@ void *ListCurr(LIST *list); */ int ListAdd(LIST *list, void *item); - /* - Insert an item right before the current item. - If current is the start of the list, add to the start. - list: Pointer to list - item: Pointer to item to add - Returns: 0 if successful, -1 otherwise + * Insert an item right before the current item, switch cursor to new item. + * If current is the start of the list, add to the start. + * list: Pointer to list + * item: Pointer to item to add + * Return: 0 if successful, -1 otherwise */ int ListInsert(LIST *list, void *item); - /* - Add an item to the end of the list - list: Pointer to list - item: Pointer to item to add - Returns: 0 if successful, -1 otherwise -*/ + * Add an item to the end of the list. Keep cursor where it is. + * list: Pointer to list + * item: Pointer to item to add + * Return: 0 if successful, -1 otherwise + */ int ListAppend(LIST *list, void *item); - /* - Add item to the front of the list - list: Pointer to list - item: Pointer to item to add - Returns: 0 if successful, -1 otherwise -*/ + * Add item to the front of the list + * list: Pointer to list + * item: Pointer to item to add + * Return: 0 if successful, -1 otherwise + */ int ListPrepend(LIST *list, void *item); /* - Delete current item from list and make next item current - list: Pointer to list - Returns: Deleted item -*/ -void *ListRemove(LIST *list); - + * Delete current item from list, free current item, and make next item current + * list: Pointer to list + * Return: 0 on success, -1 on failure + */ +int ListRemove(LIST *list); /* - Adds list2 to the end of list1 - Current pointer set to current pointer of list1 - List2 ceases to exist - list1: Pointer to list1 - list2: Pointer to list2 -*/ + * Adds list2 to the end of list1 + * Current pointer set to current pointer of list 1. List2 ceases to exist + * list1: Pointer to list1 + * list2: Pointer to list2 + */ void ListConcat(LIST *list1, LIST *list2); /* - Deletes list - list: Pointer to list - itemFree: routine that frees an item -*/ -void ListFree(LIST *list, void (*itemFree)(void *)); - + * Deletes list + * Ensure you set your pointer to NULL after calling so you don't get + * dangling pointers! + * list: Pointer to list + */ +void ListFree(LIST *list); /* - Returns last item and takes it out of the list - list: Pointer to list - Returns: Pointer to last item that was just deleted from list -*/ + * Returns last item and takes it out of the list + * list: Pointer to list + * Returns Pointer to last item that was just deleted from list + */ void *ListTrim(LIST *list); - /* - Search list starting at current item. - Finishes at end of list or when a match is found - list: Pointer to list - comparator: Routine that returns 0 - if the item and comparisonArg don't match, - or 1 if they do. If a match is found the current pointer - is left at the matched item - If no match is found, - current pointer is left at the end - Returns: Pointer to matching item if found, otherwise NULL pointer -*/ -void *ListSearch(LIST *list, int (*comparator)(void *, void *), void *comparisonArg); + * Search list starting at current item. + * Finishes at end of list or when a match is found + * list: Pointer to list + * comparator: Routine that returns 0 + * if the item and comparisonArg don't match, + * or 1 if they do. If a match is found the current pointer + * is left at the matched item + * If no match is found, + * current pointer is left at the end + * Return: Pointer to matching item if found, otherwise NULL pointer + */ +void *ListSearch(LIST *list, int (*comparator)(void *, void *), + void *comparisonArg); #endif diff --git a/list_adders.c b/list_adders.c index d6a7576..e873a90 100644 --- a/list_adders.c +++ b/list_adders.c @@ -1,13 +1,131 @@ #include +#include +#include -LIST *ListCreate(); +LIST *ListCreate(void) { + LIST *new_list; + + new_list = malloc(sizeof(LIST)); + if (!new_list) { + return NULL; + } + + new_list->size = 0; + new_list->current = 0; + new_list->head = 0; + new_list->tail = 0; -int ListAdd(); + return new_list; +} -int ListInsert(); +int ListAdd(LIST *list, void *item) { + /* 3 cases + * 1. Empty list + * 2. Insert when cursor is at the tail (& list not empty) + * 3. Insert when cursor is anywhere but the tail (& list not empty) + */ + NODE *new = malloc(sizeof(NODE)); + if (new == NULL || (list->current == NULL && list->size != 0)) { + return -1; + } + new->data = item; + if (list->size == 0) { + list->current = new; + list->head = new; + list->tail = new; + } + else if (list->current == list->tail) { + new->previous = list->tail; + list->tail->next = new; + list->tail = new; + list->current = new; + } + else if (list->current != list->tail && list->size > 0) { + new->next = list->current->next; + new->previous = list->current; + list->current->next->previous = new; + list->current->next = new; + list->current = new; + } + else { + return -1; + } -int ListPrepend(); + list->size++; + return 0; +} -int ListAppend(); +int ListInsert(LIST *list, void *item) { + /* 3 cases + * 1. Empty list + * 2. Insert when cursor is at the head (& list not empty) + * 3. Insert when cursor is anywhere but the head (& list not empty) + */ + NODE *new = malloc(sizeof(NODE)); + if (new == NULL || (list->current == NULL && list->size != 0)) { + return -1; + } + + new->data = item; + if (list->size == 0) { + list->current = new; + list->head = new; + list->tail = new; + } + else if (list->current == list->head) { + new->next = list->head; + list->head->previous = new; + list->head = new; + list->current = new; + } + else if (list->current != list->head && list->size > 0) { + new->next = list->current; + new->previous = list->current->previous; + list->current->previous->next = new; + list->current->previous = new; + list->current = new; + } + else { + return -1; + } + + list->size++; + return 0; +} + +int ListPrepend(LIST *list, void *item) { + NODE *new = malloc(sizeof(NODE)); + if (new == NULL) { + return -1; + } + new->data = item; + new->next = list->head; + list->head->previous = new; + list->head = new; + list->size++; + return 0; + +} + +int ListAppend(LIST *list, void *item) { + NODE *new = malloc(sizeof(NODE)); + if (new == NULL) { + return -1; + } + new->data = item; + new->previous = list->tail; + list->tail->next = new; + list->tail = new; + list->size++; + return 0; + +} + +void ListConcat(LIST *listone, LIST *listtwo) { + listone->tail->next = listtwo->head; + listone->tail = listtwo->tail; + listone->size += listtwo->size; + free(listtwo); + listtwo = NULL; +} -int ListConcat(); diff --git a/list_movers.c b/list_movers.c index e69de29..18b9cab 100644 --- a/list_movers.c +++ b/list_movers.c @@ -0,0 +1,40 @@ +#include +#include + +int ListCount(LIST *list) { + return (int) list->size; +} + +void *ListFirst(LIST *list) { + list->current = list->head; + return list->current->data; +} + +void *ListLast(LIST *list) { + list->current = list->tail; + return list->current->data; +} + +void *ListNext(LIST *list) { + if (list->current->next != NULL) { + list->current = list->current->next; + return list->current->data; + } + return NULL; +} + +void *ListPrev(LIST *list) { + if (list->current->next != NULL) { + list->current = list->current->previous; + return list->current->data; + } + return NULL; +} + +void *ListCurr(LIST *list) { + if (list->current != NULL) { + return list->current->data; + } + return NULL; +} + diff --git a/list_removers.c b/list_removers.c index e69de29..7c84239 100644 --- a/list_removers.c +++ b/list_removers.c @@ -0,0 +1,81 @@ +#include +#include + +int ListRemove(LIST *list) { + NODE *unused; + if (list->current == NULL) { + return -1; + } + if (list->size == 1) { + unused = list->current; + list->current = NULL; + list->head = NULL; + list->tail = NULL; + } + else if (list->current == list->head) { + unused = list->head; + list->head = list->head->next; + list->current = list->head; + list->current->previous = NULL; + } + else if (list->current == list->tail) { + unused = list->tail; + list->tail= list->tail->previous; + list->current = list->tail; + list->current->next = NULL; + } + else { + unused = list->current; + list->current->previous->next = list->current->next; + list->current->next->previous = list->current->previous; + list->current = list->current->next; + } + + unused->data = NULL; + free(unused->data); + unused->next = NULL; + unused->previous = NULL; + unused = NULL; + free(unused); + list->size--; + return 0; + +} + +void ListFree(LIST *list) { + ListFirst(list); + while (list->head != NULL) { + ListRemove(list); + } + free(list); + +} + +void *ListTrim(LIST *list) { + NODE *tempnode = list->tail->previous; + list->tail->previous = NULL; + free(list->tail); + list->tail = tempnode; + list->size--; + return 0; +} + +void *ListSearch(LIST *list, int (*comparator)(void *, void*), + void *comparisonArg) { + ListFirst(list); + while (list->current != NULL) { + if ((*comparator)(list->current->data, comparisonArg)) { + break; + } + else { + ListNext(list); + } + } + + if (list->current == NULL) { + list->current = list->tail; + return NULL; + } + + return list->current; +} diff --git a/list_remvoers.c b/list_remvoers.c new file mode 100644 index 0000000..e69de29 diff --git a/listtest.c b/listtest.c new file mode 100644 index 0000000..5ff9b00 --- /dev/null +++ b/listtest.c @@ -0,0 +1,255 @@ +#include +#include +#include + +int ListPrint(LIST *list) { + if (ListFirst(list) != NULL) { + printf("%d, ", *(int*)list->current->data); + } + + while (ListNext(list) != NULL) { + printf("%d, ", *(int*)list->current->data); + } + printf("\n"); + return 0; +} + +int main(void) { + LIST *listone = ListCreate(); + LIST *listtwo = ListCreate(); + NODE *cursor, *temp; + int errors = 0; + int one = 1; + int two = 2; + int three = 3; + int four = 4; + int five = 5; + int six = 6; + int seven = 7; + + /* Adders tests */ + if (listone == NULL) { + errors++; + printf("ListCreate failed on list 1\n"); + } + if (listtwo == NULL) { + errors++; + printf("ListCreate failed on list 2\n"); + } + + /* Test each of the three cases for ListAdd */ + ListAdd(listone, &one); + if (ListCount(listone) != 1) { + printf("Error in ListAdd: ListCount expected 1 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->head->data != &one) { + printf("Error in ListAdd: head data unexpected\n"); + errors++; + } + if (listone->tail->data != &one) { + printf("Error in ListAdd: tail data unexpected\n"); + errors++; + } + if (listone->current->data != &one) { + printf("Error in ListAdd: current data unexpected\n"); + errors++; + } + + /* ListAdd 2 */ + ListAdd(listone, &two); + if (ListCount(listone) != 2) { + printf("Error in ListAdd 2: ListCount expected 2 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->tail->data != &two) { + printf("Error in ListAdd 2: tail data unexpected\n"); + errors++; + } + if (listone->current->data != &two) { + printf("Error in ListAdd 2: current data unexpected\n"); + errors++; + } + + /* ListAdd 3 */ + ListFirst(listone); + if (listone->current != listone->head) { + printf("Error in ListAdd 3: ListFirst didn't move cursor\n"); + errors++; + } + ListAdd(listone, &three); + if (ListCount(listone) != 3) { + printf("Error in ListAdd 3: ListCount expected 3 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->head->data != &one) { + printf("Error in ListAdd 3: head data unexpected\n"); + errors++; + } + if (listone->tail->data != &two) { + printf("Error in ListAdd 3: tail data unexpected\n"); + errors++; + } + if (listone->current->data != &three) { + printf("Error in ListAdd 3: current data unexpected\n"); + errors++; + } + + ListLast(listone); + if (listone->current != listone->tail) { + printf("Error: ListLast didn't move cursor\n"); + errors++; + } + + /* List Append */ + ListFirst(listone); + cursor = listone->current; + ListAppend(listone, &four); + if (ListCount(listone) != 4) { + printf("Error in ListAppend: ListCount expected 4 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->tail->data != &four) { + printf("Error in ListAppend: tail data unexpected\n"); + errors++; + } + if (listone->current != cursor) { + printf("Error in ListAppend: Cursor moved"); + errors++; + } + + ListNext(listone); + if (listone->current->data != &three) { + printf("Error: ListNext didn't move the cursor\n"); + errors++; + } + + /* List Prepend */ + cursor = listone->current; + ListPrepend(listone, &five); + if (ListCount(listone) != 5) { + printf("Error in ListPrepend: ListCount expected 5 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->head->data != &five) { + printf("Error in ListPrepend: head data unexpected\n"); + errors++; + } + if (listone->current != cursor) { + printf("Error in ListPrepend: Cursor moved"); + errors++; + } + + temp = listone->current->previous; + ListPrev(listone); + if (temp != listone->current) { + printf("Error: ListPrev did not function properly\n"); + errors++; + } + + /* List Insert */ + /* Test w/ cursor at head of list */ + ListFirst(listone); + temp = listone->current; + ListInsert(listone, &six); + + if (listone->head->data != &six) { + printf("Error in ListInsert: Did not change head of list\n"); + errors++; + } + + if (ListCount(listone) != 6) { + printf("Error: ListInsert did not update count\n"); + errors++; + } + + /* Move cursor and test */ + ListNext(listone); + ListNext(listone); + + ListInsert(listone, &seven); + + if (ListCount(listone) != 7) { + printf("Error: ListInsert did not update count\n"); + errors++; + } + if (listone->current->data != &seven) { + printf("Error: ListInsert did not update current\n"); + errors++; + } + if (ListCurr(listone) != listone->current->data) { + printf("Error: ListCurr did not return current data\n"); + errors++; + } + + ListAdd(listtwo, &one); + ListAdd(listtwo, &two); + ListAdd(listtwo, &three); + ListAdd(listtwo, &four); + ListAdd(listtwo, &five); + + ListFirst(listtwo); + ListNext(listtwo); + ListNext(listtwo); + if (ListCurr(listtwo) != &three) { + printf("Error: List movers\n"); + errors++; + } + + /* Test remove */ + + ListRemove(listtwo); + if (ListCurr(listtwo) != &four) { + printf("Error: ListRemove did not move the cursor properly\n"); + errors++; + } + if (ListCount(listtwo) != 4) { + printf("Error: ListRemove did not update count\n"); + errors++; + } + + ListFirst(listtwo); + ListRemove(listtwo); + if (listtwo->head->data != &two || listtwo->current->data != &two) { + printf("Error: ListRemove did not change the head or cursor\n"); + errors++; + } + + ListLast(listtwo); + ListRemove(listtwo); + if (listtwo->tail->data != &four || listtwo->current->data != &four) { + printf("Error: ListRemove did not change the tail or cursor\n"); + errors++; + } + + /* Test concat */ + ListConcat(listone, listtwo); + listtwo = NULL; + if (ListCount(listone) != 9) { + printf("Error: ListConcat did not change list size\n"); + errors++; + } + if (listone->tail->previous->data != &two || listone->tail->data != &four) { + printf("Error: ListConcat did not concatenate properly\n"); + errors++; + } + + /* Tested free in GDB */ + ListTrim(listone); + if (listone->tail->data != &two) { + printf("Error: ListTrim did not set tail properly\n"); + errors++; + } + if (ListCount(listone) != 8) { + printf("Error: ListTrim did not change count properly\n"); + errors++; + } + printf("Finished with %d errors\n", errors); + + return 0; +} diff --git a/main.c b/main.c index 4c1009f..f6c702a 100644 --- a/main.c +++ b/main.c @@ -16,12 +16,12 @@ #include #include #include -/*#include "list.h"*/ +#include #define MAXBUFSIZE 30 #define BACKLOG 10 -/*LIST *receivelist, *sendlist;*/ +LIST *receivelist, *sendlist; void *input(void *arg) { char msg[512]; @@ -74,10 +74,10 @@ int main(int argc, char* argv[]) { remote_machine = argv[2]; remote_port = argv[3]; - /*receivelist = ListCreate(); + receivelist = ListCreate(); sendlist = ListCreate(); -*/ - if (atoi(local_port) < atoi(remote_port)) { + + if (atoi(local_port) < atoi(remote_port)) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; From d2e6441c96bf11626ca0210b5d496db5a805bdd7 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 8 Jul 2025 20:06:03 -0600 Subject: [PATCH 22/41] remove typo file --- list_remvoers.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 list_remvoers.c diff --git a/list_remvoers.c b/list_remvoers.c deleted file mode 100644 index e69de29..0000000 From 503ab912f88cb1d4da3a711c56b08f34adb3aa1f Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 8 Jul 2025 21:40:43 -0600 Subject: [PATCH 23/41] added basic input thread function --- main.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index f6c702a..0e59c20 100644 --- a/main.c +++ b/main.c @@ -22,6 +22,7 @@ #define BACKLOG 10 LIST *receivelist, *sendlist; +pthread_mutex_t sendmut, receivemut; void *input(void *arg) { char msg[512]; @@ -29,7 +30,9 @@ void *input(void *arg) { while (1) { printf("Type a message: "); scanf("%s", msg); - printf("%s", msg); + pthread_mutex_lock(&sendmut); + ListAppend(sendlist, msg); + pthread_mutex_unlock(&sendmut); } return 0; } @@ -52,7 +55,7 @@ void *get_in_addr(struct sockaddr *sa) { } int main(int argc, char* argv[]) { - pthread_t input_thread, send_thread, receive_thread; + pthread_t input_thread, send_thread, receive_thread, output_thread; socklen_t sin_size; struct addrinfo *p, *q; struct addrinfo hints; @@ -63,14 +66,17 @@ int main(int argc, char* argv[]) { char *remote_machine, *local_port, *remote_port; int status, socketfd, confd, len; int yes = 1; - + if (argc != 4) { - printf("Wrong number of arguments. Usage: ./chatty \ - \n"); + printf("Wrong number of arguments. Usage: ./chatty \ + \n"); return -1; } - - local_port = argv[1]; + + pthread_mutex_init(&sendmut, NULL); + pthread_mutex_init(&receivemut, NULL); + + local_port = argv[1]; remote_machine = argv[2]; remote_port = argv[3]; From af2e194ad4bd255c5984c488e2b75b390232ff3f Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Wed, 9 Jul 2025 18:02:45 -0600 Subject: [PATCH 24/41] bug fixes --- Makefile | 26 ++++++++++-- list_adders.c | 112 ++++++++++++++++++++++++++++---------------------- main.c | 9 ++-- 3 files changed, 88 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 1bf9676..8d97806 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,29 @@ CC = gcc CFLAGS = -g CPPFLAGS = -Wall -Wextra -pedantic -std=gnu90 -chatty: main.o - $(CC) $(CFLAGS) -o chatty main.o -lpthread +chatty: main.o liblist.a + $(CC) $(CFLAGS) -L. -o chatty main.o -llist -lpthread main.o: main.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o main.o main.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o main.o main.c + +liblist.a: list_adders.o list_removers.o list_movers.o + ar -rcs liblist.a list_adders.o list_removers.o list_movers.o + +list_adders.o: list_adders.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_adders.o list_adders.c + +list_movers.o: list_movers.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_movers.o list_movers.c + +list_removers.o: list_removers.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_removers.o list_removers.c + +listtest: listtest.o liblist.a + $(CC) $(CFLAGS) -L. -o listtest listtest.o -llist + +listtest.o: listtest.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o listtest.o listtest.c clean: - rm -f *.o chatty + rm -f *.o chatty liblist.a diff --git a/list_adders.c b/list_adders.c index e873a90..1dd7534 100644 --- a/list_adders.c +++ b/list_adders.c @@ -3,19 +3,19 @@ #include LIST *ListCreate(void) { - LIST *new_list; + LIST *new_node_list; - new_list = malloc(sizeof(LIST)); - if (!new_list) { + new_node_list = malloc(sizeof(LIST)); + if (!new_node_list) { return NULL; } - new_list->size = 0; - new_list->current = 0; - new_list->head = 0; - new_list->tail = 0; + new_node_list->size = 0; + new_node_list->current = 0; + new_node_list->head = 0; + new_node_list->tail = 0; - return new_list; + return new_node_list; } int ListAdd(LIST *list, void *item) { @@ -24,28 +24,28 @@ int ListAdd(LIST *list, void *item) { * 2. Insert when cursor is at the tail (& list not empty) * 3. Insert when cursor is anywhere but the tail (& list not empty) */ - NODE *new = malloc(sizeof(NODE)); - if (new == NULL || (list->current == NULL && list->size != 0)) { + NODE *new_node = malloc(sizeof(NODE)); + if (new_node == NULL || (list->current == NULL && list->size != 0)) { return -1; } - new->data = item; + new_node->data = item; if (list->size == 0) { - list->current = new; - list->head = new; - list->tail = new; + list->current = new_node; + list->head = new_node; + list->tail = new_node; } else if (list->current == list->tail) { - new->previous = list->tail; - list->tail->next = new; - list->tail = new; - list->current = new; + new_node->previous = list->tail; + list->tail->next = new_node; + list->tail = new_node; + list->current = new_node; } else if (list->current != list->tail && list->size > 0) { - new->next = list->current->next; - new->previous = list->current; - list->current->next->previous = new; - list->current->next = new; - list->current = new; + new_node->next = list->current->next; + new_node->previous = list->current; + list->current->next->previous = new_node; + list->current->next = new_node; + list->current = new_node; } else { return -1; @@ -61,29 +61,29 @@ int ListInsert(LIST *list, void *item) { * 2. Insert when cursor is at the head (& list not empty) * 3. Insert when cursor is anywhere but the head (& list not empty) */ - NODE *new = malloc(sizeof(NODE)); - if (new == NULL || (list->current == NULL && list->size != 0)) { + NODE *new_node = malloc(sizeof(NODE)); + if (new_node == NULL || (list->current == NULL && list->size != 0)) { return -1; } - new->data = item; + new_node->data = item; if (list->size == 0) { - list->current = new; - list->head = new; - list->tail = new; + list->current = new_node; + list->head = new_node; + list->tail = new_node; } else if (list->current == list->head) { - new->next = list->head; - list->head->previous = new; - list->head = new; - list->current = new; + new_node->next = list->head; + list->head->previous = new_node; + list->head = new_node; + list->current = new_node; } else if (list->current != list->head && list->size > 0) { - new->next = list->current; - new->previous = list->current->previous; - list->current->previous->next = new; - list->current->previous = new; - list->current = new; + new_node->next = list->current; + new_node->previous = list->current->previous; + list->current->previous->next = new_node; + list->current->previous = new_node; + list->current = new_node; } else { return -1; @@ -94,28 +94,40 @@ int ListInsert(LIST *list, void *item) { } int ListPrepend(LIST *list, void *item) { - NODE *new = malloc(sizeof(NODE)); - if (new == NULL) { + NODE *new_node = malloc(sizeof(NODE)); + if (new_node == NULL) { return -1; } - new->data = item; - new->next = list->head; - list->head->previous = new; - list->head = new; + new_node->data = item; + if (list->size == 0) { + list->current = new_node; + list->head = new_node; + list->tail = new_node; + } + new_node->next = list->head; + list->head->previous = new_node; + list->head = new_node; list->size++; return 0; } int ListAppend(LIST *list, void *item) { - NODE *new = malloc(sizeof(NODE)); - if (new == NULL) { + NODE *add = malloc(sizeof(NODE)); + if (add == NULL) { return -1; } - new->data = item; - new->previous = list->tail; - list->tail->next = new; - list->tail = new; + add->data = item; + if (list->size == 0) { + list->current = add; + list->head = add; + list->tail = add; + } + else { + add->previous = list->tail; + list->tail->next = add; + list->tail = add; + } list->size++; return 0; diff --git a/main.c b/main.c index 0e59c20..cb305ff 100644 --- a/main.c +++ b/main.c @@ -25,13 +25,12 @@ LIST *receivelist, *sendlist; pthread_mutex_t sendmut, receivemut; void *input(void *arg) { - char msg[512]; - + char msg[30]; while (1) { printf("Type a message: "); - scanf("%s", msg); + fgets(msg, sizeof(msg), stdin); pthread_mutex_lock(&sendmut); - ListAppend(sendlist, msg); + ListAppend(sendlist, &msg); pthread_mutex_unlock(&sendmut); } return 0; @@ -180,7 +179,7 @@ int main(int argc, char* argv[]) { } pthread_create(&input_thread, NULL, input, (void*) msg); pthread_join(input_thread, NULL); - + close(socketfd); close(confd); return 0; From 05e9c8b028175ce18ada53b315b6cf9aedde45f6 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Wed, 9 Jul 2025 19:25:33 -0600 Subject: [PATCH 25/41] added send function --- main.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index cb305ff..3606703 100644 --- a/main.c +++ b/main.c @@ -23,6 +23,8 @@ LIST *receivelist, *sendlist; pthread_mutex_t sendmut, receivemut; +pthread_cond_t sendcv, receivecv; +int sockfd, confd; void *input(void *arg) { char msg[30]; @@ -37,7 +39,13 @@ void *input(void *arg) { } void *sender(void *arg) { - + char *msg; + while (1) { + pthread_mutex_lock(&sendmut); + msg = ListTrim(sendlist); + send(sockfd, msg, 30, NULL); + pthread_mutex_unlock(&sendmut); + } return 0; } @@ -63,7 +71,7 @@ int main(int argc, char* argv[]) { char s[INET6_ADDRSTRLEN]; char *msg; char *remote_machine, *local_port, *remote_port; - int status, socketfd, confd, len; + int status, len; int yes = 1; if (argc != 4) { @@ -72,9 +80,20 @@ int main(int argc, char* argv[]) { return -1; } - pthread_mutex_init(&sendmut, NULL); - pthread_mutex_init(&receivemut, NULL); - + if (pthread_mutex_init(&sendmut, NULL) != 0) { + printf("Error: send mutex init failed\n"); + return -1; + } + if (pthread_mutex_init(&receivemut, NULL) != 0) { + printf("Error: receive mutex init failed\n"); + return -1; + } + if (pthread_cond_init(&sendcv, NULL) != 0) { + printf("Error: send CV init failed\n"); + return -1; + } + + local_port = argv[1]; remote_machine = argv[2]; remote_port = argv[3]; From defa1d8a9d1c1fc89124c3396ffccde5fe6914d6 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Wed, 25 Jun 2025 16:40:34 -0600 Subject: [PATCH 26/41] Added rules for list lib to Makefile --- Makefile | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Makefile b/Makefile index 8d97806..fcc59f2 100644 --- a/Makefile +++ b/Makefile @@ -26,5 +26,18 @@ listtest: listtest.o liblist.a listtest.o: listtest.c $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o listtest.o listtest.c +liblist.a: list_adders.o list_removers.o list_movers.o + ar -rcs liblist.a list_adders.o list_removers.o list_movers.o + +list_adders.o: list_adders.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_adders.o list_adders.c + +list_movers.o: list_movers.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_movers.o list_movers.c + +list_removers.o: list_removers.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_removers.o list_removers.c + + clean: rm -f *.o chatty liblist.a From dc81e4748d22376cf4fb118882ed90598ade9561 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Wed, 25 Jun 2025 16:42:32 -0600 Subject: [PATCH 27/41] updated input thread function --- liblist.a | Bin 17660 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 liblist.a diff --git a/liblist.a b/liblist.a deleted file mode 100644 index 927feaf174ad7085b4deb5d8c28b931d37c7494c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17660 zcmeHOeQaFEao=~RBab@q%d#X=QmmtFN%V*KWtyfG*``8Erffx4ZKq)k+v1TtlZ-?j zeLNbnVZ{dG6q3_67T_QTLbMWs0&WVoaf39DBfv83qShZRf&@t2B0&8|T{uON4@5zP zBuzTM*_p?^;axvG|SeT#jwf$4YIbS=Nlggp|agUJl<7{wnzF6eS{dtT5 zSMSSD7asRr*k8>1$^*rzX?Kh|btE@Fo-fXI6lk!*@#*R5>+bLA?dqZ->h9|5>!tFR z{(c#tk=0M{JGeg)MKnyFB6qu6

#opgE{>b--)pqOPQ5qussC*H`+XOoHuT5) zE)JdAcjwk)j=|GO|n1* z){=|**dwYR!WU7ra1r0A_H95laeC5o*LiNlWzz7z3L>5C95tdgUyzAgNrRO-%S?1$ zi~c1}k9g(w%E~2GZeJhzZ{J#`+*Von6;*C4Q*J9)Zmq2ReN}E<8+vZtqMp~_3ZsTv zv?}e8O0-a)b5RrDj>PHl2Eb7>k30<_)l)9nu)8h#aAsHLz}iF$4a9XWles;UB++C& zHzs^ze};y)Bf6ti71~leS`Vykj;^X5XnCqNT1#`SIoj5+Hj~`4X$#<{4bIgxk~!yU z#VSpe^x7!dkjd=Mz$~=t*24|62Z&uQJ{Z{18rsjm7-ZIjGK+n1uD;hL(`pNs(?CFM z9DuutKD0iFc;0diUvI~?^2!UurbxDv$|#C{-cXMM6A3paingHY6491KBhPDaLaD1= zop(h*vOY@HJex|-rxKq^)tyO22UFX+Q;CbIx<5-r52o6~de(QA+k{n}8 z=1p66hWVMfsfn5VcoqwEs+6C0W3rTOB_k=atw#o}X=xuU!4 z(8sca{kyW=JsmwA-PxY5o}RA$?p@jT`^ex>t|SdRd#=y!oG#7JL1^{@$fhI%V(_rU!RaEtDiopYu6aT=A*@rmi4{{GH8^K(Z_ zh1t%DsZ!ZfZp}?FhP?yShA(Y@ zXtDhv;6&BhpYqLB+ZQg=eooqXgIE8<-oG?0DRAAZ+>d^>q=5ih5S3uU`9Za$E$QNC zOj%pfYzo?#bhL?8pros>fTBOV)t0q25_eV5Pu-(85>5xmCA5VQ$g3RR3&Owy9}*44 zdjy{{_-%qeXYd1p|E1viurQZz~&3WLq6Oo)i35c+J5mX zPyJK}sr*%*b+{gomHz_|$MQNZj|gt%pEU9}3;%Q#`7apxeZrrqBCm5?`#&slZ&Z=T z+5|y9oV7Z`fY;LJqx1pkcmUUR4SYSmh!ppnbC_qKh(7UCiRw21B!YanD!Li3JFS;Jz5nRV7C3gPZ;2FVx zZtxogUnM09*ndvsHVLlw1$NgPT-Rs6!F7)A6&wZZ>;5xrt}4QUfGn1=%)NcA)(3Q<-Ra2`b!a|+br3%8w0;NdeLO=;^0Ad!VJk70AA z`k3#q8O~8+WB;E36Oi?PJGEI1;za>(Fovz{E|RS@e(f1pp?=6B$N1qM+3~xZFl&<_ zw;%)ZV=w_(*@vmkVi5nV`0WaGQMIx-w^ZtX7Y?*Us*nEH(Z}}xF~Y1(g52xk|3xqX zS=nRMR>}W}_&+YX@Q)$2{!b7Fo7zvRGJRYgV2BHaq^y=Fsj-s&pU8sJ{Yq`9o|d@2 zO8P$)eLXi+(?2Wv+OFkx9D*v4`qidar~*+lOl^sev9Che50vL1fP)$UPoA^`3KDI9nk+W8i*e7Mf`2YubEmZ z=}$I!m2bzIzGC$`I)J$PGGpg`z1@9Trsc=Z53gP9!~j>zW9JBpzYhF;e7%aVI3S*- z#`l*OT>q^Tr9{BHm$|gE@HsLl0pJrU0l@i`fakPIz;kvb;5o?>@RDo!Dy=0A(DN*` zbH-g8AdwHyM?OHmIvx1{edGi5kq^R0K0u%G0s6=X=%sB9?zaZ$dDoEuJ=Y~b&vgmV zb6o@U{QfBcdR_;I_Q0Ny?q1PC19h4Ah(j%0Jw5EXZMc@i>BFmX?(l=8MR91}d4CUP z5QVONnJNvC@~HwgU%Qrgb~hNhyHVUm3k7vIxL(|mgMFcc{px_t+*;Yp->R8g12elq zGrP;o+*H}jf2o<90y7<{#>eYK2`T@s)_Rkn^%T( zm)p4~buS?oVL9O~-;^85Lh#Lj`gRDyNUzcEN{4T5-HvLw?TSy9NJKgAWRR!Qcl4zbLq#Dts;?UJ{GD zQJjic(QjSitPMgKd^!-n8dJx*L7V0x@D2}BdAt*V5E}ql`Ed`&@>_+UlG4h5*2wn= z|3Ve{*Npr}gy%Cp)vf*ajQoAV|A&-T{%ShTfb@DtJ?mNpxAJLehrGO2Gh%ZWMUm5S zhCFmP3;sdnE_6Km#Si?3ug`l8PQP4W()q6PKN9?2DHYckyUkr}lkpli^4}5usKMVB ze%9dY#LfwWHwk{q;M;_^xr?2GpEdG_gtxhiPO%@(H;mgx!QT`;usA5``u!Kdb$qn{ z?;HFP;Ulr9^7jjFa}m0JdPH9R>V9&-*ipZu23PyD2LA`~`-I>qa9z5OA-@jNeyaVy zFu2kb+F`n<>+dF}rv4X*b8$l$tPeBRg>x9&?uUhVS>D+%Gcus12`Gfu}r@vTyUe40Kt z2#*6lNb&ui{a??S=y;BZe_S>`dLN%LxXzz52G@Ce-r%}k-Zi+c-{0j@WME8@B_4B0 z=bJVUNX5Pw%JNh(S1p$^obe)uMd4~n~PQq7b4FDW3U^^fzC#UQHt-q(#`D_bp>^3odb@EKYB7(d)2JAQW)W^F?AdC~g; zn1HP8!_;Omh(9fdo~}R_RVzD87+ej|C!}^cP^v!qUq>I?|HlZkHeu(l#sA-d3CPMG zqqa)^hsFPK(S?6ZN$Vfy57^XxQkAJB3!>LJR94HABwb1WB{_`g^Igow*Q)w2R?%;k zj>hi|VnFq@JS+NYU&{f#Pz9t^J%wMP3c6~hsZ)JBF4ipeUD&kxvm$tj+CsAWZ&72V z`}a+`e=mtL?jO$Bs^21bCEsY8#AG9SQ7-sOb1C}sxQ}}?@wXj6bkpuV5I!z11mBJ| zeZ}f?Or*&FQs8XL<^G4z+uu+BMgUzwE=3O^)P(`=Mp-W93UVM#OaF^N{{xUeDlErN zkU5aQW&{ZTLnGk%j~Xw~h-qel*OVQ>_^631E6*&Xe{E)=u2N``s3tX4X z0@o$8z;(?m@Iy~B3%r3xZMAz~QRqe~DGp7S!SkkVJ*tV*!xZeV92c*7nY8#8MjPYD zw4SG;g^#GEjqALnNw&Lj>qpt{h-*Nlk-Jd?;U;t{RoEB(5ort6;|e z&^`#9FNts`mxR*8Sb5FTSUE+*@mqHMxZX#`YnO(^(>^3#w-^#%ZA0Rj@{oAhuj<1{ zIDVyHUmhk8f0n-(O84>krgG8n_xV*L>Ux01V2AWLF)NLzUt=QbHRt%(_s{aL@9#<7 z!oRqW&ZIWqkt%Om8V0{ixZ4J~%VXvAi=Pkb$MyJ~fBa7^uEcTfD~f8%?qZ_a2)8Z% z{VU#fe|-@9vZ3(6PWg7e(jd3Y7d#iUJY9Zsv2NahG*%qMvUQi@eMQ^l_v@Rf4-e4? zR7u~rEd8dvhMw)ey}xhAvmLQuCEdL-9=wTagOqJlLSE%`kH)(=@F9`Yb{`84W)G&P zOx(qAaM|A$*#i87@T>~Y9`Fysyg{4BdiMY%QhAM4?)C5z`EkKjeyi|$mbLcvOa^&5 zwzGyFJAmWSeK({29EU1!)dg>3r8>qN(MW_l!H-+!7GoT+6F(TK-YxCwSM~c1F09jW zPUx4a=D&`=mWu0msvpINNe9&D3m#|KnG}9NO6xZ(IQkOyXTab(&Lalb{`@YMCIe%N zEb$m~oe$bPAQgKglIwFa8Vd&zXgY;c^JJo@Q&jhr81z#1&`p5i( z&6Vn7p2B80w}_4XYt9N7$oj7qOMB0Y$M5pOF43 zva-jht&;y&#s6{9g?~WSKb}vpsr{rXQ>Sc-Ym7r>wLD4EmGnO>hl+yO(?a#Me6foD zmqdT1v9x~{ef6uQ`c?iFs$i+w`Twry+i}tHQ~e86flaI5BpZs3zsg(vx2U1g{p(ue uHHJhH_wPz#X(z?M{$J`!V`=AQ|GHWHYhlN)nHucg1KH!!e?4ba)BkVjzdHl~ From a73aa38678868b734ce7438a30e69ddd6817ccc1 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 01:00:34 -0600 Subject: [PATCH 28/41] fix --- list_adders.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/list_adders.c b/list_adders.c index 1dd7534..ba6c9c5 100644 --- a/list_adders.c +++ b/list_adders.c @@ -1,21 +1,18 @@ #include #include -#include - -LIST *ListCreate(void) { - LIST *new_node_list; + LIST *new_list; - new_node_list = malloc(sizeof(LIST)); - if (!new_node_list) { + new_list = malloc(sizeof(LIST)); + if (!new_list) { return NULL; } - new_node_list->size = 0; - new_node_list->current = 0; - new_node_list->head = 0; - new_node_list->tail = 0; + new_list->size = 0; + new_list->current = 0; + new_list->head = 0; + new_list->tail = 0; - return new_node_list; + return new_list; } int ListAdd(LIST *list, void *item) { From 027f626d14679495cda9529e6a996adeeb3a6831 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 12:49:58 -0600 Subject: [PATCH 29/41] Added basic receive function --- Makefile | 18 ------------------ main.c | 29 ++++++++++++++++++----------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index fcc59f2..0d8259b 100644 --- a/Makefile +++ b/Makefile @@ -19,24 +19,6 @@ list_movers.o: list_movers.c list_removers.o: list_removers.c $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_removers.o list_removers.c - -listtest: listtest.o liblist.a - $(CC) $(CFLAGS) -L. -o listtest listtest.o -llist - -listtest.o: listtest.c - $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o listtest.o listtest.c - -liblist.a: list_adders.o list_removers.o list_movers.o - ar -rcs liblist.a list_adders.o list_removers.o list_movers.o - -list_adders.o: list_adders.c - $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_adders.o list_adders.c - -list_movers.o: list_movers.c - $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_movers.o list_movers.c - -list_removers.o: list_removers.c - $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_removers.o list_removers.c clean: diff --git a/main.c b/main.c index 3606703..90167ab 100644 --- a/main.c +++ b/main.c @@ -43,13 +43,20 @@ void *sender(void *arg) { while (1) { pthread_mutex_lock(&sendmut); msg = ListTrim(sendlist); - send(sockfd, msg, 30, NULL); + send(sockfd, msg, 30, 0); pthread_mutex_unlock(&sendmut); } return 0; } void *receiver(void *arg) { + char *msg; + while (1) { + recv(sockfd, msg, 30, 0); + pthread_mutex_lock(&receivemut); + ListAppend(receivelist, msg); + pthread_mutex_unlock(&receivemut); + } return 0; } @@ -113,19 +120,19 @@ int main(int argc, char* argv[]) { } for (p = servinfo; p != NULL; p = p->ai_next) { - if ((socketfd = socket(p->ai_family, + if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("Server: socket"); continue; } - if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } - if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { - close(socketfd); + if (bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { + close(sockfd); perror("Server: bind"); continue; } @@ -141,14 +148,14 @@ int main(int argc, char* argv[]) { } freeaddrinfo(servinfo); - if (listen(socketfd, BACKLOG) == -1) { + if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sin_size = sizeof their_addr; printf("Waiting for connection...\n"); - confd = accept(socketfd, (struct sockaddr *)&their_addr, &sin_size); + confd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (confd == -1) { perror("accept"); } @@ -169,7 +176,7 @@ int main(int argc, char* argv[]) { exit(1); } for (q = servinfo; q != NULL; q = q->ai_next) { - if ((socketfd = socket(q->ai_family, + if ((sockfd = socket(q->ai_family, q->ai_socktype, q->ai_protocol)) == -1) { perror("Client: socket"); @@ -179,9 +186,9 @@ int main(int argc, char* argv[]) { s, sizeof s); printf("Client: attempting connection to %s\n", s); - if (connect(socketfd, q->ai_addr, q->ai_addrlen) == -1) { + if (connect(sockfd, q->ai_addr, q->ai_addrlen) == -1) { perror("Client: connect"); - close(socketfd); + close(sockfd); continue; } break; @@ -199,7 +206,7 @@ int main(int argc, char* argv[]) { pthread_create(&input_thread, NULL, input, (void*) msg); pthread_join(input_thread, NULL); - close(socketfd); + close(sockfd); close(confd); return 0; } From 5691d848e135b59f19558c122d61fcd89620ad4f Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 17:49:27 -0600 Subject: [PATCH 30/41] changed receive function --- main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.c b/main.c index 90167ab..04f283c 100644 --- a/main.c +++ b/main.c @@ -23,7 +23,6 @@ LIST *receivelist, *sendlist; pthread_mutex_t sendmut, receivemut; -pthread_cond_t sendcv, receivecv; int sockfd, confd; void *input(void *arg) { @@ -50,7 +49,7 @@ void *sender(void *arg) { } void *receiver(void *arg) { - char *msg; + char msg[30]; while (1) { recv(sockfd, msg, 30, 0); pthread_mutex_lock(&receivemut); From 259dd096cbed39b73252d29985235933318e03cc Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 18:56:20 -0600 Subject: [PATCH 31/41] fix --- list_removers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/list_removers.c b/list_removers.c index 7c84239..3a18fb6 100644 --- a/list_removers.c +++ b/list_removers.c @@ -53,11 +53,12 @@ void ListFree(LIST *list) { void *ListTrim(LIST *list) { NODE *tempnode = list->tail->previous; + void *nodedata = list->tail->data; list->tail->previous = NULL; free(list->tail); list->tail = tempnode; list->size--; - return 0; + return nodedata; } void *ListSearch(LIST *list, int (*comparator)(void *, void*), From 71346bdd5f391065cee3615761f9c424f58d70bb Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 19:10:39 -0600 Subject: [PATCH 32/41] time to test --- list_adders.c | 1 + main.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/list_adders.c b/list_adders.c index ba6c9c5..015a87d 100644 --- a/list_adders.c +++ b/list_adders.c @@ -1,5 +1,6 @@ #include #include +LIST *ListCreate(void) { LIST *new_list; new_list = malloc(sizeof(LIST)); diff --git a/main.c b/main.c index 04f283c..2a9fb1a 100644 --- a/main.c +++ b/main.c @@ -59,6 +59,20 @@ void *receiver(void *arg) { return 0; } +void *output(void *arg) { + char msg[30]; + while (1) { + pthread_mutex_lock(&receivemut); + ListFirst(receivelist); + strcpy(msg, ListCurr(receivelist)); + ListRemove(receivelist); + pthread_mutex_unlock(&receivemut); + printf("%s\n", msg); + } + + return 0; +} + void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); @@ -94,11 +108,6 @@ int main(int argc, char* argv[]) { printf("Error: receive mutex init failed\n"); return -1; } - if (pthread_cond_init(&sendcv, NULL) != 0) { - printf("Error: send CV init failed\n"); - return -1; - } - local_port = argv[1]; remote_machine = argv[2]; From 1f810c707ef50ad00f6d5270de124426bfa1b9ba Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 19:29:43 -0600 Subject: [PATCH 33/41] created threads --- main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 2a9fb1a..a2faa9e 100644 --- a/main.c +++ b/main.c @@ -211,8 +211,14 @@ int main(int argc, char* argv[]) { } printf("Connected!\n"); } - pthread_create(&input_thread, NULL, input, (void*) msg); - pthread_join(input_thread, NULL); + pthread_create(&input_thread, NULL, input, NULL); + pthread_create(&send_thread, NULL, sender, NULL); + pthread_create(&receive_thread, NULL, receiver, NULL); + pthread_create(&output_thread, NULL, output, NULL); + pthread_join(input_thread, NULL); + pthread_join(send_thread, NULL); + pthread_join(receive_thread, NULL); + pthread_join(output_thread, NULL); close(sockfd); close(confd); From c2aa3fb11a76f0fe7118625abc9669a9ed60c568 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Thu, 10 Jul 2025 22:19:53 -0600 Subject: [PATCH 34/41] fixed sender issue --- main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index a2faa9e..bd73135 100644 --- a/main.c +++ b/main.c @@ -41,8 +41,14 @@ void *sender(void *arg) { char *msg; while (1) { pthread_mutex_lock(&sendmut); - msg = ListTrim(sendlist); - send(sockfd, msg, 30, 0); + if (ListCount(sendlist) != 0) { + ListFirst(sendlist); + strcpy(msg, ListCurr(sendlist)); + ListRemove(sendlist); + } + else { + continue; + } pthread_mutex_unlock(&sendmut); } return 0; @@ -89,9 +95,8 @@ int main(int argc, char* argv[]) { struct addrinfo *servinfo; struct sockaddr_storage their_addr; char s[INET6_ADDRSTRLEN]; - char *msg; char *remote_machine, *local_port, *remote_port; - int status, len; + int status; int yes = 1; if (argc != 4) { From 7059385ca136e50a7f2d3866c0e1f37b350b7cc7 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Mon, 14 Jul 2025 23:22:04 -0600 Subject: [PATCH 35/41] update output function and fix segfault --- list_movers.c | 16 +++++++++++----- main.c | 12 ++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/list_movers.c b/list_movers.c index 18b9cab..12c220b 100644 --- a/list_movers.c +++ b/list_movers.c @@ -6,13 +6,19 @@ int ListCount(LIST *list) { } void *ListFirst(LIST *list) { - list->current = list->head; - return list->current->data; -} + if (list->size != 0) { + list->current = list->head; + return list->current->data; + } + return NULL; +} void *ListLast(LIST *list) { - list->current = list->tail; - return list->current->data; + if (list->size != 0) { + list->current = list->tail; + return list->current->data; + } + return NULL; } void *ListNext(LIST *list) { diff --git a/main.c b/main.c index bd73135..4bdd83f 100644 --- a/main.c +++ b/main.c @@ -69,11 +69,15 @@ void *output(void *arg) { char msg[30]; while (1) { pthread_mutex_lock(&receivemut); - ListFirst(receivelist); - strcpy(msg, ListCurr(receivelist)); - ListRemove(receivelist); + if (ListCount(receivelist) != 0) { + ListFirst(receivelist); + strcpy(msg, ListCurr(receivelist)); + ListRemove(receivelist); + } pthread_mutex_unlock(&receivemut); - printf("%s\n", msg); + if (ListCount(receivelist) != 0) { + printf("%s\n", msg); + } } return 0; From 288ec07147d905f8cde4607b62bfcf3d0ccfd27c Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 15 Jul 2025 11:08:23 -0600 Subject: [PATCH 36/41] fixed deadlock --- main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main.c b/main.c index 4bdd83f..8c4c36f 100644 --- a/main.c +++ b/main.c @@ -47,6 +47,7 @@ void *sender(void *arg) { ListRemove(sendlist); } else { + pthread_mutex_unlock(&sendmut); continue; } pthread_mutex_unlock(&sendmut); From eac0c934dc45edb5efac09019637372d14142786 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 15 Jul 2025 11:42:10 -0600 Subject: [PATCH 37/41] fixed bug in output and sender --- main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 8c4c36f..b39a0c8 100644 --- a/main.c +++ b/main.c @@ -38,7 +38,7 @@ void *input(void *arg) { } void *sender(void *arg) { - char *msg; + char msg[30]; while (1) { pthread_mutex_lock(&sendmut); if (ListCount(sendlist) != 0) { @@ -74,11 +74,9 @@ void *output(void *arg) { ListFirst(receivelist); strcpy(msg, ListCurr(receivelist)); ListRemove(receivelist); + printf("%s\n", msg); } pthread_mutex_unlock(&receivemut); - if (ListCount(receivelist) != 0) { - printf("%s\n", msg); - } } return 0; From 5b4ad86b2670610694f573f01783addaa0168214 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 15 Jul 2025 12:08:37 -0600 Subject: [PATCH 38/41] fixed pointer issue --- main.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index b39a0c8..40cdea5 100644 --- a/main.c +++ b/main.c @@ -27,11 +27,13 @@ int sockfd, confd; void *input(void *arg) { char msg[30]; + char *copy = malloc(31); while (1) { printf("Type a message: "); - fgets(msg, sizeof(msg), stdin); + fgets(msg, sizeof(msg), stdin); + strcpy(copy, msg); pthread_mutex_lock(&sendmut); - ListAppend(sendlist, &msg); + ListAppend(sendlist, copy); pthread_mutex_unlock(&sendmut); } return 0; @@ -57,11 +59,14 @@ void *sender(void *arg) { void *receiver(void *arg) { char msg[30]; + char *copy = malloc(31); while (1) { recv(sockfd, msg, 30, 0); - pthread_mutex_lock(&receivemut); - ListAppend(receivelist, msg); - pthread_mutex_unlock(&receivemut); + if (msg[0] != '\n' && msg[0] != '\0') { + pthread_mutex_lock(&receivemut); + ListAppend(receivelist, msg); + pthread_mutex_unlock(&receivemut); + } } return 0; } From af6b68fa9b28b57a6f136da75f196f0ff97ccaac Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 15 Jul 2025 12:38:23 -0600 Subject: [PATCH 39/41] cast to string --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 40cdea5..68d859f 100644 --- a/main.c +++ b/main.c @@ -79,7 +79,7 @@ void *output(void *arg) { ListFirst(receivelist); strcpy(msg, ListCurr(receivelist)); ListRemove(receivelist); - printf("%s\n", msg); + printf("%s\n", (char*)msg); } pthread_mutex_unlock(&receivemut); } From af5258fd972a51f6e131381afb0dcba2dcf24711 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Tue, 15 Jul 2025 12:42:10 -0600 Subject: [PATCH 40/41] pointer issue --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 68d859f..1752b83 100644 --- a/main.c +++ b/main.c @@ -72,12 +72,12 @@ void *receiver(void *arg) { } void *output(void *arg) { - char msg[30]; + char *msg; while (1) { pthread_mutex_lock(&receivemut); if (ListCount(receivelist) != 0) { ListFirst(receivelist); - strcpy(msg, ListCurr(receivelist)); + msg = ListCurr(receivelist); ListRemove(receivelist); printf("%s\n", (char*)msg); } From 6086c8ec2cfb72c5efe34372489ad8f0408c571b Mon Sep 17 00:00:00 2001 From: DaneMacFadden <31639805+DaneMacFadden@users.noreply.github.com> Date: Sat, 19 Jul 2025 23:24:00 -0600 Subject: [PATCH 41/41] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bdc543..472edcf 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ It's inspired by an assignment I did in university that was a similar project and is intended to be an exercise in networked and multithreaded programming. Check out Beej's guide to network programming (and his other guides) if you want to build something similar. Much of my code is based on his client and server. -Shoutout James for helping me write the list library back in the day. +Shoutout James for helping me write the list.h file back in the day.