spawn: Use special invocation for <spawn.h> on OS/2 kLIBC.
[gnulib.git] / tests / test-nonblocking-socket-main.c
blob90b60fc8bb49d205b16fb95ed8d603a7a9ee6e48
1 /* Test for nonblocking read and write on sockets.
3 Copyright (C) 2011-2021 Free Software Foundation, Inc.
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.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 #include <config.h>
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>
28 #if defined _WIN32 && ! defined __CYGWIN__
29 # include <process.h>
30 #else
31 # include <spawn.h>
32 #endif
34 #include "nonblocking.h"
35 #include "wait-process.h"
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"
43 int
44 main (int argc, char *argv[])
46 const char *child_path;
47 int test;
48 int server;
49 int port;
50 pid_t child;
51 int server_socket;
52 int exitcode;
54 child_path = argv[1];
55 test = atoi (argv[2]);
57 /* Create a server socket. */
58 server = create_server (0, 1, &port);
60 /* Spawn the child process. */
62 char port_arg[10+1];
63 const char *child_argv[4];
65 sprintf (port_arg, "%u", port);
66 child_argv[0] = child_path;
67 child_argv[1] = argv[2];
68 child_argv[2] = port_arg;
69 child_argv[3] = NULL;
71 #if defined _WIN32 && ! defined __CYGWIN__
72 child = _spawnvpe (P_NOWAIT, child_path, child_argv,
73 (const char **) environ);
74 ASSERT (child >= 0);
75 #else
77 pid_t child_pid;
78 int err =
79 posix_spawnp (&child_pid, child_path, NULL, NULL, (char **) child_argv,
80 environ);
81 ASSERT (err == 0);
82 child = child_pid;
84 #endif
87 /* Accept a connection from the child process. */
88 server_socket = create_server_socket (server);
90 /* Prepare the file descriptor. */
91 if (test & 1)
92 ASSERT (set_nonblocking_flag (server_socket, true) >= 0);
94 #if ENABLE_DEBUGGING
95 # ifdef SO_SNDBUF
97 int value;
98 socklen_t value_len = sizeof (value);
99 if (getsockopt (server_socket, SOL_SOCKET, SO_SNDBUF, &value, &value_len) >= 0)
100 fprintf (stderr, "SO_SNDBUF = %d\n", value);
102 # endif
103 # ifdef SO_RCVBUF
105 int value;
106 socklen_t value_len = sizeof (value);
107 if (getsockopt (server_socket, SOL_SOCKET, SO_RCVBUF, &value, &value_len) >= 0)
108 fprintf (stderr, "SO_RCVBUF = %d\n", value);
110 # endif
111 #endif
113 exitcode =
114 main_writer_loop (test, SOCKET_DATA_BLOCK_SIZE, server_socket,
115 SOCKET_HAS_LARGE_BUFFER);
118 int err =
119 wait_subprocess (child, child_path, false, false, false, false, NULL);
120 ASSERT (err == 0);
123 return exitcode;