]> Chaos Git - corbenik/ctrulib.git/commitdiff
Make soc_fcntl.c more sane.
authormtheall <pigman46@gmail.com>
Thu, 11 Dec 2014 14:33:26 +0000 (08:33 -0600)
committermtheall <pigman46@gmail.com>
Thu, 11 Dec 2014 14:33:26 +0000 (08:33 -0600)
libctru/source/services/soc/soc_fcntl.c

index 6179a69ae5eb4305e82723d3445f270bc4b35fba..fcc873bf72837f493b1d21b391183a242c966e9e 100644 (file)
@@ -3,33 +3,59 @@
 #include <fcntl.h>
 #include <stdarg.h>
 
+#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;
+
+       if(ret & ~ALL_3DS)
+       {
+               /* somehow report unknown flags */
+       }
 
-       if(ret<0)return -1;
-       return ret;
+       return from_3ds(ret);
 }