diff options
author | nileshagrawal@chromium.org <nileshagrawal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-06 22:42:47 +0000 |
---|---|---|
committer | nileshagrawal@chromium.org <nileshagrawal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-06 22:42:47 +0000 |
commit | 617b0f81bd5389fe22d4766b2d55ad282c275907 (patch) | |
tree | bb68031b48701096e44282744cca84027dc40167 /base/os_compat_android.cc | |
parent | 1da97d43128a596792a65d16b7c85e5e28f93057 (diff) | |
download | chromium_src-617b0f81bd5389fe22d4766b2d55ad282c275907.zip chromium_src-617b0f81bd5389fe22d4766b2d55ad282c275907.tar.gz chromium_src-617b0f81bd5389fe22d4766b2d55ad282c275907.tar.bz2 |
Android: Provide futimes() implementation using utimensat()
The earlier implementation using /proc/self/fd/<num> failed when called from a non-main thread in production builds of Chrome and Android.
Depends on NDK r8e: https://codereview.chromium.org/14860010/
BUG=236403
Review URL: https://chromiumcodereview.appspot.com/14649009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204633 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/os_compat_android.cc')
-rw-r--r-- | base/os_compat_android.cc | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/base/os_compat_android.cc b/base/os_compat_android.cc index c4ea463..2f5b4db 100644 --- a/base/os_compat_android.cc +++ b/base/os_compat_android.cc @@ -4,22 +4,37 @@ #include "base/os_compat_android.h" +#include <asm/unistd.h> #include <errno.h> #include <math.h> #include <sys/stat.h> +#include <sys/syscall.h> #include <time64.h> #include "base/rand_util.h" #include "base/stringprintf.h" #include "base/strings/string_piece.h" +extern "C" { // There is no futimes() avaiable in Bionic, so we provide our own // implementation until it is there. -extern "C" { - int futimes(int fd, const struct timeval tv[2]) { - const std::string fd_path = base::StringPrintf("/proc/self/fd/%d", fd); - return utimes(fd_path.c_str(), tv); + if (tv == NULL) + return syscall(__NR_utimensat, fd, NULL, NULL, 0); + + if (tv[0].tv_usec < 0 || tv[0].tv_usec >= 1000000 || + tv[1].tv_usec < 0 || tv[1].tv_usec >= 1000000) { + errno = EINVAL; + return -1; + } + + // Convert timeval to timespec. + struct timespec ts[2]; + ts[0].tv_sec = tv[0].tv_sec; + ts[0].tv_nsec = tv[0].tv_usec * 1000; + ts[1].tv_sec = tv[1].tv_sec; + ts[1].tv_nsec = tv[1].tv_usec * 1000; + return syscall(__NR_utimensat, fd, NULL, ts, 0); } // Android has only timegm64() and no timegm(). |