Handle result code+errno properly...

also make fcntl and ioctl non-variadic for convenience for the newlib wrapper
This commit is contained in:
TuxSH 2018-01-30 22:27:40 +01:00
parent 2d48fca238
commit 3078f3e27e
2 changed files with 33 additions and 50 deletions

View File

@ -29,6 +29,9 @@ typedef struct {
u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8).
} BsdBufferConfig; } BsdBufferConfig;
__thread Result t_bsdResult; ///< Last Switch "result", per-thread
__thread int t_bsdErrno; ///< Last errno, per-thread
const BsdBufferConfig *bsdGetDefaultBufferConfig(void); const BsdBufferConfig *bsdGetDefaultBufferConfig(void);
Result bsdInitialize(const BsdBufferConfig *config); Result bsdInitialize(const BsdBufferConfig *config);
void bsdExit(void); 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 bsdGetSockName(int sockfd, struct sockaddr *address, socklen_t *addrlen);
int bsdGetSockOpt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); int bsdGetSockOpt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int bsdListen(int sockfd, int backlog); int bsdListen(int sockfd, int backlog);
int bsdIoctl(int fd, int request, ...); // The following two functions are supposed to be variadic
int bsdFnctl(int fd, int cmd, ...); 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 bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
int bsdShutdown(int sockfd, int how); int bsdShutdown(int sockfd, int how);
int bsdShutdownAllSockets(int how); int bsdShutdownAllSockets(int how);

View File

@ -1,5 +1,4 @@
// Copyright 2017 plutoo // Copyright 2017 plutoo
#include <stdarg.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
@ -21,6 +20,8 @@
#include <net/if.h> #include <net/if.h>
#include <net/if_media.h> #include <net/if_media.h>
__thread Result t_bsdResult;
__thread int t_bsdErrno;
static Service g_bsdSrv; static Service g_bsdSrv;
static Service g_bsdMonitor; static Service g_bsdMonitor;
@ -92,7 +93,8 @@ static Result _bsdRegisterClient(Service* srv, TransferMemory* tmem, const BsdBu
} *resp = r.Raw; } *resp = r.Raw;
*pid_out = resp->pid; *pid_out = resp->pid;
rc = resp->result; t_bsdResult = rc = resp->result;
t_bsdErrno = 0;
} }
return rc; return rc;
@ -126,7 +128,8 @@ static Result _bsdStartMonitor(Service* srv, u64 pid) {
u64 result; u64 result;
} *resp = r.Raw; } *resp = r.Raw;
rc = resp->result; t_bsdResult = rc = resp->result;
t_bsdErrno = 0;
} }
return rc; return rc;
@ -152,13 +155,13 @@ static int _bsdDispatchBasicCommand(IpcCommand *c, IpcParsedCommand *rOut) {
rc = resp->result; rc = resp->result;
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
errno = resp->errno_; t_bsdErrno = resp->errno_;
ret = resp->ret; t_bsdResult = rc = resp->ret;
} }
} }
if (R_FAILED(rc)) if (R_FAILED(rc))
errno = EPIPE; t_bsdErrno = -1;
if(rOut != NULL) if(rOut != NULL)
*rOut = r; *rOut = r;
@ -604,8 +607,7 @@ int bsdListen(int sockfd, int backlog) {
return _bsdDispatchBasicCommand(&c, NULL); return _bsdDispatchBasicCommand(&c, NULL);
} }
// Not in bsd.h, exposed for the newlib compatibility wrapper int bsdIoctl(int fd, int request, void *data) {
int bsdIoctl_v(int fd, int request, va_list args) {
IpcCommand c; IpcCommand c;
const void *in1 = NULL, *in2 = NULL, *in3 = NULL, *in4 = NULL; 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) { switch(request) {
case SIOCGIFCONF: case SIOCGIFCONF:
{ {
struct ifconf *data = va_arg(args, struct ifconf *); struct ifconf *data_ = (struct ifconf *)data;
in1 = out1 = data; in1 = out1 = data;
in1sz = out1sz = sizeof(struct ifconf); in1sz = out1sz = sizeof(struct ifconf);
in2 = out2 = data->ifc_req; in2 = out2 = data_->ifc_req;
in2sz = out2sz = data->ifc_len; in2sz = out2sz = data_->ifc_len;
bufcount = 2; bufcount = 2;
break; break;
} }
case SIOCGIFMEDIA: case SIOCGIFMEDIA:
case SIOCGIFXMEDIA: case SIOCGIFXMEDIA:
{ {
struct ifmediareq *data = va_arg(args, struct ifmediareq *); struct ifmediareq *data_ = (struct ifmediareq *)data;
in1 = out1 = data; in1 = out1 = data;
in1sz = out1sz = sizeof(struct ifmediareq); in1sz = out1sz = sizeof(struct ifmediareq);
in2 = out2 = data->ifm_ulist; in2 = out2 = data_->ifm_ulist;
in2sz = out2sz = 8 * data->ifm_count; in2sz = out2sz = 8 * data_->ifm_count;
bufcount = 2; bufcount = 2;
break; break;
} }
// Generic ioctl // Generic ioctl
default: default:
{ {
void *data = NULL; void *data_ = NULL;
if(request & IOC_INOUT) if(request & IOC_INOUT)
data = va_arg(args, void *); data_ = data;
if(request & IOC_IN) if(request & IOC_IN)
{ {
in1 = data; in1 = data_;
in1sz = IOCPARM_LEN(request); in1sz = IOCPARM_LEN(request);
} }
if(request & IOC_OUT) if(request & IOC_OUT)
{ {
out1 = data; out1 = data_;
out1sz = IOCPARM_LEN(request); out1sz = IOCPARM_LEN(request);
} }
break; break;
@ -697,29 +699,17 @@ int bsdIoctl_v(int fd, int request, va_list args) {
return _bsdDispatchBasicCommand(&c, NULL); return _bsdDispatchBasicCommand(&c, NULL);
} }
int bsdIoctl(int fd, int request, ...) { int bsdFnctl(int fd, int cmd, int flags) {
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) {
IpcCommand c; IpcCommand c;
int arg = 0;
if(cmd == F_GETFL || cmd == F_SETFL) { if(cmd == F_GETFL || cmd == F_SETFL) {
errno = 0; t_bsdResult = 0;
t_bsdErrno = EINVAL;
return -1; return -1;
} }
if(cmd == F_SETFL) if(cmd == F_GETFL)
arg = va_arg(args, int); flags = 0;
ipcInitialize(&c); ipcInitialize(&c);
@ -728,7 +718,7 @@ int bsdFnctl_v(int fd, int cmd, va_list args) {
u64 cmd_id; u64 cmd_id;
int fd; int fd;
int cmd; int cmd;
int arg; int flags;
} *raw; } *raw;
raw = ipcPrepareHeader(&c, sizeof(*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->cmd_id = 20;
raw->fd = fd; raw->fd = fd;
raw->cmd = cmd; raw->cmd = cmd;
raw->arg = arg; raw->flags = flags;
return _bsdDispatchBasicCommand(&c, NULL); 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) { int bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);