From 88dbc66d01ae6ab227fcd391afac335af03de9ee Mon Sep 17 00:00:00 2001 From: TuxSH Date: Tue, 30 Jan 2018 22:27:40 +0100 Subject: [PATCH] Handle result code+errno properly... also make fcntl and ioctl non-variadic for convenience for the newlib wrapper --- nx/include/switch/services/bsd.h | 8 +++- nx/source/services/bsd.c | 75 ++++++++++++-------------------- 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/nx/include/switch/services/bsd.h b/nx/include/switch/services/bsd.h index 68cb35fa..2e58200a 100644 --- a/nx/include/switch/services/bsd.h +++ b/nx/include/switch/services/bsd.h @@ -29,6 +29,9 @@ typedef struct { u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). } BsdBufferConfig; +__thread Result t_bsdResult; ///< Last Switch "result", per-thread +__thread int t_bsdErrno; ///< Last errno, per-thread + const BsdBufferConfig *bsdGetDefaultBufferConfig(void); Result bsdInitialize(const BsdBufferConfig *config); void bsdExit(void); @@ -50,8 +53,9 @@ int bsdGetPeerName(int sockfd, struct sockaddr *address, socklen_t *addrlen); int bsdGetSockName(int sockfd, struct sockaddr *address, socklen_t *addrlen); int bsdGetSockOpt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); int bsdListen(int sockfd, int backlog); -int bsdIoctl(int fd, int request, ...); -int bsdFnctl(int fd, int cmd, ...); +// The following two functions are supposed to be variadic +int bsdIoctl(int fd, int request, void *data); +int bsdFnctl(int fd, int cmd, int flags); int bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); int bsdShutdown(int sockfd, int how); int bsdShutdownAllSockets(int how); diff --git a/nx/source/services/bsd.c b/nx/source/services/bsd.c index 6a76719e..febd1f79 100644 --- a/nx/source/services/bsd.c +++ b/nx/source/services/bsd.c @@ -1,5 +1,4 @@ // Copyright 2017 plutoo -#include #include #include @@ -21,6 +20,8 @@ #include #include +__thread Result t_bsdResult; +__thread int t_bsdErrno; static Service g_bsdSrv; static Service g_bsdMonitor; @@ -92,7 +93,8 @@ static Result _bsdRegisterClient(Service* srv, TransferMemory* tmem, const BsdBu } *resp = r.Raw; *pid_out = resp->pid; - rc = resp->result; + t_bsdResult = rc = resp->result; + t_bsdErrno = 0; } return rc; @@ -126,7 +128,8 @@ static Result _bsdStartMonitor(Service* srv, u64 pid) { u64 result; } *resp = r.Raw; - rc = resp->result; + t_bsdResult = rc = resp->result; + t_bsdErrno = 0; } return rc; @@ -152,13 +155,13 @@ static int _bsdDispatchBasicCommand(IpcCommand *c, IpcParsedCommand *rOut) { rc = resp->result; if (R_SUCCEEDED(rc)) { - errno = resp->errno_; - ret = resp->ret; + t_bsdErrno = resp->errno_; + t_bsdResult = rc = resp->ret; } } if (R_FAILED(rc)) - errno = EPIPE; + t_bsdErrno = -1; if(rOut != NULL) *rOut = r; @@ -604,8 +607,7 @@ int bsdListen(int sockfd, int backlog) { return _bsdDispatchBasicCommand(&c, NULL); } -// Not in bsd.h, exposed for the newlib compatibility wrapper -int bsdIoctl_v(int fd, int request, va_list args) { +int bsdIoctl(int fd, int request, void *data) { IpcCommand c; const void *in1 = NULL, *in2 = NULL, *in3 = NULL, *in4 = NULL; @@ -619,39 +621,39 @@ int bsdIoctl_v(int fd, int request, va_list args) { switch(request) { case SIOCGIFCONF: { - struct ifconf *data = va_arg(args, struct ifconf *); + struct ifconf *data_ = (struct ifconf *)data; in1 = out1 = data; in1sz = out1sz = sizeof(struct ifconf); - in2 = out2 = data->ifc_req; - in2sz = out2sz = data->ifc_len; + in2 = out2 = data_->ifc_req; + in2sz = out2sz = data_->ifc_len; bufcount = 2; break; } case SIOCGIFMEDIA: case SIOCGIFXMEDIA: { - struct ifmediareq *data = va_arg(args, struct ifmediareq *); + struct ifmediareq *data_ = (struct ifmediareq *)data; in1 = out1 = data; in1sz = out1sz = sizeof(struct ifmediareq); - in2 = out2 = data->ifm_ulist; - in2sz = out2sz = 8 * data->ifm_count; + in2 = out2 = data_->ifm_ulist; + in2sz = out2sz = 8 * data_->ifm_count; bufcount = 2; break; } // Generic ioctl default: { - void *data = NULL; + void *data_ = NULL; if(request & IOC_INOUT) - data = va_arg(args, void *); + data_ = data; if(request & IOC_IN) { - in1 = data; + in1 = data_; in1sz = IOCPARM_LEN(request); } if(request & IOC_OUT) { - out1 = data; + out1 = data_; out1sz = IOCPARM_LEN(request); } break; @@ -697,29 +699,17 @@ int bsdIoctl_v(int fd, int request, va_list args) { return _bsdDispatchBasicCommand(&c, NULL); } -int bsdIoctl(int fd, int request, ...) { - int ret; - - va_list args; - va_start(args, request); - ret = bsdIoctl_v(fd, request, args); - va_end(args); - - return ret; -} - -// Not in bsd.h, exposed for the newlib compatibility wrapper -int bsdFnctl_v(int fd, int cmd, va_list args) { +int bsdFnctl(int fd, int cmd, int flags) { IpcCommand c; - int arg = 0; if(cmd == F_GETFL || cmd == F_SETFL) { - errno = 0; + t_bsdResult = 0; + t_bsdErrno = EINVAL; return -1; } - if(cmd == F_SETFL) - arg = va_arg(args, int); + if(cmd == F_GETFL) + flags = 0; ipcInitialize(&c); @@ -728,7 +718,7 @@ int bsdFnctl_v(int fd, int cmd, va_list args) { u64 cmd_id; int fd; int cmd; - int arg; + int flags; } *raw; raw = ipcPrepareHeader(&c, sizeof(*raw)); @@ -737,22 +727,11 @@ int bsdFnctl_v(int fd, int cmd, va_list args) { raw->cmd_id = 20; raw->fd = fd; raw->cmd = cmd; - raw->arg = arg; + raw->flags = flags; return _bsdDispatchBasicCommand(&c, NULL); } -int bsdFnctl(int fd, int cmd, ...) { - int ret; - - va_list args; - va_start(args, cmd); - ret = bsdFnctl_v(fd, cmd, args); - va_end(args); - - return ret; -} - int bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { IpcCommand c; ipcInitialize(&c);