Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
remzi-arpacidusseau
GitHub Repository: remzi-arpacidusseau/ostep-projects
Path: blob/master/concurrency-webserver/src/io_helper.c
909 views
1
#include "io_helper.h"
2
3
ssize_t readline(int fd, void *buf, size_t maxlen) {
4
char c;
5
char *bufp = buf;
6
int n;
7
for (n = 0; n < maxlen - 1; n++) { // leave room at end for '\0'
8
int rc;
9
if ((rc = read_or_die(fd, &c, 1)) == 1) {
10
*bufp++ = c;
11
if (c == '\n')
12
break;
13
} else if (rc == 0) {
14
if (n == 1)
15
return 0; /* EOF, no data read */
16
else
17
break; /* EOF, some data was read */
18
} else
19
return -1; /* error */
20
}
21
*bufp = '\0';
22
return n;
23
}
24
25
26
int open_client_fd(char *hostname, int port) {
27
int client_fd;
28
struct hostent *hp;
29
struct sockaddr_in server_addr;
30
31
if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
32
return -1;
33
34
// Fill in the server's IP address and port
35
if ((hp = gethostbyname(hostname)) == NULL)
36
return -2; // check h_errno for cause of error
37
bzero((char *) &server_addr, sizeof(server_addr));
38
server_addr.sin_family = AF_INET;
39
bcopy((char *) hp->h_addr,
40
(char *) &server_addr.sin_addr.s_addr, hp->h_length);
41
server_addr.sin_port = htons(port);
42
43
// Establish a connection with the server
44
if (connect(client_fd, (sockaddr_t *) &server_addr, sizeof(server_addr)) < 0)
45
return -1;
46
return client_fd;
47
}
48
49
int open_listen_fd(int port) {
50
// Create a socket descriptor
51
int listen_fd;
52
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
53
fprintf(stderr, "socket() failed\n");
54
return -1;
55
}
56
57
// Eliminates "Address already in use" error from bind
58
int optval = 1;
59
if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &optval, sizeof(int)) < 0) {
60
fprintf(stderr, "setsockopt() failed\n");
61
return -1;
62
}
63
64
// Listen_fd will be an endpoint for all requests to port on any IP address for this host
65
struct sockaddr_in server_addr;
66
bzero((char *) &server_addr, sizeof(server_addr));
67
server_addr.sin_family = AF_INET;
68
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
69
server_addr.sin_port = htons((unsigned short) port);
70
if (bind(listen_fd, (sockaddr_t *) &server_addr, sizeof(server_addr)) < 0) {
71
fprintf(stderr, "bind() failed\n");
72
return -1;
73
}
74
75
// Make it a listening socket ready to accept connection requests
76
if (listen(listen_fd, 1024) < 0) {
77
fprintf(stderr, "listen() failed\n");
78
return -1;
79
}
80
return listen_fd;
81
}
82
83
84
85