aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2019-04-15 17:17:01 +0300
committerEli Zaretskii2019-04-15 17:17:01 +0300
commit3ec22997a208b8260c2a0e7a61888d7c0db4e4fd (patch)
tree24844ac09b4a6e26993de84101d82284f7648a23
parente29260b5f946156652c92fe77f97450c756d0367 (diff)
downloademacs-3ec22997a208b8260c2a0e7a61888d7c0db4e4fd.tar.gz
emacs-3ec22997a208b8260c2a0e7a61888d7c0db4e4fd.zip
Fix MS-Windows build broken by make-fingerprint changes
* lib-src/make-fingerprint.c (fseeko) [WNDOWSNT]: Define to fseeko64 for non-MinGW64 MinGW. * lib-src/ntlib.c (stat): Fix calculation of file size. (fstat): New function, a subset of src/w32.c:fstat. This is needed because make-fingerprint.c now calls 'fstat', and the MS version will fail to produce reliable results because nt/inc/sys/stat.h redefines 'struct stat'.
-rw-r--r--lib-src/make-fingerprint.c5
-rw-r--r--lib-src/ntlib.c100
2 files changed, 102 insertions, 3 deletions
diff --git a/lib-src/make-fingerprint.c b/lib-src/make-fingerprint.c
index dc21fc2aa9a..535e5751320 100644
--- a/lib-src/make-fingerprint.c
+++ b/lib-src/make-fingerprint.c
@@ -50,6 +50,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50 is really just insurance. */ 50 is really just insurance. */
51#undef fopen 51#undef fopen
52#include <direct.h> 52#include <direct.h>
53
54#ifndef MINGW_W64
55# undef fseeko
56# define fseeko fseeko64
57#endif
53#endif /* WINDOWSNT */ 58#endif /* WINDOWSNT */
54 59
55int 60int
diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c
index dbafc47da28..d992f54a0fa 100644
--- a/lib-src/ntlib.c
+++ b/lib-src/ntlib.c
@@ -290,8 +290,8 @@ is_exec (const char * name)
290/* FIXME? This is in configure.ac now - is this still needed? */ 290/* FIXME? This is in configure.ac now - is this still needed? */
291#define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\') 291#define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\')
292 292
293/* We need this because nt/inc/sys/stat.h defines struct stat that is 293/* We need stat/fsfat below because nt/inc/sys/stat.h defines struct
294 incompatible with the MS run-time libraries. */ 294 stat that is incompatible with the MS run-time libraries. */
295int 295int
296stat (const char * path, struct stat * buf) 296stat (const char * path, struct stat * buf)
297{ 297{
@@ -377,7 +377,9 @@ stat (const char * path, struct stat * buf)
377 buf->st_dev = _getdrive (); 377 buf->st_dev = _getdrive ();
378 buf->st_rdev = buf->st_dev; 378 buf->st_rdev = buf->st_dev;
379 379
380 buf->st_size = wfd.nFileSizeLow; 380 buf->st_size = wfd.nFileSizeHigh;
381 buf->st_size <<= 32;
382 buf->st_size += wfd.nFileSizeLow;
381 383
382 /* Convert timestamps to Unix format. */ 384 /* Convert timestamps to Unix format. */
383 buf->st_mtime = convert_time (wfd.ftLastWriteTime); 385 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
@@ -408,6 +410,98 @@ lstat (const char * path, struct stat * buf)
408 return stat (path, buf); 410 return stat (path, buf);
409} 411}
410 412
413int
414fstat (int desc, struct stat * buf)
415{
416 HANDLE fh = (HANDLE) _get_osfhandle (desc);
417 BY_HANDLE_FILE_INFORMATION info;
418 unsigned __int64 fake_inode;
419 int permission;
420
421 if (!init)
422 {
423 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
424 SYSTEMTIME st;
425
426 st.wYear = 1970;
427 st.wMonth = 1;
428 st.wDay = 1;
429 st.wHour = 0;
430 st.wMinute = 0;
431 st.wSecond = 0;
432 st.wMilliseconds = 0;
433
434 SystemTimeToFileTime (&st, &utc_base_ft);
435 utc_base = (long double) utc_base_ft.dwHighDateTime
436 * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
437 init = 1;
438 }
439
440 switch (GetFileType (fh) & ~FILE_TYPE_REMOTE)
441 {
442 case FILE_TYPE_DISK:
443 buf->st_mode = S_IFREG;
444 if (!GetFileInformationByHandle (fh, &info))
445 {
446 errno = EACCES;
447 return -1;
448 }
449 break;
450 case FILE_TYPE_PIPE:
451 buf->st_mode = S_IFIFO;
452 goto non_disk;
453 case FILE_TYPE_CHAR:
454 case FILE_TYPE_UNKNOWN:
455 default:
456 buf->st_mode = S_IFCHR;
457 non_disk:
458 memset (&info, 0, sizeof (info));
459 info.dwFileAttributes = 0;
460 info.ftCreationTime = utc_base_ft;
461 info.ftLastAccessTime = utc_base_ft;
462 info.ftLastWriteTime = utc_base_ft;
463 }
464
465 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
466 buf->st_mode = S_IFDIR;
467
468 buf->st_nlink = info.nNumberOfLinks;
469 /* Might as well use file index to fake inode values, but this
470 is not guaranteed to be unique unless we keep a handle open
471 all the time. */
472 fake_inode = info.nFileIndexHigh;
473 fake_inode <<= 32;
474 fake_inode += info.nFileIndexLow;
475 buf->st_ino = fake_inode;
476
477 buf->st_dev = info.dwVolumeSerialNumber;
478 buf->st_rdev = info.dwVolumeSerialNumber;
479
480 buf->st_size = info.nFileSizeHigh;
481 buf->st_size <<= 32;
482 buf->st_size += info.nFileSizeLow;
483
484 /* Convert timestamps to Unix format. */
485 buf->st_mtime = convert_time (info.ftLastWriteTime);
486 buf->st_atime = convert_time (info.ftLastAccessTime);
487 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
488 buf->st_ctime = convert_time (info.ftCreationTime);
489 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
490
491 /* determine rwx permissions */
492 if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
493 permission = S_IREAD;
494 else
495 permission = S_IREAD | S_IWRITE;
496
497 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
498 permission |= S_IEXEC;
499
500 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
501
502 return 0;
503}
504
411/* On Windows, you cannot rename into an existing file. */ 505/* On Windows, you cannot rename into an existing file. */
412int 506int
413sys_rename (const char *from, const char *to) 507sys_rename (const char *from, const char *to)