From 20d4e95dfd333eb3280ed341b5fa3c703e7421ff Mon Sep 17 00:00:00 2001 From: mtheall Date: Thu, 11 Dec 2014 08:33:26 -0600 Subject: [PATCH] Make soc_fcntl.c more sane. --- libctru/source/services/soc/soc_fcntl.c | 58 ++++++++++++++++++++----- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/libctru/source/services/soc/soc_fcntl.c b/libctru/source/services/soc/soc_fcntl.c index 6179a69..fcc873b 100644 --- a/libctru/source/services/soc/soc_fcntl.c +++ b/libctru/source/services/soc/soc_fcntl.c @@ -3,33 +3,59 @@ #include #include +#define O_NONBLOCK_3DS 0x4 + +#define ALL_3DS (O_NONBLOCK_3DS) +#define ALL_FLAGS (O_NONBLOCK) + +static int from_3ds(int flags) +{ + int newflags = 0; + + if(flags & O_NONBLOCK_3DS) newflags |= O_NONBLOCK; + /* add other flag translations here, but I have only seen O_NONBLOCK */ + + return newflags; +} + +static int to_3ds(int flags) +{ + int newflags = 0; + + if(flags & O_NONBLOCK) newflags |= O_NONBLOCK_3DS; + /* add other flag translations here, but I have only seen O_NONBLOCK */ + + return newflags; +} + int fcntl(int fd, int cmd, ...) { - int ret=0; - int arg=0; + int ret = 0; + int arg = 0; u32 *cmdbuf = getThreadCommandBuffer(); va_list args; - if(cmd!=F_GETFL && cmd!=F_SETFL) + if(cmd != F_GETFL && cmd != F_SETFL) { SOCU_errno = -EINVAL; return -1; } va_start(args, cmd); - if(cmd==F_SETFL) + if(cmd == F_SETFL) { arg = va_arg(args, int); - if(arg && arg!=O_NONBLOCK) + /* make sure they only used known flags */ + if(arg & ~ALL_FLAGS) { SOCU_errno = -EINVAL; va_end(args); return -1; } - if(arg==O_NONBLOCK)arg = 0x4; + arg = to_3ds(arg); } va_end(args); @@ -39,12 +65,22 @@ int fcntl(int fd, int cmd, ...) cmdbuf[3] = (u32)arg; cmdbuf[4] = 0x20; - if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret; + if((ret = svcSendSyncRequest(SOCU_handle)) != 0) + return ret; ret = (int)cmdbuf[1]; - if(ret==0)ret = _net_convert_error(cmdbuf[2]); - if(ret<0)SOCU_errno = ret; + if(ret == 0) + ret = _net_convert_error(cmdbuf[2]); + if(ret < 0) + SOCU_errno = ret; - if(ret<0)return -1; - return ret; + if(ret < 0) + return -1; + + if(ret & ~ALL_3DS) + { + /* somehow report unknown flags */ + } + + return from_3ds(ret); }