Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions fs/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,21 +226,6 @@ void fdtable_do_cloexec(struct fdtable *table) {
unlock(&table->lock);
}

#define F_DUPFD_ 0
#define F_GETFD_ 1
#define F_SETFD_ 2
#define F_GETFL_ 3
#define F_SETFL_ 4

#define F_GETLK_ 5
#define F_SETLK_ 6
#define F_SETLKW_ 7
#define F_GETLK64_ 12
#define F_SETLK64_ 13
#define F_SETLKW64_ 14

#define F_DUPFD_CLOEXEC_ 1030

dword_t sys_dup(fd_t f) {
STRACE("dup(%d)", f);
struct fd *fd = f_get(f);
Expand Down
15 changes: 15 additions & 0 deletions fs/fd.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ struct dir_entry {
char name[NAME_MAX + 1];
};

#define F_DUPFD_ 0
#define F_GETFD_ 1
#define F_SETFD_ 2
#define F_GETFL_ 3
#define F_SETFL_ 4

#define F_GETLK_ 5
#define F_SETLK_ 6
#define F_SETLKW_ 7
#define F_GETLK64_ 12
#define F_SETLK64_ 13
#define F_SETLKW64_ 14

#define F_DUPFD_CLOEXEC_ 1030

#define LSEEK_SET 0
#define LSEEK_CUR 1
#define LSEEK_END 2
Expand Down
17 changes: 16 additions & 1 deletion fs/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,21 @@ int_t sys_accept(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr) {
return client_f;
}

int_t sys_accept4(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr, int_t flags) {
if (flags & ~(SOCK_NONBLOCK_ | SOCK_CLOEXEC_))
return _EINVAL;
fd_t client = sys_accept(sock_fd, sockaddr_addr, sockaddr_len_addr);
if (client < 0)
return client;
if (flags & SOCK_NONBLOCK_) {
int_t old = sys_fcntl(client, F_GETFL_, 0);
sys_fcntl(client, F_SETFL_, old | O_NONBLOCK_);
}
if (flags & SOCK_CLOEXEC_)
sys_fcntl(client, F_SETFD_, 1);
return client;
}

static void copy_unix_name(char *sockaddr, dword_t *sockaddr_len, struct fd *sock) {
struct sockaddr_ *fake_addr = (void *) sockaddr;
fake_addr->family = PF_LOCAL_;
Expand Down Expand Up @@ -1214,7 +1229,7 @@ static struct socket_call {
{(syscall_t) sys_getsockopt, 5},
{(syscall_t) sys_sendmsg, 3},
{(syscall_t) sys_recvmsg, 3},
{NULL}, // accept4
{(syscall_t) sys_accept4, 4},
{NULL}, // recvmmsg
{(syscall_t) sys_sendmmsg, 4},
};
Expand Down
1 change: 1 addition & 0 deletions fs/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ int_t sys_bind(fd_t sock_fd, addr_t sockaddr_addr, uint_t sockaddr_len);
int_t sys_connect(fd_t sock_fd, addr_t sockaddr_addr, uint_t sockaddr_len);
int_t sys_listen(fd_t sock_fd, int_t backlog);
int_t sys_accept(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr);
int_t sys_accept4(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr, int_t flags);
int_t sys_getsockname(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr);
int_t sys_getpeername(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr);
int_t sys_socketpair(dword_t domain, dword_t type, dword_t protocol, addr_t sockets_addr);
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/accept4/expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
accept4 ok
21 changes: 21 additions & 0 deletions tests/e2e/accept4/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
python3 -c "
import socket, ctypes, ctypes.util, threading, time

libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 19999))
s.listen(1)

def connect():
time.sleep(0.3)
c = socket.socket()
c.connect(('127.0.0.1', 19999))

threading.Thread(target=connect).start()

args = (ctypes.c_ulong * 4)(s.fileno(), 0, 0, 0)
result = libc.syscall(102, 18, args)
err = ctypes.get_errno()
print('accept4 ok' if result > 0 else 'accept4 failed errno=' + str(err))
"