mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Implement getpeername(2) and getsockname(2).
This commit is contained in:
parent
4eb9caaa39
commit
ef2e478607
12 changed files with 273 additions and 12 deletions
|
@ -1057,4 +1057,14 @@ int Descriptor::shutdown(ioctx_t* ctx, int how)
|
||||||
return vnode->shutdown(ctx, how);
|
return vnode->shutdown(ctx, how);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Descriptor::getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize)
|
||||||
|
{
|
||||||
|
return vnode->getpeername(ctx, addr, addrsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Descriptor::getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize)
|
||||||
|
{
|
||||||
|
return vnode->getsockname(ctx, addr, addrsize);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
|
@ -267,6 +267,8 @@ public:
|
||||||
virtual int tcsendbreak(ioctx_t* ctx, int duration);
|
virtual int tcsendbreak(ioctx_t* ctx, int duration);
|
||||||
virtual int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
virtual int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
||||||
virtual int shutdown(ioctx_t* ctx, int how);
|
virtual int shutdown(ioctx_t* ctx, int how);
|
||||||
|
virtual int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
virtual int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool SendMessage(Channel* channel, size_t type, void* ptr, size_t size,
|
bool SendMessage(Channel* channel, size_t type, void* ptr, size_t size,
|
||||||
|
@ -1748,6 +1750,18 @@ int Unode::shutdown(ioctx_t* ctx, int how)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Unode::getpeername(ioctx_t* /*ctx*/, uint8_t* /*addr*/,
|
||||||
|
size_t* /*addrsize*/)
|
||||||
|
{
|
||||||
|
return errno = ENOTSOCK, -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Unode::getsockname(ioctx_t* /*ctx*/, uint8_t* /*addr*/,
|
||||||
|
size_t* /*addrsize*/)
|
||||||
|
{
|
||||||
|
return errno = ENOTSOCK, -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool Bootstrap(Ref<Inode>* out_root,
|
bool Bootstrap(Ref<Inode>* out_root,
|
||||||
Ref<Inode>* out_server,
|
Ref<Inode>* out_server,
|
||||||
const struct stat* rootst)
|
const struct stat* rootst)
|
||||||
|
|
|
@ -121,6 +121,8 @@ public:
|
||||||
int tcsendbreak(ioctx_t* ctx, int duration);
|
int tcsendbreak(ioctx_t* ctx, int duration);
|
||||||
int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
||||||
int shutdown(ioctx_t* ctx, int how);
|
int shutdown(ioctx_t* ctx, int how);
|
||||||
|
int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<Descriptor> open_elem(ioctx_t* ctx, const char* filename, int flags,
|
Ref<Descriptor> open_elem(ioctx_t* ctx, const char* filename, int flags,
|
||||||
|
|
|
@ -130,6 +130,8 @@ public:
|
||||||
virtual int tcsendbreak(ioctx_t* ctx, int duration) = 0;
|
virtual int tcsendbreak(ioctx_t* ctx, int duration) = 0;
|
||||||
virtual int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio) = 0;
|
virtual int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio) = 0;
|
||||||
virtual int shutdown(ioctx_t* ctx, int how) = 0;
|
virtual int shutdown(ioctx_t* ctx, int how) = 0;
|
||||||
|
virtual int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize) = 0;
|
||||||
|
virtual int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -235,6 +237,8 @@ public:
|
||||||
virtual int tcsendbreak(ioctx_t* ctx, int duration);
|
virtual int tcsendbreak(ioctx_t* ctx, int duration);
|
||||||
virtual int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
virtual int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
||||||
virtual int shutdown(ioctx_t* ctx, int how);
|
virtual int shutdown(ioctx_t* ctx, int how);
|
||||||
|
virtual int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
virtual int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -95,13 +95,13 @@ uid_t sys_geteuid(void);
|
||||||
gid_t sys_getgid(void);
|
gid_t sys_getgid(void);
|
||||||
int sys_gethostname(char*, size_t);
|
int sys_gethostname(char*, size_t);
|
||||||
size_t sys_getpagesize(void);
|
size_t sys_getpagesize(void);
|
||||||
int sys_getpeername(int, struct sockaddr*, socklen_t*);
|
int sys_getpeername(int, void*, size_t*);
|
||||||
pid_t sys_getpgid(pid_t);
|
pid_t sys_getpgid(pid_t);
|
||||||
pid_t sys_getpid(void);
|
pid_t sys_getpid(void);
|
||||||
pid_t sys_getppid(void);
|
pid_t sys_getppid(void);
|
||||||
int sys_getpriority(int, id_t);
|
int sys_getpriority(int, id_t);
|
||||||
pid_t sys_getsid(pid_t);
|
pid_t sys_getsid(pid_t);
|
||||||
int sys_getsockname(int, struct sockaddr*, socklen_t*);
|
int sys_getsockname(int, void*, size_t*);
|
||||||
int sys_getsockopt(int, int, int, void*, size_t*);
|
int sys_getsockopt(int, int, int, void*, size_t*);
|
||||||
int sys_gettermmode(int, unsigned*);
|
int sys_gettermmode(int, unsigned*);
|
||||||
uid_t sys_getuid(void);
|
uid_t sys_getuid(void);
|
||||||
|
|
|
@ -118,6 +118,8 @@ public:
|
||||||
int tcsendbreak(ioctx_t* ctx, int duration);
|
int tcsendbreak(ioctx_t* ctx, int duration);
|
||||||
int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
|
||||||
int shutdown(ioctx_t* ctx, int how);
|
int shutdown(ioctx_t* ctx, int how);
|
||||||
|
int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
|
||||||
public /*TODO: private*/:
|
public /*TODO: private*/:
|
||||||
Ref<Inode> inode;
|
Ref<Inode> inode;
|
||||||
|
|
|
@ -626,4 +626,16 @@ int AbstractInode::shutdown(ioctx_t* /*ctx*/, int /*how*/)
|
||||||
return errno = ENOTSOCK, -1;
|
return errno = ENOTSOCK, -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AbstractInode::getpeername(ioctx_t* /*ctx*/, uint8_t* /*addr*/,
|
||||||
|
size_t* /*addrsize*/)
|
||||||
|
{
|
||||||
|
return errno = ENOTSOCK, -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractInode::getsockname(ioctx_t* /*ctx*/, uint8_t* /*addr*/,
|
||||||
|
size_t* /*addrsize*/)
|
||||||
|
{
|
||||||
|
return errno = ENOTSOCK, -1;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
|
@ -928,20 +928,22 @@ ssize_t sys_tcsetblob(int fd, const char* name, const void* buffer, size_t count
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_getpeername(int fd, struct sockaddr* addr, socklen_t* addrsize)
|
int sys_getpeername(int fd, void* addr, size_t* addrsize)
|
||||||
{
|
{
|
||||||
(void) fd;
|
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
|
||||||
(void) addr;
|
if ( !desc )
|
||||||
(void) addrsize;
|
return -1;
|
||||||
return errno = ENOSYS, -1;
|
ioctx_t ctx; SetupUserIOCtx(&ctx);
|
||||||
|
return desc->getpeername(&ctx, (uint8_t*) addr, addrsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_getsockname(int fd, struct sockaddr* addr, socklen_t* addrsize)
|
int sys_getsockname(int fd, void* addr, size_t* addrsize)
|
||||||
{
|
{
|
||||||
(void) fd;
|
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
|
||||||
(void) addr;
|
if ( !desc )
|
||||||
(void) addrsize;
|
return -1;
|
||||||
return errno = ENOSYS, -1;
|
ioctx_t ctx; SetupUserIOCtx(&ctx);
|
||||||
|
return desc->getsockname(&ctx, (uint8_t*) addr, addrsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_shutdown(int fd, int how)
|
int sys_shutdown(int fd, int how)
|
||||||
|
|
|
@ -103,6 +103,8 @@ public:
|
||||||
virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
|
virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
|
||||||
const void* option_value, size_t option_size);
|
const void* option_value, size_t option_size);
|
||||||
virtual int shutdown(ioctx_t* ctx, int how);
|
virtual int shutdown(ioctx_t* ctx, int how);
|
||||||
|
virtual int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
virtual int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int do_bind(ioctx_t* ctx, const uint8_t* addr, size_t addrsize);
|
int do_bind(ioctx_t* ctx, const uint8_t* addr, size_t addrsize);
|
||||||
|
@ -118,6 +120,7 @@ public: /* For use by Manager. */
|
||||||
StreamSocket* last_pending;
|
StreamSocket* last_pending;
|
||||||
struct sockaddr_un* bound_address;
|
struct sockaddr_un* bound_address;
|
||||||
size_t bound_address_size;
|
size_t bound_address_size;
|
||||||
|
int shutdown_flags;
|
||||||
bool is_listening;
|
bool is_listening;
|
||||||
bool is_connected;
|
bool is_connected;
|
||||||
bool is_refused;
|
bool is_refused;
|
||||||
|
@ -170,6 +173,7 @@ StreamSocket::StreamSocket(uid_t owner, gid_t group, mode_t mode,
|
||||||
this->last_pending = NULL;
|
this->last_pending = NULL;
|
||||||
this->bound_address = NULL;
|
this->bound_address = NULL;
|
||||||
this->bound_address_size = 0;
|
this->bound_address_size = 0;
|
||||||
|
this->shutdown_flags = 0;
|
||||||
this->is_listening = false;
|
this->is_listening = false;
|
||||||
this->is_connected = false;
|
this->is_connected = false;
|
||||||
this->is_refused = false;
|
this->is_refused = false;
|
||||||
|
@ -386,6 +390,41 @@ int StreamSocket::shutdown(ioctx_t* /*ctx*/, int how)
|
||||||
incoming.Disconnect();
|
incoming.Disconnect();
|
||||||
if ( how & SHUT_WR )
|
if ( how & SHUT_WR )
|
||||||
outgoing.Disconnect();
|
outgoing.Disconnect();
|
||||||
|
shutdown_flags |= how;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StreamSocket::getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize)
|
||||||
|
{
|
||||||
|
ScopedLock lock(&socket_lock);
|
||||||
|
if ( !is_connected )
|
||||||
|
return errno = ENOTCONN, -1;
|
||||||
|
if ( shutdown_flags & SHUT_WR )
|
||||||
|
return errno = EINVAL, -1;
|
||||||
|
size_t used_addrsize;
|
||||||
|
if ( !ctx->copy_from_src(&used_addrsize, addrsize, sizeof(used_addrsize)) )
|
||||||
|
return -1;
|
||||||
|
if ( bound_address_size < used_addrsize )
|
||||||
|
used_addrsize = bound_address_size;
|
||||||
|
if ( !ctx->copy_to_dest(addr, bound_address, bound_address_size) )
|
||||||
|
return -1;
|
||||||
|
if ( !ctx->copy_to_dest(addrsize, &used_addrsize, sizeof(used_addrsize)) )
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StreamSocket::getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize)
|
||||||
|
{
|
||||||
|
ScopedLock lock(&socket_lock);
|
||||||
|
size_t used_addrsize;
|
||||||
|
if ( !ctx->copy_from_src(&used_addrsize, addrsize, sizeof(used_addrsize)) )
|
||||||
|
return -1;
|
||||||
|
if ( bound_address_size < used_addrsize )
|
||||||
|
used_addrsize = bound_address_size;
|
||||||
|
if ( !ctx->copy_to_dest(addr, bound_address, bound_address_size) )
|
||||||
|
return -1;
|
||||||
|
if ( !ctx->copy_to_dest(addrsize, &used_addrsize, sizeof(used_addrsize)) )
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,6 +535,13 @@ Ref<StreamSocket> Manager::Accept(StreamSocket* socket, ioctx_t* ctx,
|
||||||
if ( !server )
|
if ( !server )
|
||||||
return Ref<StreamSocket>(NULL);
|
return Ref<StreamSocket>(NULL);
|
||||||
|
|
||||||
|
server->bound_address = (struct sockaddr_un*) malloc(bound_address_size);
|
||||||
|
if ( !server->bound_address )
|
||||||
|
return Ref<StreamSocket>(NULL);
|
||||||
|
|
||||||
|
server->bound_address_size = bound_address_size;
|
||||||
|
memcpy(server->bound_address, bound_address, bound_address_size);
|
||||||
|
|
||||||
StreamSocket* client = socket->first_pending;
|
StreamSocket* client = socket->first_pending;
|
||||||
QueuePop(&socket->first_pending, &socket->last_pending);
|
QueuePop(&socket->first_pending, &socket->last_pending);
|
||||||
|
|
||||||
|
|
|
@ -498,4 +498,14 @@ int Vnode::shutdown(ioctx_t* ctx, int how)
|
||||||
return inode->shutdown(ctx, how);
|
return inode->shutdown(ctx, how);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Vnode::getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize)
|
||||||
|
{
|
||||||
|
return inode->getpeername(ctx, addr, addrsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Vnode::getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize)
|
||||||
|
{
|
||||||
|
return inode->getsockname(ctx, addr, addrsize);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
|
@ -25,6 +25,7 @@ test-pthread-once \
|
||||||
test-pthread-self \
|
test-pthread-self \
|
||||||
test-pthread-tls \
|
test-pthread-tls \
|
||||||
test-signal-raise \
|
test-signal-raise \
|
||||||
|
test-unix-socket-name \
|
||||||
test-unix-socket-shutdown \
|
test-unix-socket-shutdown \
|
||||||
|
|
||||||
all: $(BINARIES) $(TESTS)
|
all: $(BINARIES) $(TESTS)
|
||||||
|
|
158
regress/test-unix-socket-name.c
Normal file
158
regress/test-unix-socket-name.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* test-unix-socket-name.c
|
||||||
|
* Tests whether unix sockets return the right names.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
static pid_t main_pid;
|
||||||
|
static char tmpdir[] = "/tmp/test-unix-socket-name.XXXXXX";
|
||||||
|
static char sockpath[(sizeof(tmpdir) - 1) + 1 + 6 + 1];
|
||||||
|
static bool made_tmpdir = false;
|
||||||
|
static bool made_socket = false;
|
||||||
|
|
||||||
|
void exit_handler(void)
|
||||||
|
{
|
||||||
|
if ( getpid() != main_pid )
|
||||||
|
return;
|
||||||
|
if ( made_socket )
|
||||||
|
unlink(sockpath);
|
||||||
|
if ( made_tmpdir )
|
||||||
|
rmdir(tmpdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
main_pid = getpid();
|
||||||
|
test_assert(atexit(exit_handler) == 0);
|
||||||
|
test_assert(mkdtemp(tmpdir));
|
||||||
|
made_tmpdir = true;
|
||||||
|
|
||||||
|
int server;
|
||||||
|
test_assert(0 <= (server = socket(AF_UNIX, SOCK_STREAM, 0)));
|
||||||
|
|
||||||
|
test_assert(snprintf(sockpath, sizeof(sockpath), "%s/socket", tmpdir) <
|
||||||
|
(int) sizeof(sockpath));
|
||||||
|
socklen_t sockaddr_actual_len =
|
||||||
|
offsetof(struct sockaddr_un, sun_path) + strlen(sockpath) + 1;
|
||||||
|
struct sockaddr_un sockaddr;
|
||||||
|
test_assert(sockaddr_actual_len <= sizeof(sockaddr));
|
||||||
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
|
sockaddr.sun_family = AF_UNIX;
|
||||||
|
strlcpy(sockaddr.sun_path, sockpath, sizeof(sockaddr.sun_path));
|
||||||
|
socklen_t sockaddr_len = sizeof(sockaddr);
|
||||||
|
|
||||||
|
test_assert(bind(server, (struct sockaddr*) &sockaddr, sockaddr_len) == 0);
|
||||||
|
test_assert(listen(server, 1) == 0 );
|
||||||
|
made_socket = true;
|
||||||
|
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
socklen_t addr_len;
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
test_assert(getsockname(server, (struct sockaddr*) &addr,
|
||||||
|
&addr_len) == 0);
|
||||||
|
test_assert(sockaddr_actual_len <= addr_len);
|
||||||
|
test_assert(addr_len <= sizeof(addr));
|
||||||
|
test_assert(addr.sun_family == AF_UNIX);
|
||||||
|
test_assert(strcmp(sockpath, addr.sun_path) == 0);
|
||||||
|
|
||||||
|
test_assert(getpeername(server, (struct sockaddr*) &addr,
|
||||||
|
&addr_len) == -1);
|
||||||
|
test_assert(errno == ENOTCONN);
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
|
||||||
|
int client;
|
||||||
|
pid_t pid;
|
||||||
|
test_assert(0 <= (pid = fork()));
|
||||||
|
if ( pid == 0 )
|
||||||
|
{
|
||||||
|
test_assert(0 <= (client = socket(AF_UNIX, SOCK_STREAM, 0)));
|
||||||
|
test_assert(connect(client, (struct sockaddr*) &sockaddr,
|
||||||
|
sockaddr_len) == 0);
|
||||||
|
|
||||||
|
#if defined(__sortix__) // Linux returns an empty struct sockaddr_un.
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
test_assert(getsockname(client, (struct sockaddr*) &addr,
|
||||||
|
&addr_len) == 0);
|
||||||
|
test_assert(sockaddr_actual_len <= addr_len);
|
||||||
|
test_assert(addr_len <= sizeof(addr));
|
||||||
|
test_assert(addr.sun_family == AF_UNIX);
|
||||||
|
test_assert(strcmp(sockpath, addr.sun_path) == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
test_assert(getpeername(client, (struct sockaddr*) &addr,
|
||||||
|
&addr_len) == 0);
|
||||||
|
test_assert(sockaddr_actual_len <= addr_len);
|
||||||
|
test_assert(addr_len <= sizeof(addr));
|
||||||
|
test_assert(addr.sun_family == AF_UNIX);
|
||||||
|
test_assert(strcmp(sockpath, addr.sun_path) == 0);
|
||||||
|
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
test_assert(0 <= (client = accept(server, (struct sockaddr*) &addr,
|
||||||
|
&addr_len)));
|
||||||
|
test_assert(sockaddr_actual_len <= addr_len);
|
||||||
|
test_assert(addr_len <= sizeof(addr));
|
||||||
|
test_assert(addr.sun_family == AF_UNIX);
|
||||||
|
test_assert(strcmp(sockpath, addr.sun_path) == 0);
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
test_assert(getsockname(client, (struct sockaddr*) &addr,
|
||||||
|
&addr_len) == 0);
|
||||||
|
test_assert(sockaddr_actual_len <= addr_len);
|
||||||
|
test_assert(addr_len <= sizeof(addr));
|
||||||
|
test_assert(addr.sun_family == AF_UNIX);
|
||||||
|
test_assert(strcmp(sockpath, addr.sun_path) == 0);
|
||||||
|
|
||||||
|
#if defined(__sortix__) // Linux returns an empty struct sockaddr_un.
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr_len = sizeof(addr);
|
||||||
|
test_assert(getpeername(client, (struct sockaddr*) &addr,
|
||||||
|
&addr_len) == 0);
|
||||||
|
test_assert(sockaddr_actual_len <= addr_len);
|
||||||
|
test_assert(addr_len <= sizeof(addr));
|
||||||
|
test_assert(addr.sun_family == AF_UNIX);
|
||||||
|
test_assert(strcmp(sockpath, addr.sun_path) == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int status = 0;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
if ( !WIFEXITED(status) || WEXITSTATUS(status) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue