Add nanosecond resolution times to struct Stat
authorSteffen Kieß <s-kiess@web.de>
Wed, 27 Mar 2013 12:45:50 +0000 (13:45 +0100)
committerSteffen Kieß <s-kiess@web.de>
Wed, 27 Mar 2013 12:45:50 +0000 (13:45 +0100)
configure.in
mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs
mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs
mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs
support/map.c
support/map.h
support/sys-stat.c

index c32d35fc442b6424a2584eef49fd806991de5fa1..b400832a1ddb9d835493de514db989ec7f123940 100644 (file)
@@ -2007,6 +2007,11 @@ if test x$target_win32 = xno; then
                [struct statfs.f_flags],,, 
                [#include <sys/types.h>
                 #include <sys/vfs.h>])
+       AC_CHECK_MEMBERS(
+               [struct stat.st_atim, struct stat.st_mtim, struct stat.st_ctim],,, 
+               [#include <sys/types.h>
+                #include <sys/stat.h>
+                #include <unistd.h>])
 
        dnl Favour xattr through glibc, but use libattr if we have to
        AC_CHECK_FUNC(lsetxattr, ,
index 7ac5a750f411def545f26595c5c960f0299194ca..4c56a293d517780d16e64f0e8107db4c6cf71dad 100644 (file)
@@ -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);
 
index e5e41cc3b0cc0d1989d1f2a35fcb1491b25aece0..d9097f8d7a3394610167957639000144950b97e6 100644 (file)
@@ -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);
 
index 083fb6c40936b97f6f5c93b46802743d012668c7..27d241539d5a7e3a35ea4d74436ff211bdfd4afb 100644 (file)
@@ -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 <Stat>
@@ -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)
index 2150cb29bbba031e1ac9d4391df127c569bc96ab..8374331c09a3e090fdd95e8c47efb7819b68ef7a 100644 (file)
@@ -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;
index 77d75db3ad41fe077fb0d1ea0bc5b01a75b6e443..a78caf0ef9e478cc30e1f40e3a8afa6b90f73aa2 100644 (file)
@@ -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);
index 54d53086801464ef70e413d869a08febd325e57a..52ab1cf46898e6a3f810341b656e6e211f453d40 100644 (file)
 
 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)
 {