summaryrefslogtreecommitdiff
path: root/win32/win32.h
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2020-10-06 17:07:00 +1100
committerTony Cook <tony@develop-help.com>2020-12-01 15:29:33 +1100
commit92b3a3ebc05e3ce0e84a1ccff46487ca2200b471 (patch)
treefbeb49a61e3dca1e48e9382b4e316b430628623a /win32/win32.h
parentc1ec4bdd803f587dd2ae76548bca0ae59d0fe84b (diff)
downloadperl-92b3a3ebc05e3ce0e84a1ccff46487ca2200b471.tar.gz
Win32: add lstat(), fetch st_dev and st_ino and fetch st_nlink for fstat
We need lstat() for various modules to work well with symlinks, and the same modules often want to check for matches on the device and inode number. The values we're using for st_ino match those that the Python and Rust libraries use, and Go uses the same volume and file index values for testing if two stat objects refer to the same file. They aren't entirely unique, given ReFS uses 128-bit file ids, but the API used to check for this (GetFileInformationByHandleEx() for FileIdInfo) is only available on server operating systems, so I can't directly test it anyway.
Diffstat (limited to 'win32/win32.h')
-rw-r--r--win32/win32.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/win32/win32.h b/win32/win32.h
index 00d052ac9c..171cbfb8b8 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -731,5 +731,37 @@ DllExport void *win32_signal_context(void);
# define O_ACCMODE (O_RDWR | O_WRONLY | O_RDONLY)
#endif
+/* ucrt at least seems to allocate a whole bit per type,
+ just mask off one bit from the mask for our symlink
+ file type.
+*/
+#define _S_IFLNK ((unsigned)(_S_IFMT ^ (_S_IFMT & -_S_IFMT)))
+#undef S_ISLNK
+#define S_ISLNK(mode) (((mode) & _S_IFMT) == _S_IFLNK)
+
+/*
+
+The default CRT struct stat uses unsigned short for st_dev and st_ino
+which obviously isn't enough, so we define our own structure.
+
+ */
+
+typedef DWORD Dev_t;
+typedef unsigned __int64 Ino_t;
+
+struct w32_stat {
+ Dev_t st_dev;
+ Ino_t st_ino;
+ unsigned short st_mode;
+ DWORD st_nlink;
+ short st_uid;
+ short st_gid;
+ Dev_t st_rdev;
+ Off_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+};
+
#endif /* _INC_WIN32_PERL5 */