aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/dd.c25
-rw-r--r--include/mingw.h2
-rw-r--r--win32/mingw.c6
3 files changed, 26 insertions, 7 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index fc8b1dbb2..042355e24 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -466,6 +466,27 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
466 466
467 xmove_fd(xopen(outfile, oflag), ofd); 467 xmove_fd(xopen(outfile, oflag), ofd);
468 468
469#if ENABLE_PLATFORM_MINGW32
470 {
471 off_t len = (off_t)seek * ((G.flags & FLAG_SEEK_BYTES) ? 1 : obs);
472 struct stat st;
473 int ret = fstat(ofd, &st);
474
475 if (ret == 0 && !(G.flags & FLAG_APPEND) && len > st.st_size)
476 make_sparse(ofd, st.st_size, len);
477
478 if (seek && !(G.flags & FLAG_NOTRUNC)) {
479 if (ftruncate(ofd, len) < 0) {
480 if (ret < 0
481 || S_ISREG(st.st_mode)
482 || S_ISDIR(st.st_mode)
483 ) {
484 goto die_outfile;
485 }
486 }
487 }
488 }
489#else
469 if (seek && !(G.flags & FLAG_NOTRUNC)) { 490 if (seek && !(G.flags & FLAG_NOTRUNC)) {
470 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs; 491 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs;
471 if (ftruncate(ofd, seek * blocksz) < 0) { 492 if (ftruncate(ofd, seek * blocksz) < 0) {
@@ -479,6 +500,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
479 } 500 }
480 } 501 }
481 } 502 }
503#endif
482 } else { 504 } else {
483 outfile = bb_msg_standard_output; 505 outfile = bb_msg_standard_output;
484 } 506 }
@@ -502,9 +524,6 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
502 } 524 }
503 if (seek) { 525 if (seek) {
504 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs; 526 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs;
505#if ENABLE_PLATFORM_MINGW32
506 seek_sparse(ofd, seek * blocksz);
507#endif
508 if (lseek(ofd, seek * blocksz, SEEK_CUR) < 0) 527 if (lseek(ofd, seek * blocksz, SEEK_CUR) < 0)
509 goto die_outfile; 528 goto die_outfile;
510 } 529 }
diff --git a/include/mingw.h b/include/mingw.h
index 0fead43c9..39d716521 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -537,5 +537,5 @@ int chdir_system_drive(void);
537char *xabsolute_path(char *path); 537char *xabsolute_path(char *path);
538char *get_drive_cwd(const char *path, char *buffer, int size); 538char *get_drive_cwd(const char *path, char *buffer, int size);
539void fix_path_case(char *path); 539void fix_path_case(char *path);
540void seek_sparse(int fd, size_t size); 540void make_sparse(int fd, off_t start, off_t end);
541int skip_ansi_emulation(int reset); 541int skip_ansi_emulation(int reset);
diff --git a/win32/mingw.c b/win32/mingw.c
index 7f8fecdc3..5c4c39b9d 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1751,7 +1751,7 @@ void fix_path_case(char *path)
1751 } 1751 }
1752} 1752}
1753 1753
1754void seek_sparse(int fd, size_t size) 1754void make_sparse(int fd, off_t start, off_t end)
1755{ 1755{
1756 DWORD dwTemp; 1756 DWORD dwTemp;
1757 HANDLE fh; 1757 HANDLE fh;
@@ -1762,8 +1762,8 @@ void seek_sparse(int fd, size_t size)
1762 1762
1763 DeviceIoControl(fh, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwTemp, NULL); 1763 DeviceIoControl(fh, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwTemp, NULL);
1764 1764
1765 fzdi.FileOffset.QuadPart = 0; 1765 fzdi.FileOffset.QuadPart = start;
1766 fzdi.BeyondFinalZero.QuadPart = size; 1766 fzdi.BeyondFinalZero.QuadPart = end;
1767 DeviceIoControl(fh, FSCTL_SET_ZERO_DATA, &fzdi, sizeof(fzdi), 1767 DeviceIoControl(fh, FSCTL_SET_ZERO_DATA, &fzdi, sizeof(fzdi),
1768 NULL, 0, &dwTemp, NULL); 1768 NULL, 0, &dwTemp, NULL);
1769} 1769}