Add utimensat (#609)

* Update compatibility_hacks.c

* Add utimensat Wrapper

* Add utimensat to stat.h

* It Works! (kinda)
This commit is contained in:
TheBrokenRail 2020-01-08 12:01:48 -05:00 committed by Andrew Hyatt
parent edef755da6
commit c0dd759993
11 changed files with 226 additions and 15 deletions

View File

@ -362,6 +362,13 @@ mode_t umask(mode_t);
int fchmodat(int, const char *, mode_t, int) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
int fstatat(int, const char *, struct stat *, int) __DARWIN_INODE64(fstatat) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
int mkdirat(int, const char *, mode_t) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
#define UTIME_NOW -1
#define UTIME_OMIT -2
int futimens(int __fd, const struct timespec __times[2]) __API_AVAILABLE(macosx(10.13), ios(11.0), tvos(11.0), watchos(4.0));
int utimensat(int __fd, const char *__path, const struct timespec __times[2],
int __flag) __API_AVAILABLE(macosx(10.13), ios(11.0), tvos(11.0), watchos(4.0));
#endif
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)

View File

@ -29,7 +29,7 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
* created from /home/lubos/Projects/darling/src/kernel/libsyscall/xcodescripts/syscalls.master
* created from bsd/kern/syscalls.master
*/
#ifndef _SYS_SYSCALL_H_
@ -223,7 +223,7 @@
#define SYS_seteuid 183
#define SYS_sigreturn 184
/* 185 old chud */
/* 186 */
#define SYS_thread_selfcounts 186
#define SYS_fdatasync 187
#define SYS_stat 188
#define SYS_fstat 189
@ -412,7 +412,7 @@
#define SYS_thread_selfid 372
#define SYS_ledger 373
#define SYS_kevent_qos 374
/* 375 */
#define SYS_kevent_id 375
/* 376 */
/* 377 */
/* 378 */
@ -472,8 +472,8 @@
#define SYS_audit_session_port 432
#define SYS_pid_suspend 433
#define SYS_pid_resume 434
/* 435 */
/* 436 */
#define SYS_pid_hibernate 435
#define SYS_pid_shutdown_sockets 436
/* 437 old shared_region_slide_np */
#define SYS_shared_region_map_and_slide_np 438
#define SYS_kas_info 439
@ -559,7 +559,17 @@
/* 519 */
#define SYS_terminate_with_payload 520
#define SYS_abort_with_payload 521
#define SYS_MAXSYSCALL 522
#define SYS_necp_session_open 522
#define SYS_necp_session_action 523
#define SYS_setattrlistat 524
#define SYS_net_qos_guideline 525
#define SYS_fmount 526
#define SYS_ntp_adjtime 527
#define SYS_ntp_gettime 528
#define SYS_os_fault_with_payload 529
/* 530 */
/* 531 */
#define SYS_MAXSYSCALL 532
#define SYS_invalid 63
#endif /* __APPLE_API_PRIVATE */

View File

@ -206,6 +206,7 @@ set(emulation_sources
stat/common.c
xattr/getattrlistbulk.c
xattr/getattrlistat.c
xattr/setattrlistat.c
xattr/listxattr.c
xattr/flistxattr.c
xattr/removexattr.c

View File

@ -170,6 +170,7 @@
#include "hfs/stub.h"
#include "xattr/getattrlistbulk.h"
#include "xattr/getattrlistat.h"
#include "xattr/setattrlistat.h"
#include "xattr/listxattr.h"
#include "xattr/flistxattr.h"
#include "xattr/removexattr.h"
@ -445,5 +446,6 @@ void* __bsd_syscall_table[600] = {
[500] = sys_getentropy,
[515] = sys_ulock_wait,
[516] = sys_ulock_wake,
[524] = sys_setattrlistat,
};

View File

@ -0,0 +1,7 @@
#include "setattrlistat.h"
long sys_setattrlistat()
{
return 0;
}

View File

@ -0,0 +1,7 @@
#ifndef LINUX_SETATTRLISTAT_H
#define LINUX_SETATTRLISTAT_H
long sys_setattrlistat();
#endif

View File

@ -114,6 +114,7 @@ set(syscall_sources
wrappers/unlinkat.c
wrappers/unlink.c
wrappers/work_interval.c
wrappers/utimensat.c
wrappers/legacy/select-pre1050.c
@ -257,6 +258,7 @@ set(syscall_sources
bsdsyscalls/_fremovexattr.S
bsdsyscalls/_fsctl.S
bsdsyscalls/_fsetattrlist.S
bsdsyscalls/_setattrlistat.S
bsdsyscalls/_fsetxattr.S
bsdsyscalls/_fsgetpath.S
bsdsyscalls/___fsgetpath.S

View File

@ -0,0 +1,11 @@
#define __SYSCALL_32BIT_ARG_BYTES 20
#include "SYS.h"
#ifndef SYS_setattrlistat
#error "SYS_setattrlistat not defined. The header files libsyscall is building against do not match syscalls.master."
#endif
#if defined(__i386__) || defined(__x86_64__)
__SYSCALL2(_setattrlistat, setattrlistat, 6, cerror_nocancel)
#endif

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2006, 2017 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/attr.h>
#include <sys/time.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <strings.h>
extern int __gettimeofday(struct timeval *, struct timezone *);
extern int __commpage_gettimeofday(struct timeval *);
static struct timespec times_now[2] = {
{ .tv_nsec = UTIME_NOW },
{ .tv_nsec = UTIME_NOW }
};
/*
* Resolve any UTIME_NOW or UTIME_OMIT and return the attributes buffer and
* attributes to pass. Assumes times_in is writable.
*/
static int
prepare_times_array_and_attrs(struct timespec times_in[2],
struct timespec times_out[2], size_t *times_out_size)
{
if (times_in[0].tv_nsec == UTIME_OMIT &&
times_in[1].tv_nsec == UTIME_OMIT) {
return 0;
}
if (times_in[0].tv_nsec == UTIME_NOW ||
times_in[1].tv_nsec == UTIME_NOW) {
struct timespec now = {};
{
/*
* TODO: Replace with nanosecond time when available
*/
struct timeval tv;
if (__commpage_gettimeofday(&tv) != 0) {
__gettimeofday(&tv, NULL);
}
TIMEVAL_TO_TIMESPEC(&tv, &now);
}
if (times_in[0].tv_nsec == UTIME_NOW) {
times_in[0] = now;
}
if (times_in[1].tv_nsec == UTIME_NOW) {
times_in[1] = now;
}
}
int attrs = 0;
*times_out_size = 0;
struct timespec *times_cursor = times_out;
if (times_in[1].tv_nsec != UTIME_OMIT) {
attrs |= ATTR_CMN_MODTIME;
*times_cursor++ = times_in[1];
*times_out_size += sizeof(struct timespec);
}
if (times_in[0].tv_nsec != UTIME_OMIT) {
attrs |= ATTR_CMN_ACCTIME;
*times_cursor = times_in[0];
*times_out_size += sizeof(struct timespec);
}
return attrs;
}
int
futimens(int fd, const struct timespec _times_in[2])
{
struct timespec times_in[2];
if (_times_in != NULL) {
memcpy(&times_in, _times_in, sizeof(times_in));
} else {
memcpy(&times_in, times_now, sizeof(times_in));
}
size_t attrbuf_size = 0;
struct timespec times_out[2] = {};
struct attrlist a = {
.bitmapcount = ATTR_BIT_MAP_COUNT
};
a.commonattr = prepare_times_array_and_attrs(times_in, times_out, &attrbuf_size);
return fsetattrlist(fd, &a, &times_out, attrbuf_size, 0);
}
int
utimensat(int fd, const char *path, const struct timespec _times_in[2], int flags)
{
struct timespec times_in[2];
if (_times_in != NULL) {
memcpy(&times_in, _times_in, sizeof(times_in));
} else {
memcpy(&times_in, times_now, sizeof(times_in));
}
size_t attrbuf_size = 0;
struct timespec times_out[2] = {};
struct attrlist a = {
.bitmapcount = ATTR_BIT_MAP_COUNT
};
a.commonattr = prepare_times_array_and_attrs(times_in, times_out, &attrbuf_size);
int flags_out = 0;
if (flags & AT_SYMLINK_NOFOLLOW) {
flags_out |= FSOPT_NOFOLLOW;
}
return setattrlistat(fd, path, &a, &times_out, attrbuf_size, flags_out);
}

View File

@ -102,7 +102,7 @@
52 AUE_SIGPENDING ALL { int sigpending(struct sigvec *osv); }
53 AUE_SIGALTSTACK ALL { int sigaltstack(struct sigaltstack *nss, struct sigaltstack *oss) NO_SYSCALL_STUB ; }
54 AUE_IOCTL ALL { int ioctl(int fd, u_long com, caddr_t data) NO_SYSCALL_STUB; }
55 AUE_REBOOT ALL { int reboot(int opt, char *command); }
55 AUE_REBOOT ALL { int reboot(int opt, char *command) NO_SYSCALL_STUB; }
56 AUE_REVOKE ALL { int revoke(char *path); }
57 AUE_SYMLINK ALL { int symlink(char *path, char *link); }
58 AUE_READLINK ALL { int readlink(char *path, char *buf, int count); }
@ -262,16 +262,16 @@
174 AUE_NULL ALL { int nosys(void); } { old getdents }
175 AUE_NULL ALL { int nosys(void); } { old gc_control }
176 AUE_NULL ALL { int nosys(void); } { old add_profil }
177 AUE_KDEBUGTRACE ALL { int kdebug_typefilter(void** addr, size_t* size) NO_SYSCALL_STUB; }
178 AUE_KDEBUGTRACE ALL { uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id, const char *str) NO_SYSCALL_STUB; }
179 AUE_KDEBUGTRACE ALL { int kdebug_trace64(uint32_t code, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) NO_SYSCALL_STUB; }
180 AUE_KDEBUGTRACE ALL { int kdebug_trace(uint32_t code, u_long arg1, u_long arg2, u_long arg3, u_long arg4) NO_SYSCALL_STUB; }
177 AUE_NULL ALL { int kdebug_typefilter(void** addr, size_t* size) NO_SYSCALL_STUB; }
178 AUE_NULL ALL { uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id, const char *str) NO_SYSCALL_STUB; }
179 AUE_NULL ALL { int kdebug_trace64(uint32_t code, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) NO_SYSCALL_STUB; }
180 AUE_NULL ALL { int kdebug_trace(uint32_t code, u_long arg1, u_long arg2, u_long arg3, u_long arg4) NO_SYSCALL_STUB; }
181 AUE_SETGID ALL { int setgid(gid_t gid); }
182 AUE_SETEGID ALL { int setegid(gid_t egid); }
183 AUE_SETEUID ALL { int seteuid(uid_t euid); }
184 AUE_SIGRETURN ALL { int sigreturn(struct ucontext *uctx, int infostyle) NO_SYSCALL_STUB; }
185 AUE_NULL ALL { int enosys(void); } { old chud }
186 AUE_NULL ALL { int nosys(void); }
186 AUE_NULL ALL { int thread_selfcounts(int type, user_addr_t buf, user_size_t nbytes); }
187 AUE_FDATASYNC ALL { int fdatasync(int fd); }
188 AUE_STAT ALL { int stat(user_addr_t path, user_addr_t ub); }
189 AUE_FSTAT ALL { int fstat(int fd, user_addr_t ub); }
@ -565,7 +565,7 @@
372 AUE_NULL ALL { uint64_t thread_selfid (void) NO_SYSCALL_STUB; }
373 AUE_LEDGER ALL { int ledger(int cmd, caddr_t arg1, caddr_t arg2, caddr_t arg3); }
374 AUE_NULL ALL { int kevent_qos(int fd, const struct kevent_qos_s *changelist, int nchanges, struct kevent_qos_s *eventlist, int nevents, void *data_out, size_t *data_available, unsigned int flags); }
375 AUE_NULL ALL { int nosys(void); }
375 AUE_NULL ALL { int kevent_id(uint64_t id, const struct kevent_qos_s *changelist, int nchanges, struct kevent_qos_s *eventlist, int nevents, void *data_out, size_t *data_available, unsigned int flags); }
376 AUE_NULL ALL { int nosys(void); }
377 AUE_NULL ALL { int nosys(void); }
378 AUE_NULL ALL { int nosys(void); }
@ -666,8 +666,16 @@
432 AUE_NULL ALL { int audit_session_port(au_asid_t asid, user_addr_t portnamep); }
433 AUE_NULL ALL { int pid_suspend(int pid); }
434 AUE_NULL ALL { int pid_resume(int pid); }
#if CONFIG_EMBEDDED
435 AUE_NULL ALL { int pid_hibernate(int pid); }
#else
435 AUE_NULL ALL { int nosys(void); }
#endif
#if SOCKETS
436 AUE_NULL ALL { int pid_shutdown_sockets(int pid, int level); }
#else
436 AUE_NULL ALL { int nosys(void); }
#endif
437 AUE_NULL ALL { int nosys(void); } { old shared_region_slide_np }
438 AUE_NULL ALL { int shared_region_map_and_slide_np(int fd, uint32_t count, const struct shared_file_mapping_np *mappings, uint32_t slide, uint64_t* slide_start, uint32_t slide_size) NO_SYSCALL_STUB; }
439 AUE_NULL ALL { int kas_info(int selector, void *value, size_t *size); }
@ -676,7 +684,7 @@
#else
440 AUE_NULL ALL { int nosys(void); }
#endif
441 AUE_OPEN_RWTC ALL { int guarded_open_np(const char *path, const guardid_t *guard, u_int guardflags, int flags, int mode) NO_SYSCALL_STUB; }
441 AUE_OPEN_RWTC ALL { int guarded_open_np(user_addr_t path, const guardid_t *guard, u_int guardflags, int flags, int mode) NO_SYSCALL_STUB; }
442 AUE_CLOSE ALL { int guarded_close_np(int fd, const guardid_t *guard); }
443 AUE_KQUEUE ALL { int guarded_kqueue_np(const guardid_t *guard, u_int guardflags); }
444 AUE_NULL ALL { int change_fdguard_np(int fd, const guardid_t *guard, u_int guardflags, const guardid_t *nguard, u_int nguardflags, int *fdflagsp); }
@ -752,7 +760,7 @@
#else
483 AUE_NULL ALL { int enosys(void); }
#endif /* CSR */
484 AUE_NULL ALL { int guarded_open_dprotected_np(const char *path, const guardid_t *guard, u_int guardflags, int flags, int dpclass, int dpflags, int mode) NO_SYSCALL_STUB; }
484 AUE_NULL ALL { int guarded_open_dprotected_np(user_addr_t path, const guardid_t *guard, u_int guardflags, int flags, int dpclass, int dpflags, int mode) NO_SYSCALL_STUB; }
485 AUE_NULL ALL { user_ssize_t guarded_write_np(int fd, const guardid_t *guard, user_addr_t cbuf, user_size_t nbyte); }
486 AUE_PWRITE ALL { user_ssize_t guarded_pwrite_np(int fd, const guardid_t *guard, user_addr_t buf, user_size_t nbyte, off_t offset); }
487 AUE_WRITEV ALL { user_ssize_t guarded_writev_np(int fd, const guardid_t *guard, struct iovec *iovp, int iovcnt); }
@ -773,7 +781,11 @@
#else
492 AUE_NULL ALL { int enosys(void); }
#endif /* CONFIG_TELEMETRY */
#if PGO
493 AUE_NULL ALL { user_ssize_t grab_pgo_data (user_addr_t uuid, int flags, user_addr_t buffer, user_ssize_t size); }
#else
493 AUE_NULL ALL { int enosys(void); }
#endif
#if CONFIG_PERSONAS
494 AUE_PERSONA ALL { int persona(uint32_t operation, uint32_t flags, struct kpersona_info *info, uid_t *id, size_t *idlen) NO_SYSCALL_STUB; }
#else
@ -811,3 +823,18 @@
519 AUE_NULL ALL { int enosys(void); }
520 AUE_KILL ALL { int terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, const char *reason_string, uint64_t reason_flags) NO_SYSCALL_STUB; }
521 AUE_EXIT ALL { void abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, const char *reason_string, uint64_t reason_flags) NO_SYSCALL_STUB; }
#if NECP
522 AUE_NECP ALL { int necp_session_open(int flags); } }
523 AUE_NECP ALL { int necp_session_action(int necp_fd, uint32_t action, uint8_t *in_buffer, size_t in_buffer_length, uint8_t *out_buffer, size_t out_buffer_length); }
#else /* NECP */
522 AUE_NULL ALL { int enosys(void); }
523 AUE_NULL ALL { int enosys(void); }
#endif /* NECP */
524 AUE_SETATTRLISTAT ALL { int setattrlistat(int fd, const char *path, struct attrlist *alist, void *attributeBuffer, size_t bufferSize, uint32_t options); }
525 AUE_NET ALL { int net_qos_guideline(struct net_qos_param *param, uint32_t param_len); }
526 AUE_FMOUNT ALL { int fmount(const char *type, int fd, int flags, void *data); }
527 AUE_NULL ALL { int ntp_adjtime(struct timex *tp); }
528 AUE_NULL ALL { int ntp_gettime(struct ntptimeval *ntvp); }
529 AUE_NULL ALL { int os_fault_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, const char *reason_string, uint64_t reason_flags); }
530 AUE_NULL ALL { int enosys(void); }
531 AUE_NULL ALL { int enosys(void); }

View File

@ -36,6 +36,7 @@
".previous")
#define ADDED_IN_10_12(sym) WEAK_SYMBOL_LD_CMD(sym, 10.11)
#define ADDED_IN_10_13(sym) WEAK_SYMBOL_LD_CMD(sym, 10.12)
ADDED_IN_10_12(getentropy);
@ -49,4 +50,6 @@ ADDED_IN_10_12(dirname_r);
ADDED_IN_10_12(mkostemp);
ADDED_IN_10_12(mkostemps);
ADDED_IN_10_13(utimensat);
#endif /* TARGET_OS_IPHONE */