Attachment "select_test.c" to
ticket [1758a0b603]
added by
a3a3el
2014-03-21 15:11:46.
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
char output[1048576];
static int
_connect (const char *host, const char *port)
{
struct addrinfo hints = { .ai_family = AF_INET,
.ai_socktype = SOCK_STREAM },
*result;
int gai_errno = 0;
if ((gai_errno = getaddrinfo (host, port, &hints, &result)))
{
fprintf (stderr, "_connect: getaddrinfo failed: %s\n",
gai_strerror (gai_errno));
return -1;
}
int sock = -1;
if ((sock = socket (result->ai_family,
result->ai_socktype,
result->ai_protocol)) < 0)
{
fprintf (stderr, "_connect: socket failed: %s\n", strerror (errno));
}
else if (connect (sock, result->ai_addr, result->ai_addrlen) < 0)
{
fprintf (stderr, "_connect: connect failed: %s\n", strerror (errno));
close (sock);
sock = -1;
}
freeaddrinfo (result);
if (sock != -1)
{
fprintf (stderr, "_connect: connected to %s:%s.\n", host, port);
int flags;
if ((flags = fcntl (sock, F_GETFL, 0)) == -1)
fprintf (stderr, "_connect: fcntl (F_GETFL) failed: %s\n",
strerror (errno));
else if (fcntl (sock, F_SETFL, flags | O_NONBLOCK) == -1)
fprintf (stderr, "_connect: fcntl (F_SETFL) failed: %s\n",
strerror (errno));
else
return sock;
close (sock);
}
exit (EXIT_FAILURE);
}
static void
_select (int sock)
{
fd_set wfds;
FD_ZERO (&wfds);
FD_SET (sock, &wfds);
int rv;
if ((rv = select (sock + 1,
NULL,
&wfds,
NULL,
&(struct timeval) { .tv_sec = 1 })) < 0)
{
fprintf (stderr, "_select: select failed: %s\n", strerror (errno));
exit (EXIT_FAILURE);
}
fprintf (stderr, "_select: select = %d, FD_ISSET (%d, &wfds) == %d.\n",
rv, sock, FD_ISSET (sock, &wfds));
}
static void
_send (int sock)
{
struct iovec vec = { .iov_base = output, .iov_len = sizeof output };
struct msghdr mhdr = { .msg_iov = &vec, .msg_iovlen = 1 };
for (int i = 0; ; ++i)
{
ssize_t rv;
if ((rv = sendmsg (sock, &mhdr, 0)) < 0)
{
fprintf (stderr, "_send: sendmsg %d failed: %s\n",
i, strerror (errno));
break;
}
else
fprintf (stderr, "_send: sendmsg %d returned: %zd\n",
i, rv);
}
}
static void
_system (const char *fmt, ...)
{
char cmdbuf[64];
va_list ap;
va_start (ap, fmt);
vsprintf (cmdbuf, fmt, ap);
va_end (ap);
fprintf (stderr, "_system: %s\n", cmdbuf);
system (cmdbuf);
}
int
main (int argc, char **argv)
{
if (argc != 4)
exit (EXIT_FAILURE);
const char *host = argv[1],
*port = argv[2],
*netcat = argv[3];
_system ("%s -l %s & sleep 1", netcat, port);
signal (SIGPIPE, SIG_IGN);
int sock = _connect (host, port);
_select (sock);
_system ("pkill -x %s; sleep 1", netcat);
_select (sock);
_send (sock);
_select (sock);
exit (EXIT_SUCCESS);
}