Use kernel's fcntl.h header instead of libc's for open_mode_flags

As definitions of O_* macros provided by various libc implementations
are usually less reliable than those provided by kernel headers, switch
to use kernel's fcntl.h header.

* open.c: Include <asm/fcntl.h> instead of <fcntl.h>.  Remove
O_LARGEFILE fallback definitions assuming that the kernel headers
provide them.
* xlat/open_mode_flags.in: Add __O_SYNC after O_SYNC.  Add O_TMPFILE
and __O_TMPFILE before O_DIRECTORY.  Remove "O_TMPFILE & ~O_DIRECTORY".
* tests/open.c: Include <asm/fcntl.h> instead of <fcntl.h>.  Remove
workarounds for libc O_TMPFILE implementations.
* tests/openat.c: Include <asm/fcntl.h> instead of <fcntl.h>.
(test_mode_flag): New function.
(main): Use it to check decoding of all access modes and file flags.
* tests/gen_tests.in (openat): Add -a option.

Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
This commit is contained in:
2018-02-02 19:39:23 +00:00
parent 0ec9716124
commit 11d1c182ba
5 changed files with 85 additions and 26 deletions

7
open.c
View File

@ -36,7 +36,7 @@
#include "defs.h"
#include "xstring.h"
#include <fcntl.h>
#include <asm/fcntl.h>
/* some libcs are guilty of messing up with O_ACCMODE */
#undef O_ACCMODE
@ -45,11 +45,6 @@
#ifdef O_LARGEFILE
# if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
# undef O_LARGEFILE
# ifdef SPARC64
# define O_LARGEFILE 0x40000
# elif defined X86_64 || defined S390X
# define O_LARGEFILE 0100000
# endif
# endif
#endif

View File

@ -257,7 +257,7 @@ oldselect-efault -a13 -e trace=select
oldselect-efault-P -a13 -e trace=select -P /dev/full 9>>/dev/full
oldstat -a32 -v -P stat.sample -P /dev/full
open -a30 -P $NAME.sample
openat -P $NAME.sample
openat -a36 -P $NAME.sample
osf_utimes -a21
pause -a8 -esignal=none
perf_event_open -a1

View File

@ -30,7 +30,7 @@
#ifdef __NR_open
# include <fcntl.h>
# include <asm/fcntl.h>
# include <stdio.h>
# include <unistd.h>
@ -56,16 +56,11 @@ main(void)
sample, sprintrc(fd));
}
#ifdef O_TMPFILE
# if O_TMPFILE == (O_TMPFILE & ~O_DIRECTORY)
# define STR_O_TMPFILE "O_TMPFILE"
# else
# define STR_O_TMPFILE "O_DIRECTORY|O_TMPFILE"
# endif
# ifdef O_TMPFILE
fd = syscall(__NR_open, sample, O_WRONLY|O_TMPFILE, 0600);
printf("open(\"%s\", O_WRONLY|%s, 0600) = %s\n",
sample, STR_O_TMPFILE, sprintrc(fd));
#endif /* O_TMPFILE */
printf("open(\"%s\", O_WRONLY|O_TMPFILE, 0600) = %s\n",
sample, sprintrc(fd));
# endif /* O_TMPFILE */
puts("+++ exited with 0 +++");
return 0;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2016 Katerina Koukiou <k.koukiou@gmail.com>
* Copyright (c) 2016-2018 The strace developers.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,17 +29,36 @@
#include "tests.h"
#include <asm/unistd.h>
#if defined __NR_openat
#ifdef __NR_openat
# include <fcntl.h>
# include <asm/fcntl.h>
# include <stdio.h>
# include <unistd.h>
#ifdef O_TMPFILE
/* The kernel & C libraries often inline O_DIRECTORY. */
# define STRACE_O_TMPFILE (O_TMPFILE & ~O_DIRECTORY)
#else
# define STRACE_O_TMPFILE 0
#endif
static const char sample[] = "openat.sample";
static void
test_mode_flag(unsigned int mode_val, const char *mode_str,
unsigned int flag_val, const char *flag_str)
{
long rc = syscall(__NR_openat, -1, sample, mode_val | flag_val, 0);
printf("openat(-1, \"%s\", %s%s%s%s) = %s\n",
sample, mode_str,
flag_val ? "|" : "", flag_str,
flag_val & (O_CREAT | STRACE_O_TMPFILE) ? ", 000" : "",
sprintrc(rc));
}
int
main(void)
{
static const char sample[] = "openat.sample";
long fd = syscall(__NR_openat, -100, sample, O_RDONLY|O_CREAT, 0400);
printf("openat(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400) = %s\n",
sample, sprintrc(fd));
@ -53,6 +73,54 @@ main(void)
sample, sprintrc(fd));
}
struct {
unsigned int val;
const char *str;
} modes[] = {
{ ARG_STR(O_RDONLY) },
{ ARG_STR(O_WRONLY) },
{ ARG_STR(O_RDWR) },
{ ARG_STR(O_ACCMODE) }
}, flags[] = {
{ ARG_STR(O_APPEND) },
{ ARG_STR(O_DIRECT) },
{ ARG_STR(O_DIRECTORY) },
{ ARG_STR(O_EXCL) },
{ ARG_STR(O_LARGEFILE) },
{ ARG_STR(O_NOATIME) },
{ ARG_STR(O_NOCTTY) },
{ ARG_STR(O_NOFOLLOW) },
{ ARG_STR(O_NONBLOCK) },
{ ARG_STR(O_SYNC) },
{ ARG_STR(O_TRUNC) },
{ ARG_STR(O_CREAT) },
# ifdef O_CLOEXEC
{ ARG_STR(O_CLOEXEC) },
# endif
# ifdef O_DSYNC
{ ARG_STR(O_DSYNC) },
# endif
# ifdef __O_SYNC
{ ARG_STR(__O_SYNC) },
# endif
# ifdef O_PATH
{ ARG_STR(O_PATH) },
# endif
# ifdef O_TMPFILE
{ ARG_STR(O_TMPFILE) },
# endif
# ifdef __O_TMPFILE
{ ARG_STR(__O_TMPFILE) },
# endif
{ ARG_STR(0x80000000) },
{ 0, "" }
};
for (unsigned int m = 0; m < ARRAY_SIZE(modes); ++m)
for (unsigned int f = 0; f < ARRAY_SIZE(flags); ++f)
test_mode_flag(modes[m].val, modes[m].str,
flags[f].val, flags[f].str);
puts("+++ exited with 0 +++");
return 0;
}

View File

@ -4,7 +4,9 @@ O_NOCTTY
O_TRUNC
O_APPEND
O_NONBLOCK
/* O_SYNC should be listed before O_DSYNC and __O_SYNC */
O_SYNC
__O_SYNC
O_ASYNC
O_DSYNC
O_RSYNC
@ -14,15 +16,14 @@ O_NDELAY
O_PRIV
O_DIRECT
O_LARGEFILE
O_DIRECTORY
O_NOFOLLOW
O_NOATIME
O_CLOEXEC
O_PATH
#if defined(O_TMPFILE) && defined(O_DIRECTORY)
/* The kernel & C libraries often inline O_DIRECTORY */
{ O_TMPFILE & ~O_DIRECTORY, "O_TMPFILE" },
#endif
/* O_TMPFILE should be listed before O_DIRECTORY and __O_TMPFILE */
O_TMPFILE
__O_TMPFILE
O_DIRECTORY
FNDELAY
FAPPEND
FMARK