proper error handling for fcntl F_GETOWN on modern kernels

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.
This commit is contained in:
Rich Felker 2012-06-20 22:16:47 -04:00
parent e5fb6820a4
commit 4e8b0938d9
5 changed files with 29 additions and 1 deletions

View File

@ -31,3 +31,6 @@
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16

View File

@ -31,3 +31,6 @@
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16

View File

@ -31,3 +31,6 @@
#define F_GETLK 5
#define F_SETLK 6
#define F_SETLKW 7
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16

View File

@ -99,6 +99,17 @@ int posix_fallocate(int, off_t, off_t);
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

View File

@ -1,6 +1,8 @@
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
#include "syscall.h"
#include "libc.h"
@ -13,6 +15,12 @@ int fcntl(int fd, int cmd, ...)
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);
}