finalise NEWS.stable
[gnulib.git] / tests / test-nonblocking-socket-main.c
1 /* Test for nonblocking read and write on sockets.
2
3    Copyright (C) 2011 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include <errno.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/time.h>
26 #include <sys/socket.h>
27
28 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
29 # include <process.h>
30 #else
31 # include <spawn.h>
32 #endif
33
34 #include "nonblocking.h"
35 #include "wait-process.h"
36
37 #include "macros.h"
38 #include "socket-server.h"
39 #include "test-nonblocking-socket.h"
40 #define PROG_ROLE "main"
41 #include "test-nonblocking-writer.h"
42
43 int
44 main (int argc, char *argv[])
45 {
46   const char *child_path = argv[1];
47   int test = atoi (argv[2]);
48   int server;
49   int port;
50   int child;
51   int server_socket;
52   int exitcode;
53
54   /* Create a server socket.  */
55   server = create_server (0, 1, &port);
56
57   /* Spawn the child process.  */
58   {
59     char port_arg[10+1];
60     const char *child_argv[4];
61
62     sprintf (port_arg, "%u", port);
63     child_argv[0] = child_path;
64     child_argv[1] = argv[2];
65     child_argv[2] = port_arg;
66     child_argv[3] = NULL;
67
68 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
69     child = spawnvpe (P_NOWAIT, child_path, child_argv,
70                       (const char **) environ);
71     ASSERT (child >= 0);
72 #else
73     {
74       pid_t child_pid;
75       int err =
76         posix_spawnp (&child_pid, child_path, NULL, NULL, (char **) child_argv,
77                       environ);
78       ASSERT (err == 0);
79       child = child_pid;
80     }
81 #endif
82   }
83
84   /* Accept a connection from the child process.  */
85   server_socket = create_server_socket (server);
86
87   /* Prepare the file descriptor.  */
88   if (test & 1)
89     ASSERT (set_nonblocking_flag (server_socket, true) >= 0);
90
91 #if ENABLE_DEBUGGING
92 # ifdef SO_SNDBUF
93   {
94     int value;
95     socklen_t value_len = sizeof (value);
96     if (getsockopt (server_socket, SOL_SOCKET, SO_SNDBUF, &value, &value_len) >= 0)
97       fprintf (stderr, "SO_SNDBUF = %d\n", value);
98   }
99 # endif
100 # ifdef SO_RCVBUF
101   {
102     int value;
103     socklen_t value_len = sizeof (value);
104     if (getsockopt (server_socket, SOL_SOCKET, SO_RCVBUF, &value, &value_len) >= 0)
105       fprintf (stderr, "SO_RCVBUF = %d\n", value);
106   }
107 # endif
108 #endif
109
110   exitcode =
111     main_writer_loop (test, SOCKET_DATA_BLOCK_SIZE, server_socket,
112                       SOCKET_HAS_LARGE_BUFFER);
113
114   {
115     int err =
116       wait_subprocess (child, child_path, false, false, false, false, NULL);
117     ASSERT (err == 0);
118   }
119
120   return exitcode;
121 }