unplugged-system/external/ltp/testcases/kernel/syscalls/fcntl/fcntl_common.h

76 lines
1.6 KiB
C

#ifndef FCNTL_COMMON_H__
#define FCNTL_COMMON_H__
#include <inttypes.h>
#include "tst_test.h"
#include "tst_kernel.h"
#include "lapi/syscalls.h"
#include "lapi/abisize.h"
#include "lapi/fcntl.h"
#if defined(TST_ABI64)
#define FCNTL_COMPAT(fd, cmd, flock) \
SAFE_FCNTL(fd, cmd, flock)
#else
struct my_flock64 {
short l_type;
short l_whence;
off64_t l_start;
off64_t l_len;
pid_t l_pid;
#if defined(__sparc__)
short padding;
#endif
};
/*
* F_OFD_* commands always require flock64 struct. Older GLibc (pre 2.29) would
* pass the flock sturct directly to the kernel even if it had 32-bit
* offsets.
*
* If we are on 32-bit abi we need to use the fcntl64 compat syscall.
*
* See:
* glibc: 06ab719d30 Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251)
* kernel: fs/fcntl.c
*/
static inline int fcntl_compat(const char *file, const int line, const char *cmd_name,
int fd, int cmd, struct flock *lck)
{
struct my_flock64 l64 = {
.l_type = lck->l_type,
.l_whence = lck->l_whence,
.l_start = lck->l_start,
.l_len = lck->l_len,
.l_pid = lck->l_pid,
};
const int ret = tst_syscall(__NR_fcntl64, fd, cmd, &l64);
lck->l_type = l64.l_type;
lck->l_whence = l64.l_whence;
lck->l_start = l64.l_start;
lck->l_len = l64.l_len;
lck->l_pid = l64.l_pid;
if (ret != -1)
return ret;
tst_brk_(file, line, TBROK | TERRNO,
"fcntl64(%d, %s, { %d, %d, %"PRId64", %"PRId64", %d })",
fd,
cmd_name,
l64.l_type, l64.l_whence, l64.l_start, l64.l_len, l64.l_pid);
return ret;
}
#define FCNTL_COMPAT(fd, cmd, flock) \
fcntl_compat(__FILE__, __LINE__, #cmd, fd, cmd, flock)
#endif
#endif /* FCNTL_COMMON_H__ */