diff options
author | Ron Yorston <rmy@pobox.com> | 2019-02-16 12:36:52 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-02-16 12:36:52 +0000 |
commit | d82db8e9a618ddd9a11cc57aff37f687abb0effb (patch) | |
tree | bd072e7344a3c3f0eff553d41c0f154c4470736e /win32 | |
parent | 91e49fbc7b55e8be78ac3ff943e9b7d4494dfe59 (diff) | |
download | busybox-w32-d82db8e9a618ddd9a11cc57aff37f687abb0effb.tar.gz busybox-w32-d82db8e9a618ddd9a11cc57aff37f687abb0effb.tar.bz2 busybox-w32-d82db8e9a618ddd9a11cc57aff37f687abb0effb.zip |
win32: make stat(2) fetch additional metadata
Modify the WIN32 implementation of stat(2) to fetch inode number,
device id and number of hardlinks. This requires opening a handle
to the target file so it will be slower.
A number of features can be enabled or start to work:
- tar can detect if an archive is being stored in itself;
- find can support the -inum and -links options;
- ls can display inode numbers;
- diff can detect attempts to compare a file with itself;
- du has better support for hardlinked files;
- cp can detect attempts to copy a file over itself.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/mingw.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index 8217ec772..03636a04b 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -403,7 +403,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
403 | buf->st_ino = 0; | 403 | buf->st_ino = 0; |
404 | buf->st_uid = DEFAULT_UID; | 404 | buf->st_uid = DEFAULT_UID; |
405 | buf->st_gid = DEFAULT_GID; | 405 | buf->st_gid = DEFAULT_GID; |
406 | buf->st_nlink = 1; | 406 | buf->st_nlink = S_ISDIR(buf->st_mode) ? 2 : 1; |
407 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); | 407 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); |
408 | if (S_ISREG(buf->st_mode) && | 408 | if (S_ISREG(buf->st_mode) && |
409 | (has_exe_suffix(file_name) || has_exec_format(file_name))) | 409 | (has_exe_suffix(file_name) || has_exec_format(file_name))) |
@@ -434,6 +434,30 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | ||
438 | { | ||
439 | BY_HANDLE_FILE_INFORMATION hdata; | ||
440 | HANDLE fh = CreateFile(file_name, 0, | ||
441 | 0, NULL, OPEN_EXISTING, | ||
442 | FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, | ||
443 | NULL); | ||
444 | if (fh != INVALID_HANDLE_VALUE) { | ||
445 | if (GetFileInformationByHandle(fh, &hdata)) { | ||
446 | buf->st_dev = hdata.dwVolumeSerialNumber; | ||
447 | buf->st_ino = hdata.nFileIndexLow | | ||
448 | (((uint64_t)hdata.nFileIndexHigh)<<32); | ||
449 | buf->st_nlink = S_ISDIR(buf->st_mode) ? 2 : | ||
450 | hdata.nNumberOfLinks; | ||
451 | } | ||
452 | CloseHandle(fh); | ||
453 | } | ||
454 | else { | ||
455 | errno = err_win_to_posix(GetLastError()); | ||
456 | return -1; | ||
457 | } | ||
458 | } | ||
459 | #endif | ||
460 | |||
437 | /* | 461 | /* |
438 | * Assume a block is 4096 bytes and calculate number of 512 byte | 462 | * Assume a block is 4096 bytes and calculate number of 512 byte |
439 | * sectors. | 463 | * sectors. |
@@ -522,12 +546,19 @@ int mingw_fstat(int fd, struct mingw_stat *buf) | |||
522 | buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); | 546 | buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); |
523 | buf->st_blocks = ((buf->st_size+4095)>>12)<<3; | 547 | buf->st_blocks = ((buf->st_size+4095)>>12)<<3; |
524 | success: | 548 | success: |
525 | buf->st_dev = buf->st_rdev = 0; | 549 | #if ENABLE_FEATURE_EXTRA_FILE_DATA |
550 | buf->st_dev = fdata.dwVolumeSerialNumber; | ||
551 | buf->st_ino = fdata.nFileIndexLow | | ||
552 | (((uint64_t)fdata.nFileIndexHigh)<<32); | ||
553 | buf->st_nlink = S_ISDIR(buf->st_mode) ? 2 : fdata.nNumberOfLinks; | ||
554 | #else | ||
555 | buf->st_dev = 0; | ||
526 | buf->st_ino = 0; | 556 | buf->st_ino = 0; |
557 | buf->st_nlink = S_ISDIR(buf->st_mode) ? 2 : 1; | ||
558 | #endif | ||
559 | buf->st_rdev = 0; | ||
527 | buf->st_uid = DEFAULT_UID; | 560 | buf->st_uid = DEFAULT_UID; |
528 | buf->st_gid = DEFAULT_GID; | 561 | buf->st_gid = DEFAULT_GID; |
529 | /* could use fdata.nNumberOfLinks but it's inconsistent with stat */ | ||
530 | buf->st_nlink = 1; | ||
531 | buf->st_blksize = 4096; | 562 | buf->st_blksize = 4096; |
532 | return 0; | 563 | return 0; |
533 | } | 564 | } |