cleaning
[webserver.git] / server.c
1 /* depend: */
2 /* cflags: */
3 /* linker: color.o debug.o */
4
5 #include <assert.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #ifdef _WIN32 /* Windows */
9 #include <winsock2.h>
10 #include <ws2tcpip.h>
11 #else /* Posix */
12 #include <errno.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <netinet/ip.h>
16 #include <netinet/tcp.h>
17 //#include <sys/types.h>
18 //#include <sys/socket.h>
19 #endif
20
21 #include "debug.h"
22
23 #include "server.h"
24
25 /* types */
26
27 #ifdef _WIN32 /* Windows */
28 typedef SOCKET socket_t;
29 #define PF_INET AF_INET
30 #define ERRNO (WSAGetLastError ())
31 #else /* Posix */
32 typedef int socket_t;
33 #define closesocket close
34 #define ERRNO errno
35 #define INVALID_SOCKET -1
36 #define SOCKET_ERROR -1
37 #endif
38
39 /* constants */
40
41 #define BUFFER_SIZE 4096
42
43 /* macros */
44
45 /* gobal variables */
46
47 /* open listening socket */
48
49 socket_t open_listening_socket (int port)
50 {
51 #ifdef _WIN32 /* Windows */
52 WSADATA WSAData;
53 WSAStartup (MAKEWORD(2,0), &WSAData);
54 assert (INVALID_SOCKET == (socket_t)-1);
55 assert (SOCKET_ERROR == -1);
56 #endif
57
58 VERBOSE (DEBUG, fprintf (stdout, "Opening socket\n"));
59 socket_t sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
60 if (sock == INVALID_SOCKET) {
61 return -1;
62 }
63
64 struct sockaddr_in addr = {0};
65 addr.sin_family = PF_INET;
66 addr.sin_port = htons (port);
67 addr.sin_addr.s_addr = htonl (INADDR_ANY);
68
69 VERBOSE (DEBUG, fprintf (stdout, "Binding socket\n"));
70 int rc = bind (sock, (struct sockaddr *)&addr, sizeof (addr));
71 if (rc == SOCKET_ERROR) {
72 VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
73 rc = closesocket (sock);
74 if (rc == SOCKET_ERROR) {
75 VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
76 }
77 return -1;
78 }
79
80 VERBOSE (DEBUG, fprintf (stdout, "Configuring socket\n"));
81 #ifndef _WIN32 /* Posix */
82 fcntl (sock, F_SETFL, O_NONBLOCK);
83 #endif
84 int val = 1;
85 rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val));
86 if (rc < 0) {
87 VERBOSE (ERROR, fprintf (stderr, "%s\n", "setsockopt/TCP_NODELAY"));
88 closesocket (sock);
89 if (rc == SOCKET_ERROR) {
90 VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
91 }
92 return -1;
93 }
94
95 return sock;
96 }
97
98 /* close listening socket */
99 void close_listening_socket (socket_t sock)
100 {
101 int rc = closesocket (sock);
102 if (rc == SOCKET_ERROR) {
103 VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
104 }
105 #ifdef _WIN32 /* Windows */
106 WSACleanup ();
107 #endif
108 }
109
110 /* vim: set ts=4 sw=4 et: */