Call to accept() does not time out when setting SO_RCVTIMEO on a socket
Dimitri Staessens
dimitri.staessens at intec.ugent.be
Thu Dec 8 12:43:57 UTC 2016
Dear devs,
I'm trying to get an accept() call to time out using setsockopt.
On Linux, the example below terminates:
[dstaesse at phoneutria]$ gcc accept_st.c -o accept_st
[dstaesse at phoneutria]$ ./accept_st
Timeout is 0:100000.
Check is 0:103333.
Accept returned: Resource temporarily unavailable.
Accept returned: Resource temporarily unavailable.
Accept returned: Resource temporarily unavailable.
Bye.
On FreeBSD 11.0-RELEASE however, it hangs on the accept() forever.
Is this a known issue?
Thanks for your help,
Dimitri
--- example source:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/un.h>
#define TIMEOUT 100 /* ms */
#define RUNNING 0
#define SHUTDOWN 1
#define FN "/tmp/accept_st_socket"
int sfd;
void main(void)
{
int count = 0;
int cfd;
struct timeval tv = {(TIMEOUT / 1000), (TIMEOUT % 1000) * 1000};
struct timeval check;
socklen_t len = sizeof(check);
struct sockaddr_un serv_addr;
printf("Timeout is %lu:%lu.\n", tv.tv_sec, tv.tv_usec);
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd < 0) {
printf("Failed to open socket: %s.\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (access(FN, F_OK) != -1) {
/* File exists */
if (unlink(FN))
exit(EXIT_FAILURE);
}
serv_addr.sun_family = AF_UNIX;
sprintf(serv_addr.sun_path, "%s", FN);
if (bind(sfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) {
printf("Failed to bind socket: %s.\n", strerror(errno));
close(sfd);
exit(EXIT_FAILURE);
}
if (listen(sfd, 0)) {
printf("Failed to listen on socket: %s.\n",
strerror(errno));
close(sfd);
exit(EXIT_FAILURE);
}
if (setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, (void *) &tv, len))
printf("Failed to set timeout on socket: %s.\n",
strerror(errno));
getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &check, &len);
printf("Check is %lu:%lu.\n", check.tv_sec, check.tv_usec);
while (count < 3) {
cfd = accept(sfd, 0, 0);
printf("Accept returned: %s.\n", strerror(errno));
++count;
}
printf("Bye.\n");
exit(EXIT_SUCCESS);
}
--
Dimitri Staessens
Ghent University - imec
Dept. of Information Technology (INTEC)
Internet Based Communication Networks and Services
Technologiepark 15
9052 Zwijnaarde
T: +32 9 331 48 70
F: +32 9 331 48 99
More information about the freebsd-bugs
mailing list