Copy:
gvanem@yahoo.no
On 2023-06-28 17:04, J.W. Jagersma wrote:
Hi all,
I was trying to make a non-blocking socket in Watt32 via:
fcntl(sock, F_SETFL, O_NONBLOCK);
To my surprise, it did nothing. Replacing fcntl() with fcntlsocket() does set
the flag correctly, but that's not a portable solution.
Looking at the libc code, I see the fsext handler is invoked via:
int
fcntl(int fd, int cmd, ...)
{
/* ... */
func = __FSEXT_get_function(fd);
if (func)
{
int rv;
if (__FSEXT_func_wrapper(func, __FSEXT_fcntl, &rv, fd, cmd))
return rv;
}
/* ... */
}
From what I can tell, the flags (in va_list) are never passed through to the fsext handler. Has this ever worked? It seems like a bug to me.
I see ioctl() suffers from the same issue (and doesn't even pass cmd).
If I may propose a patch:
diff --git a/src/libc/compat/ioctl/ioctl.c b/src/libc/compat/ioctl/ioctl.c index f4382755..182be1a6 100644
--- a/src/libc/compat/ioctl/ioctl.c
+++ b/src/libc/compat/ioctl/ioctl.c
@@ -336,8 +336,17 @@ int ioctl(int fd, int cmd, ...)
** see if this is a file system extension file
**
*/
- if (func && __FSEXT_func_wrapper(func, __FSEXT_ioctl, &rv, fd))
- return rv;
+ if (func)
+ {
+ char *arg;
+
+ va_start(args, cmd);
+ arg = va_arg(args, char *);
+ va_end(args);
+
+ if (__FSEXT_func_wrapper(func, __FSEXT_ioctl, &rv, fd, cmd, arg))
+ return rv;
+ }
va_start(args, cmd);
diff --git a/src/libc/posix/fcntl/fcntl.c b/src/libc/posix/fcntl/fcntl.c
index e08ffe2b..1d43c0ff 100644
--- a/src/libc/posix/fcntl/fcntl.c
+++ b/src/libc/posix/fcntl/fcntl.c
@@ -281,8 +281,13 @@ fcntl(int fd, int cmd, ...)
func = __FSEXT_get_function(fd);
if (func)
{
- int rv;
- if (__FSEXT_func_wrapper(func, __FSEXT_fcntl, &rv, fd, cmd))
+ int rv, arg;
+
+ va_start(ap, cmd);
+ arg = va_arg(ap, int);
+ va_end(ap);
+
+ if (__FSEXT_func_wrapper