FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian Kernel

 
 
LinkBack Thread Tools
 
Old 11-12-2011, 01:17 PM
Émeric Maschino
 
Default ia64: Add accept4() syscall

From: Émeric Maschino <emeric.maschino@gmail.com>
Subject: ia64: Add accept4() syscall

While debugging udev > 170 failure on Debian Wheezy
(http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=648325), it appears
that the issue was in fact due to missing accept4() in ia64.

This patch simply adds accept4() to ia64. The
arch/ia64/include/asm/unistd.h and arch/ia64/kernel/entry.S diffs
apply cleanly against 3.2-rc1.

Patch has been successfully tested running an ia64-targeted version of
test_accept4.c (modified from x86/x86_64-centric original version from
http://git.kernel.org/linus/de11defebf00007677fb7ee91d9b089b78786fbb):

/* 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

#define __NR_accept4 1334

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("
");

return syscall(__NR_accept4, fd, sockaddr, addrlen, flags);
}

/************************************************** ********************/

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("=======================================
");

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)
",
(flf & O_NONBLOCK) ? "" : "not ",
flf_pass ? "OK" : "failed");

close(acceptfd);
close(connfd);

printf("Test result: %s
", (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);
}

Signed-off-by: Émeric Maschino <emeric.maschino@gmail.com>
---

diff -uprN -X linux-3.2-rc1/Documentation/dontdiff
a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
--- a/arch/ia64/include/asm/unistd.h 2011-11-08 01:16:02.000000000 +0100
+++ b/arch/ia64/include/asm/unistd.h 2011-11-12 11:31:53.000000000 +0100
@@ -323,11 +323,12 @@
#define __NR_sendmmsg 1331
#define __NR_process_vm_readv 1332
#define __NR_process_vm_writev 1333
+#define __NR_accept4 1334

#ifdef __KERNEL__


-#define NR_syscalls 310 /* length of syscall table */
+#define NR_syscalls 311 /* length of syscall table */

/*
* The following defines stop scripts/checksyscalls.sh from complaining about
diff -uprN -X linux-3.2-rc1/Documentation/dontdiff
a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
--- a/arch/ia64/kernel/entry.S 2011-11-08 01:16:02.000000000 +0100
+++ b/arch/ia64/kernel/entry.S 2011-11-12 11:33:40.000000000 +0100
@@ -1779,6 +1779,7 @@ sys_call_table:
data8 sys_sendmmsg
data8 sys_process_vm_readv
data8 sys_process_vm_writev
+ data8 sys_accept4

.org sys_call_table + 8*NR_syscalls // guard against failures to
increase NR_syscalls
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */


--
To UNSUBSCRIBE, email to debian-kernel-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: CAA9xbM5w3j6GbXs3764N-Z-ePTagi3cjyid-a2Ci_jTtZ8Y5Rg@mail.gmail.com">http://lists.debian.org/CAA9xbM5w3j6GbXs3764N-Z-ePTagi3cjyid-a2Ci_jTtZ8Y5Rg@mail.gmail.com
 

Thread Tools




All times are GMT. The time now is 05:16 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright ©2007 - 2008, www.linux-archive.org