mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-04 02:22:15 +02:00
Handle result code+errno properly...
also make fcntl and ioctl non-variadic for convenience for the newlib wrapper
This commit is contained in:
parent
2d48fca238
commit
3078f3e27e
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user