From: Steffen Kieß Date: Wed, 27 Mar 2013 12:45:50 +0000 (+0100) Subject: Add nanosecond resolution times to struct Stat X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=28e16142fa261d0cd0acad319e8c00a9bd3c7025 Add nanosecond resolution times to struct Stat --- diff --git a/configure.in b/configure.in index c32d35fc442..b400832a1dd 100644 --- a/configure.in +++ b/configure.in @@ -2007,6 +2007,11 @@ if test x$target_win32 = xno; then [struct statfs.f_flags],,, [#include #include ]) + AC_CHECK_MEMBERS( + [struct stat.st_atim, struct stat.st_mtim, struct stat.st_ctim],,, + [#include + #include + #include ]) dnl Favour xattr through glibc, but use libattr if we have to AC_CHECK_FUNC(lsetxattr, , diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs index 7ac5a750f41..4c56a293d51 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs @@ -318,6 +318,22 @@ namespace Mono.Unix.Native { return fopen_mode; } + [DllImport (LIB, EntryPoint="Mono_Posix_FromStat")] + private static extern int FromStat (ref Stat source, IntPtr destination); + + public static bool TryCopy (ref Stat source, IntPtr destination) + { + return FromStat (ref source, destination) == 0; + } + + [DllImport (LIB, EntryPoint="Mono_Posix_ToStat")] + private static extern int ToStat (IntPtr source, out Stat destination); + + public static bool TryCopy (IntPtr source, out Stat destination) + { + return ToStat (source, out destination) == 0; + } + [DllImport (LIB, EntryPoint="Mono_Posix_FromStatvfs")] private static extern int FromStatvfs (ref Statvfs source, IntPtr destination); diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs index e5e41cc3b0c..d9097f8d7a3 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs @@ -838,22 +838,6 @@ namespace Mono.Unix.Native { return rval; } - [DllImport (LIB, EntryPoint="Mono_Posix_FromStat")] - private static extern int FromStat (ref Stat source, IntPtr destination); - - public static bool TryCopy (ref Stat source, IntPtr destination) - { - return FromStat (ref source, destination) == 0; - } - - [DllImport (LIB, EntryPoint="Mono_Posix_ToStat")] - private static extern int ToStat (IntPtr source, out Stat destination); - - public static bool TryCopy (IntPtr source, out Stat destination) - { - return ToStat (source, out destination) == 0; - } - [DllImport (LIB, EntryPoint="Mono_Posix_FromSysconfName")] private static extern int FromSysconfName (SysconfName value, out Int32 rval); diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs index 083fb6c4093..27d241539d5 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs @@ -820,7 +820,7 @@ namespace Mono.Unix.Native { } } - [Map ("struct stat")] + // Use manually written To/From methods to handle fields st_atime_nsec etc. public struct Stat #if NET_2_0 : IEquatable @@ -850,6 +850,39 @@ namespace Mono.Unix.Native { [time_t] public long st_atime; // time of last access [time_t] public long st_mtime; // time of last modification [time_t] public long st_ctime; // time of last status change + public long st_atime_nsec; // Timespec.tv_nsec partner to st_atime + public long st_mtime_nsec; // Timespec.tv_nsec partner to st_mtime + public long st_ctime_nsec; // Timespec.tv_nsec partner to st_ctime + + public Timespec st_atim { + get { + return new Timespec { tv_sec = st_atime, tv_nsec = st_atime_nsec }; + } + set { + st_atime = value.tv_sec; + st_atime_nsec = value.tv_nsec; + } + } + + public Timespec st_mtim { + get { + return new Timespec { tv_sec = st_mtime, tv_nsec = st_mtime_nsec }; + } + set { + st_mtime = value.tv_sec; + st_mtime_nsec = value.tv_nsec; + } + } + + public Timespec st_ctim { + get { + return new Timespec { tv_sec = st_ctime, tv_nsec = st_ctime_nsec }; + } + set { + st_ctime = value.tv_sec; + st_ctime_nsec = value.tv_nsec; + } + } public override int GetHashCode () { @@ -865,7 +898,10 @@ namespace Mono.Unix.Native { st_blocks.GetHashCode () ^ st_atime.GetHashCode () ^ st_mtime.GetHashCode () ^ - st_ctime.GetHashCode (); + st_ctime.GetHashCode () ^ + st_atime_nsec.GetHashCode () ^ + st_mtime_nsec.GetHashCode () ^ + st_ctime_nsec.GetHashCode (); } public override bool Equals (object obj) @@ -885,7 +921,10 @@ namespace Mono.Unix.Native { value.st_blocks == st_blocks && value.st_atime == st_atime && value.st_mtime == st_mtime && - value.st_ctime == st_ctime; + value.st_ctime == st_ctime && + value.st_atime_nsec == st_atime_nsec && + value.st_mtime_nsec == st_mtime_nsec && + value.st_ctime_nsec == st_ctime_nsec; } public bool Equals (Stat value) @@ -902,7 +941,10 @@ namespace Mono.Unix.Native { value.st_blocks == st_blocks && value.st_atime == st_atime && value.st_mtime == st_mtime && - value.st_ctime == st_ctime; + value.st_ctime == st_ctime && + value.st_atime_nsec == st_atime_nsec && + value.st_mtime_nsec == st_mtime_nsec && + value.st_ctime_nsec == st_ctime_nsec; } public static bool operator== (Stat lhs, Stat rhs) diff --git a/support/map.c b/support/map.c index 2150cb29bbb..8374331c09a 100644 --- a/support/map.c +++ b/support/map.c @@ -4604,86 +4604,6 @@ int Mono_Posix_ToSignum (int x, int *r) errno = EINVAL; return -1; } -#ifdef HAVE_STRUCT_STAT -int -Mono_Posix_FromStat (struct Mono_Posix_Stat *from, struct stat *to) -{ - _cnm_return_val_if_overflow (dev_t, from->st_dev, -1); - _cnm_return_val_if_overflow (ino_t, from->st_ino, -1); - _cnm_return_val_if_overflow (nlink_t, from->st_nlink, -1); - _cnm_return_val_if_overflow (uid_t, from->st_uid, -1); - _cnm_return_val_if_overflow (gid_t, from->st_gid, -1); - _cnm_return_val_if_overflow (dev_t, from->st_rdev, -1); - _cnm_return_val_if_overflow (off_t, from->st_size, -1); - _cnm_return_val_if_overflow (blksize_t, from->st_blksize, -1); - _cnm_return_val_if_overflow (blkcnt_t, from->st_blocks, -1); - _cnm_return_val_if_overflow (time_t, from->st_atime_, -1); - _cnm_return_val_if_overflow (time_t, from->st_mtime_, -1); - _cnm_return_val_if_overflow (time_t, from->st_ctime_, -1); - - memset (to, 0, sizeof(*to)); - - to->st_dev = from->st_dev; - to->st_ino = from->st_ino; - if (Mono_Posix_FromFilePermissions (from->st_mode, &to->st_mode) != 0) { - return -1; - } - to->st_nlink = from->st_nlink; - to->st_uid = from->st_uid; - to->st_gid = from->st_gid; - to->st_rdev = from->st_rdev; - to->st_size = from->st_size; - to->st_blksize = from->st_blksize; - to->st_blocks = from->st_blocks; - to->st_atime = from->st_atime_; - to->st_mtime = from->st_mtime_; - to->st_ctime = from->st_ctime_; - - return 0; -} -#endif /* ndef HAVE_STRUCT_STAT */ - - -#ifdef HAVE_STRUCT_STAT -int -Mono_Posix_ToStat (struct stat *from, struct Mono_Posix_Stat *to) -{ - _cnm_return_val_if_overflow (guint64, from->st_dev, -1); - _cnm_return_val_if_overflow (guint64, from->st_ino, -1); - _cnm_return_val_if_overflow (guint64, from->st_nlink, -1); - _cnm_return_val_if_overflow (unsigned int, from->st_uid, -1); - _cnm_return_val_if_overflow (unsigned int, from->st_gid, -1); - _cnm_return_val_if_overflow (guint64, from->st_rdev, -1); - _cnm_return_val_if_overflow (gint64, from->st_size, -1); - _cnm_return_val_if_overflow (gint64, from->st_blksize, -1); - _cnm_return_val_if_overflow (gint64, from->st_blocks, -1); - _cnm_return_val_if_overflow (gint64, from->st_atime, -1); - _cnm_return_val_if_overflow (gint64, from->st_mtime, -1); - _cnm_return_val_if_overflow (gint64, from->st_ctime, -1); - - memset (to, 0, sizeof(*to)); - - to->st_dev = from->st_dev; - to->st_ino = from->st_ino; - if (Mono_Posix_ToFilePermissions (from->st_mode, &to->st_mode) != 0) { - return -1; - } - to->st_nlink = from->st_nlink; - to->st_uid = from->st_uid; - to->st_gid = from->st_gid; - to->st_rdev = from->st_rdev; - to->st_size = from->st_size; - to->st_blksize = from->st_blksize; - to->st_blocks = from->st_blocks; - to->st_atime_ = from->st_atime; - to->st_mtime_ = from->st_mtime; - to->st_ctime_ = from->st_ctime; - - return 0; -} -#endif /* ndef HAVE_STRUCT_STAT */ - - int Mono_Posix_FromSysconfName (int x, int *r) { *r = 0; diff --git a/support/map.h b/support/map.h index 77d75db3ad4..a78caf0ef9e 100644 --- a/support/map.h +++ b/support/map.h @@ -1452,7 +1452,6 @@ struct Mono_Unix_UnixSignal_SignalInfo; struct flock; struct iovec; struct pollfd; -struct stat; struct timespec; struct timeval; struct timezone; @@ -1506,28 +1505,25 @@ Mono_Posix_ToPollfd (struct pollfd *from, struct Mono_Posix_Pollfd* to); struct Mono_Posix_Stat { - guint64 st_dev; /* dev_t */ - guint64 st_ino; /* ino_t */ + guint64 st_dev; /* dev_t */ + guint64 st_ino; /* ino_t */ unsigned int st_mode; unsigned int _padding_; - guint64 st_nlink; /* nlink_t */ - unsigned int st_uid; /* uid_t */ - unsigned int st_gid; /* gid_t */ - guint64 st_rdev; /* dev_t */ - gint64 st_size; /* off_t */ - gint64 st_blksize; /* blksize_t */ - gint64 st_blocks; /* blkcnt_t */ - gint64 st_atime_; /* time_t */ - gint64 st_mtime_; /* time_t */ - gint64 st_ctime_; /* time_t */ + guint64 st_nlink; /* nlink_t */ + unsigned int st_uid; /* uid_t */ + unsigned int st_gid; /* gid_t */ + guint64 st_rdev; /* dev_t */ + gint64 st_size; /* off_t */ + gint64 st_blksize; /* blksize_t */ + gint64 st_blocks; /* blkcnt_t */ + gint64 st_atime_; /* time_t */ + gint64 st_mtime_; /* time_t */ + gint64 st_ctime_; /* time_t */ + gint64 st_atime_nsec; + gint64 st_mtime_nsec; + gint64 st_ctime_nsec; }; -int -Mono_Posix_FromStat (struct Mono_Posix_Stat* from, struct stat *to); -int -Mono_Posix_ToStat (struct stat *from, struct Mono_Posix_Stat* to); - - struct Mono_Posix_Statvfs { guint64 f_bsize; guint64 f_frsize; @@ -1658,6 +1654,7 @@ int map_Mono_Posix_FileMode (int mode); int map_Mono_Posix_OpenFlags (int flags); int map_Mono_Posix_WaitOptions (int wait_options); int Mono_Posix_FromRealTimeSignum (int offset, int* rval); +int Mono_Posix_FromStat (struct Mono_Posix_Stat* source, void* destination); int Mono_Posix_FromStatvfs (struct Mono_Posix_Statvfs* source, void* destination); int Mono_Posix_SIGRTMAX (void); int Mono_Posix_SIGRTMIN (void); @@ -1825,6 +1822,7 @@ gint64 Mono_Posix_Syscall_write (int fd, void* buf, guint64 count); gint64 Mono_Posix_Syscall_writev (int fd, struct Mono_Posix_Iovec* iov, int iovcnt); int Mono_Posix_Syscall_WSTOPSIG (int status); int Mono_Posix_Syscall_WTERMSIG (int status); +int Mono_Posix_ToStat (void* source, struct Mono_Posix_Stat* destination); int Mono_Posix_ToStatvfs (void* source, struct Mono_Posix_Statvfs* destination); void* Mono_Unix_UnixSignal_install (int signum); int Mono_Unix_UnixSignal_uninstall (void* info); diff --git a/support/sys-stat.c b/support/sys-stat.c index 54d53086801..52ab1cf4689 100644 --- a/support/sys-stat.c +++ b/support/sys-stat.c @@ -22,6 +22,74 @@ G_BEGIN_DECLS +int +Mono_Posix_FromStat (struct Mono_Posix_Stat *from, void *_to) +{ + struct stat *to = _to; + memset (to, 0, sizeof(*to)); + + to->st_dev = from->st_dev; + to->st_ino = from->st_ino; + if (Mono_Posix_FromFilePermissions (from->st_mode, &to->st_mode) != 0) { + return -1; + } + to->st_nlink = from->st_nlink; + to->st_uid = from->st_uid; + to->st_gid = from->st_gid; + to->st_rdev = from->st_rdev; + to->st_size = from->st_size; + to->st_blksize = from->st_blksize; + to->st_blocks = from->st_blocks; + to->st_atime = from->st_atime_; + to->st_mtime = from->st_mtime_; + to->st_ctime = from->st_ctime_; +#ifdef HAVE_STRUCT_STAT_ST_ATIM + to->st_atim.tv_nsec = from->st_atime_nsec; +#endif +#ifdef HAVE_STRUCT_STAT_ST_MTIM + to->st_mtim.tv_nsec = from->st_mtime_nsec; +#endif +#ifdef HAVE_STRUCT_STAT_ST_CTIM + to->st_ctim.tv_nsec = from->st_ctime_nsec; +#endif + + return 0; +} + +int +Mono_Posix_ToStat (void *_from, struct Mono_Posix_Stat *to) +{ + struct stat *from = _from; + memset (to, 0, sizeof(*to)); + + to->st_dev = from->st_dev; + to->st_ino = from->st_ino; + if (Mono_Posix_ToFilePermissions (from->st_mode, &to->st_mode) != 0) { + return -1; + } + to->st_nlink = from->st_nlink; + to->st_uid = from->st_uid; + to->st_gid = from->st_gid; + to->st_rdev = from->st_rdev; + to->st_size = from->st_size; + to->st_blksize = from->st_blksize; + to->st_blocks = from->st_blocks; + to->st_atime_ = from->st_atime; + to->st_mtime_ = from->st_mtime; + to->st_ctime_ = from->st_ctime; +#ifdef HAVE_STRUCT_STAT_ST_ATIM + to->st_atime_nsec = from->st_atim.tv_nsec; +#endif +#ifdef HAVE_STRUCT_STAT_ST_MTIM + to->st_mtime_nsec = from->st_mtim.tv_nsec; +#endif +#ifdef HAVE_STRUCT_STAT_ST_CTIM + to->st_ctime_nsec = from->st_ctim.tv_nsec; +#endif + + return 0; +} + gint32 Mono_Posix_Syscall_stat (const char *file_name, struct Mono_Posix_Stat *buf) {