1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/os_compat_android.h"
6
7 #include <array>
8
9 #include <asm/unistd.h>
10 #include <errno.h>
11 #include <sys/syscall.h>
12 #include <unistd.h>
13
14 #include "base/containers/span.h"
15 #include "base/numerics/safe_conversions.h"
16
17 extern "C" {
18 #if __ANDROID_API__ < 26
futimes(int fd,const struct timeval tv_ptr[2])19 int futimes(int fd, const struct timeval tv_ptr[2]) {
20 if (tv_ptr == nullptr) {
21 return base::checked_cast<int>(syscall(__NR_utimensat, fd, NULL, NULL, 0));
22 }
23
24 // SAFETY: The caller is required to give an array of two elements.
25 auto tv = UNSAFE_BUFFERS(base::span(tv_ptr, 2u));
26 if (tv[0].tv_usec < 0 || tv[0].tv_usec >= 1000000 ||
27 tv[1].tv_usec < 0 || tv[1].tv_usec >= 1000000) {
28 errno = EINVAL;
29 return -1;
30 }
31
32 // Convert timeval to timespec.
33 std::array<struct timespec, 2> ts;
34 ts[0].tv_sec = tv[0].tv_sec;
35 ts[0].tv_nsec = tv[0].tv_usec * 1000;
36 ts[1].tv_sec = tv[1].tv_sec;
37 ts[1].tv_nsec = tv[1].tv_usec * 1000;
38 return base::checked_cast<int>(
39 syscall(__NR_utimensat, fd, NULL, ts.data(), 0));
40 }
41 #endif
42
43 } // extern "C"
44