LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: "Michael Kerrisk" <mtk.manpages@googlemail.com>
To: "Andrew Morton" <akpm@linux-foundation.org>
Cc: "Subrata Modak" <subrata@linux.vnet.ibm.com>,
linux-arch@vger.kernel.org, "Ulrich Drepper" <drepper@redhat.com>,
linux-kernel@vger.kernel.org, torvalds@linux-foundation.org,
linux-api@vger.kernel.org, linux-man@vger.kernel.org,
"Davide Libenzi" <davidel@xmailserver.org>,
netdev <netdev@vger.kernel.org>,
"Roland McGrath" <roland@redhat.com>,
"Oleg Nesterov" <oleg@tv-sign.ru>,
"Christoph Hellwig" <hch@lst.de>,
"David Miller" <davem@davemloft.net>,
"Alan Cox" <alan@redhat.com>, "Jakub Jelinek" <jakub@redhat.com>
Subject: Re: [PATCH] reintroduce accept4
Date: Thu, 13 Nov 2008 17:11:10 -0500 [thread overview]
Message-ID: <cfd18e0f0811131411o5b47175dl36b022bc762181e5@mail.gmail.com> (raw)
In-Reply-To: <cfd18e0f0811131402j7ec6a60cq462916cc9715b9aa@mail.gmail.com>
Here's my test program. Works on x86-32. Should work on x86-64, but
I don't have a system to hand to test with.
It tests accept4() with each of the four possible combinations of
SOCK_CLOEXEC and SOCK_NONBLOCK set/clear in 'flags', and verifies that
the appropriate flags are set on the file descriptor/open file
description returned by accept4().
I tested Ulrich's patch in this thread by applying against 2.6.28-rc2,
and it passes according to my test program.
/* test_accept4.c
Copyright (C) 2008, Linux Foundation, written by Michael Kerrisk
<mtk.manpages@gmail.com>
Licensed under the GNU GPLv2 or later.
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#define PORT_NUM 33333
#define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
/**********************************************************************/
/* The following is what we need until glibc gets a wrapper for
accept4() */
/* Flags for socket(), socketpair(), accept4() */
#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC O_CLOEXEC
#endif
#ifndef SOCK_NONBLOCK
#define SOCK_NONBLOCK O_NONBLOCK
#endif
#ifdef __x86_64__
#define SYS_accept4 288
#elif __i386__
#define USE_SOCKETCALL 1
#define SYS_ACCEPT4 18
#else
#error "Sorry -- don't know the syscall # on this architecture"
#endif
static int
accept4(int fd, struct sockaddr *sockaddr, socklen_t *addrlen, int flags)
{
printf("Calling accept4(): flags = %x", flags);
if (flags != 0) {
printf(" (");
if (flags & SOCK_CLOEXEC)
printf("SOCK_CLOEXEC");
if ((flags & SOCK_CLOEXEC) && (flags & SOCK_NONBLOCK))
printf(" ");
if (flags & SOCK_NONBLOCK)
printf("SOCK_NONBLOCK");
printf(")");
}
printf("\n");
#if USE_SOCKETCALL
long args[6];
args[0] = fd;
args[1] = (long) sockaddr;
args[2] = (long) addrlen;
args[3] = flags;
printf("x86-32\n"); /* XXX */
return syscall(SYS_socketcall, SYS_ACCEPT4, args);
#else
printf("x86-64\n"); /* XXX */
return syscall(SYS_accept4, fd, sockaddr, addrlen, flags);
#endif
}
/**********************************************************************/
static int
do_test(int lfd, struct sockaddr_in *conn_addr,
int closeonexec_flag, int nonblock_flag)
{
int connfd, acceptfd;
int fdf, flf, fdf_pass, flf_pass;
struct sockaddr_in claddr;
socklen_t addrlen;
printf("=======================================\n");
connfd = socket(AF_INET, SOCK_STREAM, 0);
if (connfd == -1)
die("socket");
if (connect(connfd, (struct sockaddr *) conn_addr,
sizeof(struct sockaddr_in)) == -1)
die("connect");
addrlen = sizeof(struct sockaddr_in);
acceptfd = accept4(lfd, (struct sockaddr *) &claddr, &addrlen,
closeonexec_flag | nonblock_flag);
if (acceptfd == -1) {
perror("accept4()");
close(connfd);
return 0;
}
fdf = fcntl(acceptfd, F_GETFD);
if (fdf == -1)
die("fcntl:F_GETFD");
fdf_pass = ((fdf & FD_CLOEXEC) != 0) ==
((closeonexec_flag & SOCK_CLOEXEC) != 0);
printf("Close-on-exec flag is %sset (%s); ",
(fdf & FD_CLOEXEC) ? "" : "not ",
fdf_pass ? "OK" : "failed");
flf = fcntl(acceptfd, F_GETFL);
if (flf == -1)
die("fcntl:F_GETFD");
flf_pass = ((flf & O_NONBLOCK) != 0) ==
((nonblock_flag & SOCK_NONBLOCK) !=0);
printf("nonblock flag is %sset (%s)\n",
(flf & O_NONBLOCK) ? "" : "not ",
flf_pass ? "OK" : "failed");
close(acceptfd);
close(connfd);
printf("Test result: %s\n", (fdf_pass && flf_pass) ? "PASS" : "FAIL");
return fdf_pass && flf_pass;
}
static int
create_listening_socket(int port_num)
{
struct sockaddr_in svaddr;
int lfd;
int optval;
memset(&svaddr, 0, sizeof(struct sockaddr_in));
svaddr.sin_family = AF_INET;
svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
svaddr.sin_port = htons(port_num);
lfd = socket(AF_INET, SOCK_STREAM, 0);
if (lfd == -1)
die("socket");
optval = 1;
if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof(optval)) == -1)
die("setsockopt");
if (bind(lfd, (struct sockaddr *) &svaddr,
sizeof(struct sockaddr_in)) == -1)
die("bind");
if (listen(lfd, 5) == -1)
die("listen");
return lfd;
}
int
main(int argc, char *argv[])
{
struct sockaddr_in conn_addr;
int lfd;
int port_num;
int passed;
passed = 1;
port_num = (argc > 1) ? atoi(argv[1]) : PORT_NUM;
memset(&conn_addr, 0, sizeof(struct sockaddr_in));
conn_addr.sin_family = AF_INET;
conn_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
conn_addr.sin_port = htons(port_num);
lfd = create_listening_socket(port_num);
if (!do_test(lfd, &conn_addr, 0, 0))
passed = 0;
if (!do_test(lfd, &conn_addr, SOCK_CLOEXEC, 0))
passed = 0;
if (!do_test(lfd, &conn_addr, 0, SOCK_NONBLOCK))
passed = 0;
if (!do_test(lfd, &conn_addr, SOCK_CLOEXEC, SOCK_NONBLOCK))
passed = 0;
close(lfd);
exit(passed ? EXIT_SUCCESS : EXIT_FAILURE);
}
next prev parent reply other threads:[~2008-11-13 22:11 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-26 16:41 Ulrich Drepper
2008-10-28 3:41 ` Andrew Morton
2008-10-28 4:22 ` Ulrich Drepper
2008-10-28 4:52 ` Andrew Morton
2008-10-28 12:34 ` Michael Kerrisk
2008-11-13 21:51 ` Michael Kerrisk
2008-11-13 22:02 ` Michael Kerrisk
2008-11-13 22:11 ` Michael Kerrisk [this message]
2008-11-13 22:14 ` Michael Kerrisk
2008-11-13 22:05 ` Andrew Morton
2008-11-13 22:25 ` Paul Mackerras
2008-11-13 22:28 ` Paul Mackerras
2008-11-13 22:57 ` Andrew Morton
2008-11-14 0:07 ` David Miller
2008-11-14 15:24 ` Michael Kerrisk
2008-11-14 17:40 ` Michael Kerrisk
2008-11-14 15:24 ` Michael Kerrisk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cfd18e0f0811131411o5b47175dl36b022bc762181e5@mail.gmail.com \
--to=mtk.manpages@googlemail.com \
--cc=akpm@linux-foundation.org \
--cc=alan@redhat.com \
--cc=davem@davemloft.net \
--cc=davidel@xmailserver.org \
--cc=drepper@redhat.com \
--cc=hch@lst.de \
--cc=jakub@redhat.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-man@vger.kernel.org \
--cc=mtk.manpages@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=oleg@tv-sign.ru \
--cc=roland@redhat.com \
--cc=subrata@linux.vnet.ibm.com \
--cc=torvalds@linux-foundation.org \
--subject='Re: [PATCH] reintroduce accept4' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).