Skip to content

Commit 40d9346

Browse files
author
lcthw
committed
Syncing the code with what was actually in the videos.
1 parent 4305a58 commit 40d9346

File tree

33 files changed

+1396
-772
lines changed

33 files changed

+1396
-772
lines changed

ex48b/statserve/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
CFLAGS=-g -O2 -Wall -Wextra -I/usr/local/include -Isrc -rdynamic $(OPTFLAGS)
12
LIBS=-llcthw $(OPTLIBS)
23
LDFLAGS=-L/usr/local/lib $(LIBS)
34
PREFIX?=/usr/local
@@ -17,6 +18,8 @@ all: $(TARGET) $(SO_TARGET) tests bin/statserve
1718
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
1819
dev: all
1920

21+
bin/statserve: $(TARGET)
22+
2023
$(TARGET): CFLAGS += -fPIC
2124
$(TARGET): build $(OBJECTS)
2225
ar rcs $@ $(OBJECTS)
@@ -25,8 +28,6 @@ $(TARGET): build $(OBJECTS)
2528
$(SO_TARGET): $(TARGET) $(OBJECTS)
2629
$(CC) -shared -o $@ $(LDFLAGS) $(LIBS) $(OBJECTS)
2730

28-
bin/statserve: $(TARGET)
29-
3031
build:
3132
@mkdir -p build
3233
@mkdir -p bin

ex48b/statserve/bin/statserve.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
#include <statserve.h>
1+
#include <stdio.h>
22
#include <lcthw/dbg.h>
3+
#include "statserve.h"
4+
#include "net.h"
35

46

57
int main(int argc, char *argv[])
@@ -14,5 +16,6 @@ int main(int argc, char *argv[])
1416
return 0;
1517

1618
error:
19+
1720
return 1;
1821
}

ex48b/statserve/src/net.c

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1+
#include <stdlib.h>
2+
#include <sys/select.h>
3+
#include <stdio.h>
14
#include <lcthw/ringbuffer.h>
2-
#include <lcthw/bstrlib.h>
35
#include <lcthw/dbg.h>
6+
#include <sys/socket.h>
7+
#include <sys/types.h>
8+
#include <sys/uio.h>
9+
#include <arpa/inet.h>
10+
#include <netdb.h>
411
#include <unistd.h>
512
#include <fcntl.h>
613
#include "net.h"
714

815
struct tagbstring NL = bsStatic("\n");
916
struct tagbstring CRLF = bsStatic("\r\n");
1017

11-
1218
int nonblock(int fd)
1319
{
1420
int flags = fcntl(fd, F_GETFL, 0);
@@ -22,6 +28,31 @@ int nonblock(int fd)
2228
return -1;
2329
}
2430

31+
int client_connect(char *host, char *port)
32+
{
33+
int rc = 0;
34+
struct addrinfo *addr = NULL;
35+
36+
rc = getaddrinfo(host, port, NULL, &addr);
37+
check(rc == 0, "Failed to lookup %s:%s", host, port);
38+
39+
int sock = socket(AF_INET, SOCK_STREAM, 0);
40+
check(sock >= 0, "Cannot create a socket.");
41+
42+
rc = connect(sock, addr->ai_addr, addr->ai_addrlen);
43+
check(rc == 0, "Connect failed.");
44+
45+
rc = nonblock(sock);
46+
check(rc == 0, "Can't set nonblocking.");
47+
48+
freeaddrinfo(addr);
49+
return sock;
50+
51+
error:
52+
freeaddrinfo(addr);
53+
return -1;
54+
}
55+
2556
int read_some(RingBuffer * buffer, int fd, int is_socket)
2657
{
2758
int rc = 0;
@@ -73,23 +104,28 @@ int write_some(RingBuffer * buffer, int fd, int is_socket)
73104
return -1;
74105
}
75106

76-
77107
int attempt_listen(struct addrinfo *info)
78108
{
79-
int sockfd = 0;
109+
int sockfd = -1; // default fail
80110
int rc = -1;
81111
int yes = 1;
82112

113+
check(info != NULL, "Invalid addrinfo.");
114+
115+
// create a socket with the addrinfo
83116
sockfd = socket(info->ai_family, info->ai_socktype,
84117
info->ai_protocol);
85-
check_debug(sockfd != -1, "Failed to bind to address result. Trying more.");
118+
check_debug(sockfd != -1, "Failed to bind to address. Trying more.");
86119

120+
// set the SO_REUSEADDR option on the socket
87121
rc = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
88-
check_debug(rc == 0, "Failed to set SO_REISEADDR.");
122+
check_debug(rc == 0, "Failed to set SO_REUSADDR.");
89123

124+
// attempt to bind to it
90125
rc = bind(sockfd, info->ai_addr, info->ai_addrlen);
91-
check_debug(rc == 0, "Failed to bind socket.");
92-
126+
check_debug(rc == 0, "Failed to find socket.");
127+
128+
// finally listen with a backlog
93129
rc = listen(sockfd, BACKLOG);
94130
check_debug(rc == 0, "Failed to listen to socket.");
95131

@@ -99,10 +135,11 @@ int attempt_listen(struct addrinfo *info)
99135
return -1;
100136
}
101137

138+
102139
int server_listen(const char *host, const char *port)
103140
{
104141
int rc = 0;
105-
int sockfd = -1;
142+
int sockfd = -1; // default fail value
106143
struct addrinfo *info = NULL;
107144
struct addrinfo *next_p = NULL;
108145
struct addrinfo addr = {
@@ -111,51 +148,26 @@ int server_listen(const char *host, const char *port)
111148
.ai_flags = AI_PASSIVE
112149
};
113150

114-
check(host != NULL, "Must give a valid host.");
115-
check(port != NULL, "Must have a valid port.");
151+
check(host != NULL, "Invalid host.");
152+
check(port != NULL, "Invalid port.");
116153

154+
// get the address info for host and port
117155
rc = getaddrinfo(NULL, port, &addr, &info);
118156
check(rc == 0, "Failed to get address info for connect.");
119-
157+
158+
// cycle through the available list to find one
120159
for(next_p = info; next_p != NULL; next_p = next_p->ai_next)
121160
{
161+
// attempt to listen to each one
122162
sockfd = attempt_listen(next_p);
123163
if(sockfd != -1) break;
124164
}
125165

166+
// either we found one and were able to listen or nothing.
126167
check(sockfd != -1, "All possible addresses failed.");
127168

169+
error: //fallthrough
128170
if(info) freeaddrinfo(info);
171+
// this gets set by the above to either -1 or valid
129172
return sockfd;
130-
131-
error: // fallthrough
132-
if(info) freeaddrinfo(info);
133-
return -1;
134-
}
135-
136-
137-
int client_connect(char *host, char *port)
138-
{
139-
int rc = 0;
140-
struct addrinfo *addr = NULL;
141-
142-
rc = getaddrinfo(host, port, NULL, &addr);
143-
check(rc == 0, "Failed to lookup %s:%s", host, port);
144-
145-
int sock = socket(AF_INET, SOCK_STREAM, 0);
146-
check(sock >= 0, "Cannot create a socket.");
147-
148-
rc = connect(sock, addr->ai_addr, addr->ai_addrlen);
149-
check(rc == 0, "Connect failed.");
150-
151-
rc = nonblock(sock);
152-
check(rc == 0, "Can't set nonblocking.");
153-
154-
freeaddrinfo(addr);
155-
return sock;
156-
157-
error:
158-
freeaddrinfo(addr);
159-
return -1;
160173
}
161-

ex48b/statserve/src/net.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
#ifndef _statserve_net_h
2-
#define _statserve_net_h
1+
#ifndef _net_h
2+
#define _net_h
33

4-
#include <netdb.h>
4+
#include <lcthw/ringbuffer.h>
55

66
#define BACKLOG 10
77

88
int nonblock(int fd);
9-
9+
int client_connect(char *host, char *port);
1010
int read_some(RingBuffer * buffer, int fd, int is_socket);
11-
1211
int write_some(RingBuffer * buffer, int fd, int is_socket);
13-
14-
int attempt_listen(struct addrinfo *info);
15-
1612
int server_listen(const char *host, const char *port);
1713

1814
#endif

ex48b/statserve/src/statserve.c

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,89 @@
1-
#include <lcthw/ringbuffer.h>
1+
#include <stdio.h>
2+
#include <ctype.h>
23
#include <lcthw/dbg.h>
34
#include <unistd.h>
45
#include <stdlib.h>
5-
#include "statserve.h"
6-
#include "net.h"
76
#include <signal.h>
87
#include <sys/wait.h>
9-
#include <stdlib.h>
8+
#include "net.h"
9+
#include <netdb.h>
1010

1111
const int RB_SIZE = 1024 * 10;
1212

13-
int client_handler(int fd)
13+
void handle_sigchild(int sig) {
14+
sig = 0; // ignore it
15+
while(waitpid(-1, NULL, WNOHANG) > 0) {
16+
}
17+
}
18+
19+
void client_handler(int client_fd)
1420
{
1521
int rc = 0;
22+
// need a ringbuffer for the input
1623
RingBuffer *sock_rb = RingBuffer_create(RB_SIZE);
17-
// child process
1824

19-
while(read_some(sock_rb, fd, 1) != -1) {
20-
if(write_some(sock_rb, fd, 1) == -1) {
21-
log_info("Client closed.");
25+
// read_some in a loop
26+
while(read_some(sock_rb, client_fd, 1) != -1) {
27+
// write_it back off the ringbuffer
28+
if(write_some(sock_rb, client_fd, 1) == -1) {
29+
debug("Client closed.");
2230
break;
2331
}
2432
}
2533

26-
rc = close(fd);
27-
check(rc != -1, "Failed to close fd.");
34+
// close the socket
35+
rc = close(client_fd);
36+
check(rc != -1, "Failed to close the socket.");
2837

2938
error: // fallthrough
3039
if(sock_rb) RingBuffer_destroy(sock_rb);
31-
exit(0);
32-
}
33-
34-
void handle_sigchld(int sig) {
35-
while(waitpid(-1, NULL, WNOHANG) > 0) {
36-
}
40+
exit(0); // just exit the child process
3741
}
3842

3943
int echo_server(const char *host, const char *port)
4044
{
45+
int rc = 0;
4146
struct sockaddr_in client_addr;
4247
socklen_t sin_size = sizeof(client_addr);
4348
int server_socket = 0;
4449
int client_fd = 0;
45-
int rc = 0;
4650

4751
struct sigaction sa = {
48-
.sa_handler = handle_sigchld,
52+
.sa_handler = handle_sigchild,
4953
.sa_flags = SA_RESTART | SA_NOCLDSTOP
5054
};
51-
sigemptyset(&sa.sa_mask);
5255

56+
check(host != NULL, "Invalid host.");
57+
check(port != NULL, "Invalid port.");
58+
59+
// create a sigaction that handles SIGCHLD
60+
sigemptyset(&sa.sa_mask);
5361
rc = sigaction(SIGCHLD, &sa, 0);
5462
check(rc != -1, "Failed to setup signal handler for child processes.");
5563

64+
// listen on the given port and host
5665
server_socket = server_listen(host, port);
57-
check(server_socket >= 0, "bind to %s:%s failed.",
58-
host, port);
66+
check(server_socket >= 0, "bind to %s:%s failed.", host, port);
5967

60-
while (1) {
61-
client_fd = accept(server_socket, (struct sockaddr *)&client_addr, &sin_size);
68+
while(1) {
69+
// accept the connection
70+
client_fd = accept(server_socket, (struct sockaddr *)&client_addr, &sin_size);
6271
check(client_fd >= 0, "Failed to accept connection.");
6372

64-
log_info("Client connected.");
73+
debug("Client connected.");
6574

6675
rc = fork();
67-
check(rc != -1, "Failed to fork!");
68-
6976
if(rc == 0) {
70-
// in the child process
71-
close(server_socket);
77+
// child process
78+
close(server_socket); // don't need this
79+
// handle the client
7280
client_handler(client_fd);
7381
} else {
7482
// server process
75-
close(client_fd);
83+
close(client_fd); // don't need this
7684
}
7785
}
7886

79-
return 0;
80-
81-
error:
87+
error: // fallthrough
8288
return -1;
8389
}
84-

ex48b/statserve/src/statserve.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@
33

44
int echo_server(const char *host, const char *port);
55

6-
76
#endif

ex48b/statserve/tests/minunit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#define _minunit_h
44

55
#include <stdio.h>
6-
#include <dbg.h>
6+
#include <lcthw/dbg.h>
77
#include <stdlib.h>
88

99
#define mu_suite_start() char *message = NULL

ex48b/statserve/tests/statserve_tests.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
#include "minunit.h"
2-
#include <statserve.h>
2+
#include <dlfcn.h>
3+
#include "statserve.h"
34

4-
5-
char *test_statserve()
5+
char *test_dummy()
66
{
7-
8-
// mu_assert(echo_server("127.0.0.1", "7899") == 0, "Failed to start echo server.");
9-
107
return NULL;
118
}
129

13-
1410
char *all_tests()
1511
{
1612
mu_suite_start();
1713

18-
mu_run_test(test_statserve);
14+
mu_run_test(test_dummy);
1915

2016
return NULL;
2117
}

0 commit comments

Comments
 (0)