diff options
author | Nick Kralevich <nnk@google.com> | 2012-07-09 12:55:32 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-07-09 12:55:32 -0700 |
commit | 8f08e1c902c726ac5230776c238e5edb6f51f440 (patch) | |
tree | f9089c8166118cf92ec6882f8f269f9b7c255e2b /libc/include | |
parent | a099e8e7d35a0e740477f9362e9360b42b98d9cd (diff) | |
parent | a3e230d1fa9a5ed773a029e2acc6eb4f3e849ea3 (diff) | |
download | bionic-8f08e1c902c726ac5230776c238e5edb6f51f440.zip bionic-8f08e1c902c726ac5230776c238e5edb6f51f440.tar.gz bionic-8f08e1c902c726ac5230776c238e5edb6f51f440.tar.bz2 |
Merge "FORTIFY_SOURCE: Add openat, fix bug"
Diffstat (limited to 'libc/include')
-rw-r--r-- | libc/include/fcntl.h | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h index 47151f4..77c92be 100644 --- a/libc/include/fcntl.h +++ b/libc/include/fcntl.h @@ -59,10 +59,10 @@ extern int creat(const char* path, mode_t mode); * http://clang.llvm.org/docs/UsersManual.html#c_unimpl_gcc */ -extern void __open_creat_error() - __attribute__((__error__ ("open called with O_CREAT, but missing mode"))); -extern void __open_toomanyargs_error() - __attribute__((__error__ ("open called with too many arguments"))); +extern void __creat_error() + __attribute__((__error__ ("called with O_CREAT, but missing mode"))); +extern void __too_many_args_error() + __attribute__((__error__ ("too many arguments"))); extern int __open_real(const char *pathname, int flags, ...) __asm__(__USER_LABEL_PREFIX__ "open"); extern int __open_2(const char *, int); @@ -71,21 +71,44 @@ __BIONIC_FORTIFY_INLINE int open(const char *pathname, int flags, ...) { if (__builtin_constant_p(flags)) { if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) { - __open_creat_error(); // compile time error + __creat_error(); // compile time error } } if (__builtin_va_arg_pack_len() > 1) { - __open_toomanyargs_error(); // compile time error + __too_many_args_error(); // compile time error } - if (__builtin_va_arg_pack_len() == 0) { + if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) { return __open_2(pathname, flags); } return __open_real(pathname, flags, __builtin_va_arg_pack()); } +extern int __openat_2(int, const char *, int); +extern int __openat_real(int dirfd, const char *pathname, int flags, ...) + __asm__(__USER_LABEL_PREFIX__ "openat"); + +__BIONIC_FORTIFY_INLINE +int openat(int dirfd, const char *pathname, int flags, ...) { + if (__builtin_constant_p(flags)) { + if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) { + __creat_error(); // compile time error + } + } + + if (__builtin_va_arg_pack_len() > 1) { + __too_many_args_error(); // compile time error + } + + if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) { + return __openat_2(dirfd, pathname, flags); + } + + return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack()); +} + #endif /* !defined(__clang__) */ #endif /* defined(__BIONIC_FORTIFY_INLINE) */ |