diff options
| author | Eli Zaretskii | 2019-04-15 17:17:01 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2019-04-15 17:17:01 +0300 |
| commit | 3ec22997a208b8260c2a0e7a61888d7c0db4e4fd (patch) | |
| tree | 24844ac09b4a6e26993de84101d82284f7648a23 | |
| parent | e29260b5f946156652c92fe77f97450c756d0367 (diff) | |
| download | emacs-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.c | 5 | ||||
| -rw-r--r-- | lib-src/ntlib.c | 100 |
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 | ||
| 55 | int | 60 | int |
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. */ |
| 295 | int | 295 | int |
| 296 | stat (const char * path, struct stat * buf) | 296 | stat (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 | ||
| 413 | int | ||
| 414 | fstat (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. */ |
| 412 | int | 506 | int |
| 413 | sys_rename (const char *from, const char *to) | 507 | sys_rename (const char *from, const char *to) |