From 079adff840032c3455eb1cb34dc9ceaa0b2bfc0c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 2 Apr 2021 12:18:20 -0700 Subject: [PATCH] Enable support for `utimes` and `futimesat`. These can both be implemented in terms of `utimensat`. --- Makefile | 1 + expected/wasm32-wasi/defined-symbols.txt | 3 +++ libc-bottom-half/sources/posix.c | 22 ++++++++++++++++++++++ libc-top-half/musl/include/sys/time.h | 4 ++-- libc-top-half/musl/src/stat/futimesat.c | 7 +++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a93b10a..5f253f3 100644 --- a/Makefile +++ b/Makefile @@ -132,6 +132,7 @@ LIBC_TOP_HALF_MUSL_SOURCES = \ env/setenv.c \ env/unsetenv.c \ unistd/posix_close.c \ + stat/futimesat.c \ ) \ $(filter-out %/procfdname.c %/syscall.c %/syscall_ret.c %/vdso.c %/version.c, \ $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/*.c)) \ diff --git a/expected/wasm32-wasi/defined-symbols.txt b/expected/wasm32-wasi/defined-symbols.txt index b8d2ba8..866f679 100644 --- a/expected/wasm32-wasi/defined-symbols.txt +++ b/expected/wasm32-wasi/defined-symbols.txt @@ -75,6 +75,7 @@ __funcs_on_exit __funcs_on_exit __funcs_on_quick_exit __funcs_on_quick_exit +__futimesat __fwritable __fwritex __fwriting @@ -647,6 +648,7 @@ ftello64 ftime ftruncate futimens +futimesat fwide fwprintf fwrite @@ -1120,6 +1122,7 @@ uselocale usleep utime utimensat +utimes vasprintf vdprintf versionsort diff --git a/libc-bottom-half/sources/posix.c b/libc-bottom-half/sources/posix.c index 153280f..b1696bb 100644 --- a/libc-bottom-half/sources/posix.c +++ b/libc-bottom-half/sources/posix.c @@ -139,6 +139,28 @@ int utime(const char *path, const struct utimbuf *times) { 0); } +int utimes(const char *path, const struct timeval times[2]) { + char *relative_path; + int dirfd = find_relpath(path, &relative_path); + + // If we can't find a preopen for it, indicate that we lack capabilities. + if (dirfd == -1) { + errno = ENOTCAPABLE; + return -1; + } + + return __wasilibc_nocwd_utimensat( + dirfd, relative_path, + times ? ((struct timespec [2]) { + { .tv_sec = times[0].tv_sec, + .tv_nsec = times[0].tv_usec * 1000 }, + { .tv_sec = times[1].tv_sec, + .tv_nsec = times[1].tv_usec * 1000 }, + }) + : NULL, + 0); +} + int unlink(const char *path) { char *relative_path; int dirfd = find_relpath(path, &relative_path); diff --git a/libc-top-half/musl/include/sys/time.h b/libc-top-half/musl/include/sys/time.h index 389cdcb..0f73655 100644 --- a/libc-top-half/musl/include/sys/time.h +++ b/libc-top-half/musl/include/sys/time.h @@ -23,9 +23,7 @@ struct itimerval { int getitimer (int, struct itimerval *); int setitimer (int, const struct itimerval *__restrict, struct itimerval *__restrict); #endif -#ifdef __wasilibc_unmodified_upstream /* WASI libc doesn't build the legacy functions */ int utimes (const char *, const struct timeval [2]); -#endif #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) struct timezone { @@ -34,7 +32,9 @@ struct timezone { }; #ifdef __wasilibc_unmodified_upstream /* WASI libc doesn't build the legacy functions */ int futimes(int, const struct timeval [2]); +#endif int futimesat(int, const char *, const struct timeval [2]); +#ifdef __wasilibc_unmodified_upstream /* WASI libc doesn't build the legacy functions */ int lutimes(const char *, const struct timeval [2]); #endif #ifdef __wasilibc_unmodified_upstream /* WASI has no way to set the time */ diff --git a/libc-top-half/musl/src/stat/futimesat.c b/libc-top-half/musl/src/stat/futimesat.c index 4bdb1c2..8ddcbb1 100644 --- a/libc-top-half/musl/src/stat/futimesat.c +++ b/libc-top-half/musl/src/stat/futimesat.c @@ -2,7 +2,9 @@ #include #include #include +#ifdef __wasilibc_unmodified_upstream // WASI has no syscall #include "syscall.h" +#endif int __futimesat(int dirfd, const char *pathname, const struct timeval times[2]) { @@ -11,7 +13,12 @@ int __futimesat(int dirfd, const char *pathname, const struct timeval times[2]) int i; for (i=0; i<2; i++) { if (times[i].tv_usec >= 1000000ULL) +#ifdef __wasilibc_unmodified_upstream // WASI has no syscall return __syscall_ret(-EINVAL); +#else + errno = EINVAL; + return -1; +#endif ts[i].tv_sec = times[i].tv_sec; ts[i].tv_nsec = times[i].tv_usec * 1000; } -- 2.39.2