proper error handling for fcntl F_GETOWN on modern kernels
[musl] / src / fcntl / fcntl.c
1 #define _GNU_SOURCE
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <stdarg.h>
5 #include <errno.h>
6 #include "syscall.h"
7 #include "libc.h"
8
9 int fcntl(int fd, int cmd, ...)
10 {
11         long arg;
12         va_list ap;
13         va_start(ap, cmd);
14         arg = va_arg(ap, long);
15         va_end(ap);
16         if (cmd == F_SETFL) arg |= O_LARGEFILE;
17         if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, arg);
18         if (cmd == F_GETOWN) {
19                 struct f_owner_ex ex;
20                 int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
21                 if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, arg);
22                 if (ret) return __syscall_ret(ret);
23                 return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
24         }
25         return syscall(SYS_fcntl, fd, cmd, arg);
26 }