maint: update copyright
[gnulib.git] / tests / test-nonblocking-socket-main.c
1 /* Test for nonblocking read and write on sockets.
2
3    Copyright (C) 2011-2014 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 #include "progname.h"
37
38 #include "macros.h"
39 #include "socket-server.h"
40 #include "test-nonblocking-socket.h"
41 #define PROG_ROLE "main"
42 #include "test-nonblocking-writer.h"
43
44 int
45 main (int argc, char *argv[])
46 {
47   const char *child_path;
48   int test;
49   int server;
50   int port;
51   int child;
52   int server_socket;
53   int exitcode;
54
55   set_program_name (argv[0]);
56
57   child_path = argv[1];
58   test = atoi (argv[2]);
59
60   /* Create a server socket.  */
61   server = create_server (0, 1, &port);
62
63   /* Spawn the child process.  */
64   {
65     char port_arg[10+1];
66     const char *child_argv[4];
67
68     sprintf (port_arg, "%u", port);
69     child_argv[0] = child_path;
70     child_argv[1] = argv[2];
71     child_argv[2] = port_arg;
72     child_argv[3] = NULL;
73
74 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
75     child = spawnvpe (P_NOWAIT, child_path, child_argv,
76                       (const char **) environ);
77     ASSERT (child >= 0);
78 #else
79     {
80       pid_t child_pid;
81       int err =
82         posix_spawnp (&child_pid, child_path, NULL, NULL, (char **) child_argv,
83                       environ);
84       ASSERT (err == 0);
85       child = child_pid;
86     }
87 #endif
88   }
89
90   /* Accept a connection from the child process.  */
91   server_socket = create_server_socket (server);
92
93   /* Prepare the file descriptor.  */
94   if (test & 1)
95     ASSERT (set_nonblocking_flag (server_socket, true) >= 0);
96
97 #if ENABLE_DEBUGGING
98 # ifdef SO_SNDBUF
99   {
100     int value;
101     socklen_t value_len = sizeof (value);
102     if (getsockopt (server_socket, SOL_SOCKET, SO_SNDBUF, &value, &value_len) >= 0)
103       fprintf (stderr, "SO_SNDBUF = %d\n", value);
104   }
105 # endif
106 # ifdef SO_RCVBUF
107   {
108     int value;
109     socklen_t value_len = sizeof (value);
110     if (getsockopt (server_socket, SOL_SOCKET, SO_RCVBUF, &value, &value_len) >= 0)
111       fprintf (stderr, "SO_RCVBUF = %d\n", value);
112   }
113 # endif
114 #endif
115
116   exitcode =
117     main_writer_loop (test, SOCKET_DATA_BLOCK_SIZE, server_socket,
118                       SOCKET_HAS_LARGE_BUFFER);
119
120   {
121     int err =
122       wait_subprocess (child, child_path, false, false, false, false, NULL);
123     ASSERT (err == 0);
124   }
125
126   return exitcode;
127 }