1
/* Copyright (C) 1995-1998,2002,2003,2005, 2008 Free Software Foundation, Inc.
2
This file is part of the GNU C Library.
4
The GNU C Library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Lesser General Public
6
License as published by the Free Software Foundation; either
7
version 2.1 of the License, or (at your option) any later version.
9
The GNU C Library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public
15
License along with the GNU C Library; if not, write to the Free
16
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
#include <sysdep-cancel.h>
20
#include <socketcall.h>
22
#include <kernel-features.h>
27
#ifdef __ASSUME_ACCEPT4
28
# define errlabel SYSCALL_ERROR_LABEL
30
# define errlabel .Lerr
37
/* The socket-oriented system calls are handled unusally in Linux/i386.
38
They are all gated through the single `socketcall' system call number.
39
`socketcall' takes two arguments: the first is the subcode, specifying
40
which socket function is being called; and the second is a pointer to
41
the arguments to the specific function. */
44
ENTRY (__libc_accept4)
54
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
56
movl $SOCKOP_accept4, %ebx /* Subcode is first arg to syscall. */
57
lea 4(%esp), %ecx /* Address of args is 2nd arg. */
59
/* Do the system call trap. */
62
/* Restore registers. */
66
/* %eax is < 0 if there was an error. */
70
/* Successful; return the syscall's value. */
76
/* We need one more register. */
78
cfi_adjust_cfa_offset(4)
80
/* Enable asynchronous cancellation. */
83
cfi_offset(6, -8) /* %esi */
89
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
91
movl $SOCKOP_accept4, %ebx /* Subcode is first arg to syscall. */
92
lea 8(%esp), %ecx /* Address of args is 2nd arg. */
94
/* Do the system call trap. */
97
/* Restore registers. */
101
/* Restore the cancellation. */
105
/* Restore registers. */
109
cfi_adjust_cfa_offset(-4)
111
/* %eax is < 0 if there was an error. */
115
/* Successful; return the syscall's value. */
119
#ifndef __ASSUME_ACCEPT4
120
/* The kernel returns -EINVAL for unknown socket operations.
121
We need to convert that error to an ENOSYS error. */
122
.Lerr: cmpl $-EINVAL, %eax
123
jne SYSCALL_ERROR_LABEL
125
/* Save registers. */
127
cfi_adjust_cfa_offset(4)
132
addl $_GLOBAL_OFFSET_TABLE_, %edx
133
movl have_accept4@GOTOFF(%edx), %eax
135
movl have_accept4, %eax
140
/* Try another call, this time with the FLAGS parameter
141
cleared and an invalid file descriptor. This call will not
142
cause any harm and it will return immediately. */
146
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
148
movl $SOCKOP_accept4, %ebx /* Subcode is first arg to syscall. */
149
lea 8(%esp), %ecx /* Address of args is 2nd arg. */
151
/* Do the system call trap. */
160
movl %eax, have_accept4@GOTOFF(%edx)
162
movl %eax, have_accept4
167
1: movl $-EINVAL, %eax
171
/* Restore registers. */
175
jmp SYSCALL_ERROR_LABEL
177
PSEUDO_END (__libc_accept4)
179
weak_alias (__libc_accept4, accept4)