-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhelpers.c
60 lines (51 loc) · 1.37 KB
/
helpers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "options.h"
#include "logging.h"
#include "helpers.h"
#include <fcntl.h>
#include <string.h>
int
enable_nonblocking(int fd) {
int flags;
flags = fcntl(fd, F_GETFL, 0);
if (flags != ERR) {
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
return ERR;
}
int
tcp_listen(uint16_t * port) {
struct sockaddr_in addr;
socklen_t addrlen = sizeof (addr);
int opt;
int fd;
/* Create socket. */
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
return ERR; // LCOV_EXCL_LINE
}
/* Avoid EADDRINUSE. */
opt = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) {
return ERR; // LCOV_EXCL_LINE
}
memset(&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(*port);
if (bind(fd, (struct sockaddr *) &addr, sizeof (addr))) {
return ERR; // LCOV_EXCL_LINE
}
if (*port == 0) {
if (getsockname(fd, (struct sockaddr *) &addr, &addrlen)) {
return ERR; // LCOV_EXCL_LINE
}
*port = ntohs(addr.sin_port);
}
if (listen(fd, TCP_BACKLOG) < 0) {
return ERR; // LCOV_EXCL_LINE
}
if (enable_nonblocking(fd) == ERR) {
return ERR; // LCOV_EXCL_LINE
}
return fd;
}