--- /dev/null
+/* -*- linux-c -*-
+ * Syscall compatibility defines.
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _COMPAT_UNISTD_H_
+#define _COMPAT_UNISTD_H_
+
+#if defined(__x86_64__)
+
+// On older kernels (like RHEL5), we have to define our own 32-bit
+// syscall numbers.
+#ifndef __NR_ia32_faccessat
+#define __NR_ia32_faccessat 307
+#endif
+
+#define __NR_compat_faccessat __NR_ia32_faccessat
+
+#endif /* __x86_64__ */
+
+#if defined(__powerpc64__) || defined (__s390x__)
+
+// On the ppc64 and s390x, the 32-bit syscalls use the same number
+// as the 64-bit syscalls.
+
+#define __NR_compat_faccessat __NR_faccessat
+
+#endif /* __powerpc64__ || __s390x__ */
+
+#endif /* _COMPAT_UNISTD_H_ */
-/* COVERAGE: access */
+/* COVERAGE: access faccessat */
+#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+// To test for glibc support for faccessat():
+//
+// Since glibc 2.10:
+// _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
+// Before glibc 2.10:
+// _ATFILE_SOURCE
+
+#define GLIBC_SUPPORT \
+ (_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L \
+ || defined(_ATFILE_SOURCE))
int main()
{
fd1 = creat("foobar1",S_IREAD|S_IWRITE);
access("foobar1", F_OK);
- //staptest// access ("foobar1", F_OK)
- //staptest// faccessat (AT_FDCWD, "foobar1", F_OK) = 0
+ //staptest// access ("foobar1", F_OK) = 0
+
+#if GLIBC_SUPPORT
+ faccessat(AT_FDCWD, "foobar1", F_OK, 0);
+ //staptest// faccessat (AT_FDCWD, "foobar1", F_OK) = 0
+#endif
access("foobar1", R_OK);
- //staptest// access ("foobar1", R_OK)
- //staptest// faccessat (AT_FDCWD, "foobar1", R_OK) = 0
+ //staptest// access ("foobar1", R_OK) = 0
+
+#if GLIBC_SUPPORT
+ faccessat(AT_FDCWD, "foobar1", R_OK, 0);
+ //staptest// faccessat (AT_FDCWD, "foobar1", R_OK) = 0
+#endif
access("foobar1", W_OK);
- //staptest// access ("foobar1", W_OK)
- //staptest// faccessat (AT_FDCWD, "foobar1", W_OK) = 0
+ //staptest// access ("foobar1", W_OK) = 0
+
+#if GLIBC_SUPPORT
+ faccessat(AT_FDCWD, "foobar1", W_OK, 0);
+ //staptest// faccessat (AT_FDCWD, "foobar1", W_OK) = 0
+#endif
access("foobar1", X_OK);
- //staptest// access ("foobar1", X_OK)
- //staptest// faccessat (AT_FDCWD, "foobar1", X_OK) = -NNNN (EACCES)
+ //staptest// access ("foobar1", X_OK) = -NNNN (EACCES)
+
+#if GLIBC_SUPPORT
+ faccessat(AT_FDCWD, "foobar1", X_OK, 0);
+ //staptest// faccessat (AT_FDCWD, "foobar1", X_OK) = -NNNN (EACCES)
+#endif
access("foobar1", R_OK|W_OK);
- //staptest// access ("foobar1", W_OK |R_OK)
- //staptest// faccessat (AT_FDCWD, "foobar1", W_OK |R_OK) = 0
+ //staptest// access ("foobar1", W_OK |R_OK) = 0
+
+#if GLIBC_SUPPORT
+ faccessat(AT_FDCWD, "foobar1", R_OK|W_OK, 0);
+ //staptest// faccessat (AT_FDCWD, "foobar1", W_OK |R_OK) = 0
+#endif
access("foobar1", R_OK|W_OK|X_OK);
- //staptest// access ("foobar1", X_OK |W_OK |R_OK)
- //staptest// faccessat (AT_FDCWD, "foobar1", X_OK |W_OK |R_OK) = -NNNN (EACCES)
+ //staptest// access ("foobar1", X_OK |W_OK |R_OK) = -NNNN (EACCES)
+
+#if GLIBC_SUPPORT
+ faccessat(AT_FDCWD, "foobar1", R_OK|W_OK|X_OK, 0);
+ //staptest// faccessat (AT_FDCWD, "foobar1", X_OK |W_OK |R_OK) = -NNNN (EACCES)
+#endif
return 0;
}