on old kernels, there's no way to detect errors; we must assume
negative syscall return values are pgrp ids. but if the F_GETOWN_EX
fcntl works, we can get a reliable answer.
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
#define F_GETLK 5
#define F_SETLK 6
#define F_SETLKW 7
#define F_GETLK 5
#define F_SETLK 6
#define F_SETLKW 7
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
int lockf(int, int, off_t);
#endif
int lockf(int, int, off_t);
#endif
+#if defined(_GNU_SOURCE)
+#define F_OWNER_TID 0
+#define F_OWNER_PID 1
+#define F_OWNER_PGRP 2
+#define F_OWNER_GID 2
+struct f_owner_ex {
+ int type;
+ pid_t pid;
+};
+#endif
+
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
#define open64 open
#define openat64 openat
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
#define open64 open
#define openat64 openat
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include "syscall.h"
#include "libc.h"
#include "syscall.h"
#include "libc.h"
va_end(ap);
if (cmd == F_SETFL) arg |= O_LARGEFILE;
if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, arg);
va_end(ap);
if (cmd == F_SETFL) arg |= O_LARGEFILE;
if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, arg);
- if (cmd == F_GETOWN) return __syscall(SYS_fcntl, fd, cmd, arg);
+ if (cmd == F_GETOWN) {
+ struct f_owner_ex ex;
+ int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
+ if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, arg);
+ if (ret) return __syscall_ret(ret);
+ return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
+ }
return syscall(SYS_fcntl, fd, cmd, arg);
}
return syscall(SYS_fcntl, fd, cmd, arg);
}