3 /* linker: color.o debug.o */
8 #ifdef _WIN32 /* Windows */
14 #include <sys/types.h>
15 #include <sys/socket.h>
22 #ifdef _WIN32 /* Windows */
23 typedef SOCKET socket_t
;
30 #define BUFFER_SIZE 4096
36 char *progname
= NULL
;
43 FILE *fid
= ret
? stderr
: stdout
;
44 fprintf (fid
, "usage: %s\n", progname
);
45 fprintf (fid
, " -h : help message\n");
46 fprintf (fid
, " -p : port number (%d)\n", port
);
47 fprintf (fid
, " -v : verbose level (%d)\n", verbose
);
52 /* open listening socket */
54 socket_t
open_listening_socket (int port
)
56 #ifdef _WIN32 /* Windows */
58 WSAStartup (MAKEWORD(2,0), &WSAData
);
59 assert (INVALID_SOCKET
== (socket_t
)-1);
62 VERBOSE (DEBUG
, fprintf (stdout
, "Opening socket\n"));
63 #ifdef _WIN32 /* Windows */
64 socket_t sock
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
65 if (sock
== INVALID_SOCKET
)
68 socket_t sock
= socket (PF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
73 struct sockaddr_in addr
= {0};
74 #ifdef _WIN32 /* Windows */
75 addr
.sin_family
= AF_INET
;
77 addr
.sin_family
= PF_INET
;
79 addr
.sin_port
= htons (port
);
80 addr
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
82 VERBOSE (DEBUG
, fprintf (stdout
, "Binding socket\n"));
83 int rc
= bind (sock
, (struct sockaddr
*)&addr
, sizeof (addr
));
84 #ifdef _WIN32 /* Windows */
85 if (rc
== SOCKET_ERROR
) {
86 VERBOSE (ERROR
, fprintf (stderr
, "error: %d\n", WSAGetLastError ()));
87 if (closesocket (sock
) == SOCKET_ERROR
) {
88 VERBOSE (ERROR
, fprintf (stderr
, "error: %d\n", WSAGetLastError ()));
92 VERBOSE (ERROR
, fprintf (stderr
, "error: %d\n", errno
));
98 VERBOSE (DEBUG
, fprintf (stdout
, "Configuring socket\n"));
99 #ifdef _WIN32 /* Windows */
101 fcntl (sock
, F_SETFL
, O_NONBLOCK
);
104 rc
= setsockopt (sock
, IPPROTO_TCP
, TCP_NODELAY
, (char *)&val
, sizeof (val
));
106 VERBOSE (ERROR
, fprintf (stderr
, "%s\n", "setsockopt/TCP_NODELAY"));
107 #ifdef _WIN32 /* Windows */
118 /* close listening socket */
119 void close_listening_socket (socket_t sock
)
121 #ifdef _WIN32 /* Windows */
131 int main (int argc
, char *argv
[])
139 while (progname
[i
] != '\0') {
140 if ((progname
[i
] == '/') || (progname
[i
] == '\\')) {
148 /* argument processing */
151 char *arg
= *(++argv
);
153 VERBOSE (ERROR
, fprintf (stderr
, "%s: invalid option -- '%s'\n", progname
, arg
); usage (1));
159 arg
= (arg
[2]) ? arg
+ 2 : (--argc
> 0) ? *(++argv
) : NULL
;
161 VERBOSE (ERROR
, fprintf (stderr
, "%s: missing port number\n", progname
); usage (1));
166 VERBOSE (ERROR
, fprintf (stderr
, "%s: incorrect port number (%s)\n", progname
, arg
); usage (1));
171 arg
= (arg
[2]) ? arg
+ 2 : (--argc
> 0) ? *(++argv
) : NULL
;
173 VERBOSE (ERROR
, fprintf (stderr
, "%s: missing verbose level\n", progname
); usage (1));
176 verbose
= atoi (arg
);
180 return usage (c
!= 'h');
184 VERBOSE (DEBUG
, fprintf (stdout
, "Initializing socket\n"));
185 socket_t sock
= open_listening_socket (port
);
186 if (sock
== (socket_t
)-1) {
187 VERBOSE (ERROR
, fprintf (stderr
, "Can't open listening socket\n"));
191 VERBOSE (INFO
, fprintf (stdout
, "Listening socket on port %d\n", port
));
194 VERBOSE (DEBUG
, fprintf (stdout
, "Closing socket\n"));
195 close_listening_socket (sock
);
200 // test: webserver.exe -h
201 // test: webserver.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
202 // test: webserver.exe -_ 2> /dev/null | wc -l | xargs test 0 =
203 // test: webserver.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
204 // test: webserver.exe error 2>&1 | grep -q 'invalid option'
205 // test: webserver.exe -v 2>&1 | grep -q 'missing verbose level'
206 // test: webserver.exe -p 2>&1 | grep -q 'missing port number'
207 // test: webserver.exe -p -1 2>&1 | grep -q 'incorrect port number'
208 // test: webserver.exe | grep -q 'Listening socket on port 8080'
209 // test: webserver.exe -p 8000 | grep -q 'Listening socket on port 8000'
211 /* vim: set ts=4 sw=4 et: */