aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/date.c25
-rw-r--r--coreutils/dd.c61
-rw-r--r--coreutils/du.c2
-rw-r--r--coreutils/expr.c2
-rw-r--r--coreutils/factor.c4
-rw-r--r--coreutils/ls.c80
-rw-r--r--coreutils/nproc.c18
-rw-r--r--coreutils/od_bloaty.c7
-rw-r--r--coreutils/printf.c68
-rw-r--r--coreutils/shred.c10
-rw-r--r--coreutils/shuf.c2
-rw-r--r--coreutils/split.c8
-rw-r--r--coreutils/stat.c5
-rw-r--r--coreutils/sum.c4
-rw-r--r--coreutils/timeout.c76
-rw-r--r--coreutils/yes.c5
16 files changed, 356 insertions, 21 deletions
diff --git a/coreutils/date.c b/coreutils/date.c
index 3a89b6caf..d8e56ef3b 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -97,7 +97,9 @@
97//usage:#define date_full_usage "\n\n" 97//usage:#define date_full_usage "\n\n"
98//usage: "Display time (using +FMT), or set time\n" 98//usage: "Display time (using +FMT), or set time\n"
99//usage: "\n -u Work in UTC (don't convert to local time)" 99//usage: "\n -u Work in UTC (don't convert to local time)"
100//usage: IF_NOT_PLATFORM_MINGW32(
100//usage: "\n [-s] TIME Set time to TIME" 101//usage: "\n [-s] TIME Set time to TIME"
102//usage: )
101//usage: "\n -d TIME Display TIME, not 'now'" 103//usage: "\n -d TIME Display TIME, not 'now'"
102//usage: IF_FEATURE_DATE_ISOFMT( 104//usage: IF_FEATURE_DATE_ISOFMT(
103//usage: "\n -D FMT FMT (strptime format) for -s/-d TIME conversion" 105//usage: "\n -D FMT FMT (strptime format) for -s/-d TIME conversion"
@@ -132,19 +134,30 @@
132 134
133enum { 135enum {
134 OPT_RFC2822 = (1 << 0), /* R */ 136 OPT_RFC2822 = (1 << 0), /* R */
137#if !ENABLE_PLATFORM_MINGW32
135 OPT_SET = (1 << 1), /* s */ 138 OPT_SET = (1 << 1), /* s */
136 OPT_UTC = (1 << 2), /* u */ 139 OPT_UTC = (1 << 2), /* u */
137 OPT_DATE = (1 << 3), /* d */ 140 OPT_DATE = (1 << 3), /* d */
138 OPT_REFERENCE = (1 << 4), /* r */ 141 OPT_REFERENCE = (1 << 4), /* r */
139 OPT_ISO8601 = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */ 142 OPT_ISO8601 = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
140 OPT_STR2DT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */ 143 OPT_STR2DT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
144#else
145 OPT_SET = (0), /* s */
146 OPT_UTC = (1 << 1), /* u */
147 OPT_DATE = (1 << 2), /* d */
148 OPT_REFERENCE = (1 << 3), /* r */
149 OPT_ISO8601 = (1 << 4) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
150 OPT_STR2DT = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
151#endif
141}; 152};
142 153
143#if ENABLE_LONG_OPTS 154#if ENABLE_LONG_OPTS
144static const char date_longopts[] ALIGN1 = 155static const char date_longopts[] ALIGN1 =
145 "rfc-822\0" No_argument "R" 156 "rfc-822\0" No_argument "R"
146 "rfc-2822\0" No_argument "R" 157 "rfc-2822\0" No_argument "R"
158#if !ENABLE_PLATFORM_MINGW32
147 "set\0" Required_argument "s" 159 "set\0" Required_argument "s"
160#endif
148 "utc\0" No_argument "u" 161 "utc\0" No_argument "u"
149 /* "universal\0" No_argument "u" */ 162 /* "universal\0" No_argument "u" */
150 "date\0" Required_argument "d" 163 "date\0" Required_argument "d"
@@ -174,13 +187,25 @@ int date_main(int argc UNUSED_PARAM, char **argv)
174 char *isofmt_arg = NULL; 187 char *isofmt_arg = NULL;
175 188
176 opt = getopt32long(argv, "^" 189 opt = getopt32long(argv, "^"
190#if !ENABLE_PLATFORM_MINGW32
177 "Rs:ud:r:" 191 "Rs:ud:r:"
192#else
193 "Rud:r:"
194#endif
178 IF_FEATURE_DATE_ISOFMT("I::D:") 195 IF_FEATURE_DATE_ISOFMT("I::D:")
196#if !ENABLE_PLATFORM_MINGW32
179 "\0" 197 "\0"
180 "d--s:s--d" 198 "d--s:s--d"
181 IF_FEATURE_DATE_ISOFMT(":R--I:I--R"), 199 IF_FEATURE_DATE_ISOFMT(":R--I:I--R"),
200#else
201 IF_FEATURE_DATE_ISOFMT("\0R--I:I--R"),
202#endif
182 date_longopts, 203 date_longopts,
204#if !ENABLE_PLATFORM_MINGW32
183 &date_str, &date_str, &filename 205 &date_str, &date_str, &filename
206#else
207 &date_str, &filename
208#endif
184 IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt) 209 IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)
185 ); 210 );
186 argv += optind; 211 argv += optind;
diff --git a/coreutils/dd.c b/coreutils/dd.c
index c032ebe1b..51f3adf24 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -59,8 +59,13 @@
59//usage: "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]" 59//usage: "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]"
60//usage: IF_FEATURE_DD_IBS_OBS("\n" 60//usage: IF_FEATURE_DD_IBS_OBS("\n"
61//usage: " [conv=notrunc|noerror|sync|fsync]\n" 61//usage: " [conv=notrunc|noerror|sync|fsync]\n"
62//usage: IF_NOT_PLATFORM_MINGW32(
62//usage: " [iflag=skip_bytes|count_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]" 63//usage: " [iflag=skip_bytes|count_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]"
63//usage: ) 64//usage: )
65//usage: IF_PLATFORM_MINGW32(
66//usage: " [iflag=skip_bytes|count_bytes|fullblock] [oflag=seek_bytes|append]"
67//usage: )
68//usage: )
64//usage:#define dd_full_usage "\n\n" 69//usage:#define dd_full_usage "\n\n"
65//usage: "Copy a file with converting and formatting\n" 70//usage: "Copy a file with converting and formatting\n"
66//usage: "\n if=FILE Read from FILE instead of stdin" 71//usage: "\n if=FILE Read from FILE instead of stdin"
@@ -84,8 +89,10 @@
84//usage: "\n iflag=skip_bytes skip=N is in bytes" 89//usage: "\n iflag=skip_bytes skip=N is in bytes"
85//usage: "\n iflag=count_bytes count=N is in bytes" 90//usage: "\n iflag=count_bytes count=N is in bytes"
86//usage: "\n oflag=seek_bytes seek=N is in bytes" 91//usage: "\n oflag=seek_bytes seek=N is in bytes"
92//usage: IF_NOT_PLATFORM_MINGW32(
87//usage: "\n iflag=direct O_DIRECT input" 93//usage: "\n iflag=direct O_DIRECT input"
88//usage: "\n oflag=direct O_DIRECT output" 94//usage: "\n oflag=direct O_DIRECT output"
95//usage: )
89//usage: "\n iflag=fullblock Read full blocks" 96//usage: "\n iflag=fullblock Read full blocks"
90//usage: "\n oflag=append Open output in append mode" 97//usage: "\n oflag=append Open output in append mode"
91//usage: ) 98//usage: )
@@ -94,6 +101,9 @@
94//usage: "\n status=none Suppress all output" 101//usage: "\n status=none Suppress all output"
95//usage: ) 102//usage: )
96//usage: "\n" 103//usage: "\n"
104//usage: IF_PLATFORM_MINGW32(
105//usage: "\nif=/dev/zero and if=/dev/urandom are supported"
106//usage: )
97//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G" 107//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G"
98//usage: 108//usage:
99//usage:#define dd_example_usage 109//usage:#define dd_example_usage
@@ -104,6 +114,10 @@
104#include "libbb.h" 114#include "libbb.h"
105#include "common_bufsiz.h" 115#include "common_bufsiz.h"
106 116
117#if ENABLE_PLATFORM_MINGW32
118# undef O_DIRECT
119#endif
120
107/* This is a NOEXEC applet. Be very careful! */ 121/* This is a NOEXEC applet. Be very careful! */
108 122
109 123
@@ -141,13 +155,13 @@ enum {
141 FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, 155 FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
142 FLAG_COUNT_BYTES = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, 156 FLAG_COUNT_BYTES = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
143 FLAG_FULLBLOCK = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS, 157 FLAG_FULLBLOCK = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
144 FLAG_IDIRECT = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS, 158 FLAG_IDIRECT = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS * ENABLE_PLATFORM_POSIX,
145 /* end of input flags */ 159 /* end of input flags */
146 /* start of output flags */ 160 /* start of output flags */
147 FLAG_OFLAG_SHIFT = 9, 161 FLAG_OFLAG_SHIFT = 9,
148 FLAG_SEEK_BYTES = (1 << 9) * ENABLE_FEATURE_DD_IBS_OBS, 162 FLAG_SEEK_BYTES = (1 << 9) * ENABLE_FEATURE_DD_IBS_OBS,
149 FLAG_APPEND = (1 << 10) * ENABLE_FEATURE_DD_IBS_OBS, 163 FLAG_APPEND = (1 << 10) * ENABLE_FEATURE_DD_IBS_OBS,
150 FLAG_ODIRECT = (1 << 11) * ENABLE_FEATURE_DD_IBS_OBS, 164 FLAG_ODIRECT = (1 << 11) * ENABLE_FEATURE_DD_IBS_OBS * ENABLE_PLATFORM_POSIX,
151 /* end of output flags */ 165 /* end of output flags */
152 FLAG_TWOBUFS = (1 << 12) * ENABLE_FEATURE_DD_IBS_OBS, 166 FLAG_TWOBUFS = (1 << 12) * ENABLE_FEATURE_DD_IBS_OBS,
153 FLAG_COUNT = 1 << 13, 167 FLAG_COUNT = 1 << 13,
@@ -220,7 +234,9 @@ static ssize_t dd_read(void *ibuf, size_t ibs)
220 ssize_t n; 234 ssize_t n;
221 235
222#if ENABLE_FEATURE_DD_IBS_OBS 236#if ENABLE_FEATURE_DD_IBS_OBS
237# if !ENABLE_PLATFORM_MINGW32
223 read_again: 238 read_again:
239# endif
224 if (G.flags & FLAG_FULLBLOCK) 240 if (G.flags & FLAG_FULLBLOCK)
225 n = full_read(ifd, ibuf, ibs); 241 n = full_read(ifd, ibuf, ibs);
226 else 242 else
@@ -240,7 +256,9 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
240{ 256{
241 ssize_t n; 257 ssize_t n;
242 258
259#if !ENABLE_PLATFORM_MINGW32
243 IF_FEATURE_DD_IBS_OBS(write_again:) 260 IF_FEATURE_DD_IBS_OBS(write_again:)
261#endif
244 n = full_write(ofd, buf, len); 262 n = full_write(ofd, buf, len);
245#if ENABLE_FEATURE_DD_IBS_OBS 263#if ENABLE_FEATURE_DD_IBS_OBS
246# ifdef O_DIRECT 264# ifdef O_DIRECT
@@ -307,9 +325,11 @@ static int parse_comma_flags(char *val, const char *words, const char *error_in)
307 325
308static void *alloc_buf(size_t size) 326static void *alloc_buf(size_t size)
309{ 327{
328#if !ENABLE_PLATFORM_MINGW32
310 /* Important for "{i,o}flag=direct" - buffers must be page aligned */ 329 /* Important for "{i,o}flag=direct" - buffers must be page aligned */
311 if (size >= bb_getpagesize()) 330 if (size >= bb_getpagesize())
312 return xmmap_anon(size); 331 return xmmap_anon(size);
332#endif
313 return xmalloc(size); 333 return xmalloc(size);
314} 334}
315 335
@@ -326,9 +346,9 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
326 static const char conv_words[] ALIGN1 = 346 static const char conv_words[] ALIGN1 =
327 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; 347 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
328 static const char iflag_words[] ALIGN1 = 348 static const char iflag_words[] ALIGN1 =
329 "skip_bytes\0""count_bytes\0""fullblock\0""direct\0"; 349 "skip_bytes\0""count_bytes\0""fullblock\0"IF_PLATFORM_POSIX("direct\0");
330 static const char oflag_words[] ALIGN1 = 350 static const char oflag_words[] ALIGN1 =
331 "seek_bytes\0append\0""direct\0"; 351 "seek_bytes\0append\0"IF_PLATFORM_POSIX("direct\0");
332#endif 352#endif
333#if ENABLE_FEATURE_DD_STATUS 353#if ENABLE_FEATURE_DD_STATUS
334 static const char status_words[] ALIGN1 = 354 static const char status_words[] ALIGN1 =
@@ -429,11 +449,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
429#if ENABLE_FEATURE_DD_IBS_OBS 449#if ENABLE_FEATURE_DD_IBS_OBS
430 if (what == OP_ibs) { 450 if (what == OP_ibs) {
431 /* Must fit into positive ssize_t */ 451 /* Must fit into positive ssize_t */
432 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 452 ibs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
433 /*continue;*/ 453 /*continue;*/
434 } 454 }
435 if (what == OP_obs) { 455 if (what == OP_obs) {
436 obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 456 obs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
437 /*continue;*/ 457 /*continue;*/
438 } 458 }
439 if (what == OP_conv) { 459 if (what == OP_conv) {
@@ -450,7 +470,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
450 } 470 }
451#endif 471#endif
452 if (what == OP_bs) { 472 if (what == OP_bs) {
453 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 473 ibs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
454 obs = ibs; 474 obs = ibs;
455 /*continue;*/ 475 /*continue;*/
456 } 476 }
@@ -515,7 +535,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
515# endif 535# endif
516 } 536 }
517#endif 537#endif
518 xmove_fd(xopen(infile, iflag), ifd); 538 xmove_fd(MINGW_SPECIAL(xopen)(infile, iflag), ifd);
539#if ENABLE_PLATFORM_MINGW32
540 update_special_fd(get_dev_type(infile), ifd);
541#endif
519 } else { 542 } else {
520 infile = bb_msg_standard_input; 543 infile = bb_msg_standard_input;
521 } 544 }
@@ -537,6 +560,27 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
537#endif 560#endif
538 xmove_fd(xopen(outfile, oflag), ofd); 561 xmove_fd(xopen(outfile, oflag), ofd);
539 562
563#if ENABLE_PLATFORM_MINGW32
564 {
565 off_t len = (off_t)seek * ((G.flags & FLAG_SEEK_BYTES) ? 1 : obs);
566 struct stat st;
567 int ret = fstat(ofd, &st);
568
569 if (ret == 0 && !(G.flags & FLAG_APPEND) && len > st.st_size)
570 make_sparse(ofd, st.st_size, len);
571
572 if (seek && !(G.flags & FLAG_NOTRUNC)) {
573 if (ftruncate(ofd, len) < 0) {
574 if (ret < 0
575 || S_ISREG(st.st_mode)
576 || S_ISDIR(st.st_mode)
577 ) {
578 goto die_outfile;
579 }
580 }
581 }
582 }
583#else
540 if (seek && !(G.flags & FLAG_NOTRUNC)) { 584 if (seek && !(G.flags & FLAG_NOTRUNC)) {
541 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs; 585 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs;
542 if (ftruncate(ofd, seek * blocksz) < 0) { 586 if (ftruncate(ofd, seek * blocksz) < 0) {
@@ -550,6 +594,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
550 } 594 }
551 } 595 }
552 } 596 }
597#endif
553 } else { 598 } else {
554 outfile = bb_msg_standard_output; 599 outfile = bb_msg_standard_output;
555 } 600 }
diff --git a/coreutils/du.c b/coreutils/du.c
index 4652b6300..338998fc9 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -137,7 +137,7 @@ static void print(unsigned long long size, const char *filename)
137 size >>= 10; 137 size >>= 10;
138 } 138 }
139 } 139 }
140 printf("%llu\t%s\n", size, filename); 140 printf("%"LL_FMT"u\t%s\n", size, filename);
141#endif 141#endif
142} 142}
143 143
diff --git a/coreutils/expr.c b/coreutils/expr.c
index 47ebe2fca..3f7e21871 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -84,7 +84,7 @@
84#if ENABLE_EXPR_MATH_SUPPORT_64 84#if ENABLE_EXPR_MATH_SUPPORT_64
85typedef int64_t arith_t; 85typedef int64_t arith_t;
86 86
87#define PF_REZ "ll" 87#define PF_REZ LL_FMT
88#define PF_REZ_TYPE (long long) 88#define PF_REZ_TYPE (long long)
89#define STRTOL(s, e, b) strtoll(s, e, b) 89#define STRTOL(s, e, b) strtoll(s, e, b)
90#else 90#else
diff --git a/coreutils/factor.c b/coreutils/factor.c
index 90e9ed761..9de5ea8eb 100644
--- a/coreutils/factor.c
+++ b/coreutils/factor.c
@@ -124,7 +124,7 @@ static NOINLINE void print_w(wide_t n)
124{ 124{
125 unsigned rep = square_count; 125 unsigned rep = square_count;
126 do 126 do
127 printf(" %llu", n); 127 printf(" %"LL_FMT"u", n);
128 while (--rep != 0); 128 while (--rep != 0);
129} 129}
130static NOINLINE void print_h(half_t n) 130static NOINLINE void print_h(half_t n)
@@ -226,7 +226,7 @@ static void factorize_numstr(const char *numstr)
226 N = bb_strtoull(numstr, NULL, 10); 226 N = bb_strtoull(numstr, NULL, 10);
227 if (errno) 227 if (errno)
228 bb_show_usage(); 228 bb_show_usage();
229 printf("%llu:", N); 229 printf("%"LL_FMT"u:", N);
230 square_count = 1; 230 square_count = 1;
231 factorize(N); 231 factorize(N);
232} 232}
diff --git a/coreutils/ls.c b/coreutils/ls.c
index b69b80460..df4277fbd 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -109,8 +109,11 @@
109//usage:#define ls_full_usage "\n\n" 109//usage:#define ls_full_usage "\n\n"
110//usage: "List directory contents\n" 110//usage: "List directory contents\n"
111//usage: "\n -1 One column output" 111//usage: "\n -1 One column output"
112//usage: "\n -a Include names starting with ." 112//usage: "\n -a Include names starting with ." IF_PLATFORM_MINGW32(" and hidden files")
113//usage: "\n -A Like -a, but exclude . and .." 113//usage: "\n -A Like -a, but exclude . and .."
114//usage: IF_PLATFORM_MINGW32(
115//usage: "\n -aa,-AA Like -a,-A but omit hidden system files"
116//usage: )
114////usage: "\n -C List by columns" - don't show, this is a default anyway 117////usage: "\n -C List by columns" - don't show, this is a default anyway
115//usage: "\n -x List by lines" 118//usage: "\n -x List by lines"
116//usage: "\n -d List directory names, not contents" 119//usage: "\n -d List directory names, not contents"
@@ -316,6 +319,9 @@ struct dnode {
316 int dn_rdev_min; 319 int dn_rdev_min;
317// dev_t dn_dev; 320// dev_t dn_dev;
318// blksize_t dn_blksize; 321// blksize_t dn_blksize;
322#if ENABLE_PLATFORM_MINGW32
323 DWORD dn_attr;
324#endif
319}; 325};
320 326
321struct globals { 327struct globals {
@@ -337,6 +343,10 @@ struct globals {
337 /* Do time() just once. Saves one syscall per file for "ls -l" */ 343 /* Do time() just once. Saves one syscall per file for "ls -l" */
338 time_t current_time_t; 344 time_t current_time_t;
339#endif 345#endif
346#if ENABLE_PLATFORM_MINGW32
347 int a_count, A_count;
348# define HIDSYS (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)
349#endif
340} FIX_ALIASING; 350} FIX_ALIASING;
341#define G (*(struct globals*)bb_common_bufsiz1) 351#define G (*(struct globals*)bb_common_bufsiz1)
342#define INIT_G() do { \ 352#define INIT_G() do { \
@@ -497,7 +507,11 @@ static NOINLINE unsigned display_single(const struct dnode *dn)
497 lpath = xmalloc_readlink_or_warn(dn->fullname); 507 lpath = xmalloc_readlink_or_warn(dn->fullname);
498 508
499 if (opt & OPT_i) /* show inode# */ 509 if (opt & OPT_i) /* show inode# */
500 column += printf("%7llu ", (long long) dn->dn_ino); 510#if !ENABLE_FEATURE_EXTRA_FILE_DATA
511 column += printf("%7"LL_FMT"u ", (long long) dn->dn_ino);
512#else
513 column += printf("%19"LL_FMT"u ", (long long) dn->dn_ino);
514#endif
501 if (opt & OPT_s) { /* show allocated blocks */ 515 if (opt & OPT_s) { /* show allocated blocks */
502 if (opt & OPT_h) { 516 if (opt & OPT_h) {
503 column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", 517 column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ",
@@ -659,7 +673,11 @@ static void display_files(struct dnode **dn, unsigned nfiles)
659 } 673 }
660 column_width += 2 674 column_width += 2
661 + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */ 675 + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */
676#if !ENABLE_FEATURE_EXTRA_FILE_DATA
662 + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */ 677 + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */
678#else
679 + ((option_mask32 & OPT_i) ? 20 : 0) /* inode# width */
680#endif
663 + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */ 681 + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */
664 ; 682 ;
665 ncols = (unsigned)G_terminal_width / column_width; 683 ncols = (unsigned)G_terminal_width / column_width;
@@ -740,6 +758,9 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f
740 758
741 /* cur->dstat = statbuf: */ 759 /* cur->dstat = statbuf: */
742 cur->dn_mode = statbuf.st_mode ; 760 cur->dn_mode = statbuf.st_mode ;
761#if ENABLE_PLATFORM_MINGW32
762 cur->dn_attr = statbuf.st_attr ;
763#endif
743 cur->dn_size = statbuf.st_size ; 764 cur->dn_size = statbuf.st_size ;
744#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES 765#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
745 cur->dn_time = statbuf.st_mtime ; 766 cur->dn_time = statbuf.st_mtime ;
@@ -920,6 +941,15 @@ static void sort_and_display_files(struct dnode **dn, unsigned nfiles)
920# define sort_and_display_files(dn, nfiles) display_files(dn, nfiles) 941# define sort_and_display_files(dn, nfiles) display_files(dn, nfiles)
921#endif 942#endif
922 943
944#if ENABLE_PLATFORM_MINGW32
945static int hide_file(DWORD attr)
946{
947 return
948 ((attr & FILE_ATTRIBUTE_HIDDEN) && !(option_mask32 & (OPT_a|OPT_A))) ||
949 (((attr & HIDSYS) == HIDSYS) && MAX(G.a_count, G.A_count) > 1);
950}
951#endif
952
923/* Returns NULL-terminated malloced vector of pointers (or NULL) */ 953/* Returns NULL-terminated malloced vector of pointers (or NULL) */
924static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) 954static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p)
925{ 955{
@@ -927,6 +957,9 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p)
927 struct dirent *entry; 957 struct dirent *entry;
928 DIR *dir; 958 DIR *dir;
929 unsigned i, nfiles; 959 unsigned i, nfiles;
960#if ENABLE_PLATFORM_MINGW32
961 struct stat statbuf;
962#endif
930 963
931 *nfiles_p = 0; 964 *nfiles_p = 0;
932 dir = warn_opendir(path); 965 dir = warn_opendir(path);
@@ -949,9 +982,29 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p)
949 continue; /* if only -A, skip . and .. but show other dotfiles */ 982 continue; /* if only -A, skip . and .. but show other dotfiles */
950 } 983 }
951 } 984 }
985#if ENABLE_PLATFORM_MINGW32
986 if (has_dos_drive_prefix(path) && path[2] == '\0')
987 fullname = xasprintf("%s%s", path, entry->d_name);
988 else
989#endif
952 fullname = concat_path_file(path, entry->d_name); 990 fullname = concat_path_file(path, entry->d_name);
991#if ENABLE_PLATFORM_MINGW32
992 /* When showing link targets we must first check the
993 * attributes of the link itself to see if it's hidden. */
994 if ((option_mask32 & OPT_L) && !lstat(fullname, &statbuf)) {
995 if (hide_file(statbuf.st_attr)) {
996 free(fullname);
997 continue;
998 }
999 }
1000#endif
953 cur = my_stat(fullname, bb_basename(fullname), 0); 1001 cur = my_stat(fullname, bb_basename(fullname), 0);
1002#if !ENABLE_PLATFORM_MINGW32
954 if (!cur) { 1003 if (!cur) {
1004#else
1005 if (!cur || hide_file(cur->dn_attr)) {
1006 /* skip invalid or hidden files */
1007#endif
955 free(fullname); 1008 free(fullname);
956 continue; 1009 continue;
957 } 1010 }
@@ -1060,6 +1113,18 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first)
1060 } 1113 }
1061} 1114}
1062 1115
1116#if ENABLE_PLATFORM_MINGW32
1117static char *fix_backslash(char *p)
1118{
1119 const char *flag = getenv("BB_FIX_BACKSLASH");
1120 int value = flag ? atoi(flag) : 0;
1121
1122 if (value == 1)
1123 bs_to_slash(p);
1124 return p;
1125}
1126#endif
1127
1063 1128
1064int ls_main(int argc UNUSED_PARAM, char **argv) 1129int ls_main(int argc UNUSED_PARAM, char **argv)
1065{ /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */ 1130{ /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */
@@ -1129,9 +1194,11 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1129 IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ 1194 IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */
1130 /* -w NUM: */ 1195 /* -w NUM: */
1131 IF_FEATURE_LS_WIDTH(":w+") 1196 IF_FEATURE_LS_WIDTH(":w+")
1197 IF_PLATFORM_MINGW32(":aa:AA")
1132 , ls_longopts 1198 , ls_longopts
1133 IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width) 1199 IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width)
1134 IF_FEATURE_LS_COLOR(, &color_opt) 1200 IF_FEATURE_LS_COLOR(, &color_opt)
1201 IF_PLATFORM_MINGW32(, &G.a_count, &G.A_count)
1135 ); 1202 );
1136#if 0 /* option bits debug */ 1203#if 0 /* option bits debug */
1137 bb_error_msg("opt:0x%08x l:%x H:%x color:%x dirs:%x", opt, OPT_l, OPT_H, OPT_color, OPT_dirs_first); 1204 bb_error_msg("opt:0x%08x l:%x H:%x color:%x dirs:%x", opt, OPT_l, OPT_H, OPT_color, OPT_dirs_first);
@@ -1204,6 +1271,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1204 option_mask32 |= OPT_dirs_first; 1271 option_mask32 |= OPT_dirs_first;
1205 } 1272 }
1206 1273
1274#if ENABLE_FEATURE_EXTRA_FILE_DATA
1275 /* Enable accurate link counts for directories */
1276 if (opt & OPT_l)
1277 count_subdirs(NULL);
1278#endif
1279
1207 argv += optind; 1280 argv += optind;
1208 if (!argv[0]) 1281 if (!argv[0])
1209 *--argv = (char*)"."; 1282 *--argv = (char*)".";
@@ -1215,6 +1288,9 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1215 dn = NULL; 1288 dn = NULL;
1216 nfiles = 0; 1289 nfiles = 0;
1217 do { 1290 do {
1291#if ENABLE_PLATFORM_MINGW32
1292 *argv = fix_backslash(*argv);
1293#endif
1218 cur = my_stat(*argv, *argv, 1294 cur = my_stat(*argv, *argv,
1219 /* follow links on command line unless -l, -i, -s or -F: */ 1295 /* follow links on command line unless -l, -i, -s or -F: */
1220 !(option_mask32 & (OPT_l|OPT_i|OPT_s|OPT_F)) 1296 !(option_mask32 & (OPT_l|OPT_i|OPT_s|OPT_F))
diff --git a/coreutils/nproc.c b/coreutils/nproc.c
index f1d11fa5a..5259921f1 100644
--- a/coreutils/nproc.c
+++ b/coreutils/nproc.c
@@ -29,7 +29,11 @@
29int nproc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 29int nproc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
30int nproc_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 30int nproc_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
31{ 31{
32#if !ENABLE_PLATFORM_MINGW32
32 unsigned long mask[1024]; 33 unsigned long mask[1024];
34#else
35 DWORD_PTR affinity, process_affinity, system_affinity;
36#endif
33 int count = 0; 37 int count = 0;
34#if ENABLE_LONG_OPTS 38#if ENABLE_LONG_OPTS
35 int ignore = 0; 39 int ignore = 0;
@@ -38,7 +42,10 @@ int nproc_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
38 "all\0" No_argument "\xff" 42 "all\0" No_argument "\xff"
39 , &ignore 43 , &ignore
40 ); 44 );
45#endif
41 46
47#if !ENABLE_PLATFORM_MINGW32
48#if ENABLE_LONG_OPTS
42 if (opts & (1 << 1)) { 49 if (opts & (1 << 1)) {
43 DIR *cpusd = opendir("/sys/devices/system/cpu"); 50 DIR *cpusd = opendir("/sys/devices/system/cpu");
44 if (cpusd) { 51 if (cpusd) {
@@ -63,6 +70,17 @@ int nproc_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
63 } 70 }
64 } 71 }
65 } 72 }
73#else /* ENABLE_PLATFORM_MINGW32 */
74 if (GetProcessAffinityMask(GetCurrentProcess(), &process_affinity,
75 &system_affinity)) {
76 affinity = (ENABLE_LONG_OPTS && opts & (1 << 1)) ?
77 system_affinity : process_affinity;
78 while (affinity) {
79 count += affinity & 1;
80 affinity >>= 1;
81 }
82 }
83#endif /* ENABLE_PLATFORM_MINGW32 */
66 84
67 IF_LONG_OPTS(count -= ignore;) 85 IF_LONG_OPTS(count -= ignore;)
68 if (count <= 0) 86 if (count <= 0)
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index e886a4ed2..641d93503 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -110,6 +110,13 @@ typedef long long llong;
110# define LDBL_DIG DBL_DIG 110# define LDBL_DIG DBL_DIG
111#endif 111#endif
112 112
113#if ENABLE_PLATFORM_MINGW32
114/* symbol conflict */
115#define CHAR SIZE_CHAR
116#define SHORT SIZE_SHORT
117#define LONG SIZE_LONG
118#define INT SIZE_INT
119#endif
113enum size_spec { 120enum size_spec {
114 NO_SIZE, 121 NO_SIZE,
115 CHAR, 122 CHAR,
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 7763d7c46..1bcc74d3b 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -152,6 +152,71 @@ static double my_xstrtod(const char *arg)
152 return result; 152 return result;
153} 153}
154 154
155#if ENABLE_PLATFORM_MINGW32
156static int buflen = 0;
157static int bufmax = 0;
158static char *buffer = NULL;
159
160static void my_flush(void)
161{
162 if (buffer)
163 full_write(STDOUT_FILENO, buffer, buflen);
164 free(buffer);
165 buffer = NULL;
166 buflen = bufmax = 0;
167}
168
169static void copy_to_buffer(const char *str, int len)
170{
171 char *newbuf;
172
173 if (buflen + len >= bufmax) {
174 bufmax += 256 + len;
175 if ((newbuf = realloc(buffer, bufmax)) == NULL) {
176 my_flush();
177 return;
178 }
179 buffer = newbuf;
180 }
181 memcpy(buffer + buflen, str, len);
182 buflen += len;
183
184 if (buflen > 40 && buffer[buflen-1] == '\n')
185 my_flush();
186}
187
188static int my_putchar(int ch)
189{
190 char str[1] = { (char)ch };
191 copy_to_buffer(str, 1);
192 return ch;
193}
194
195static int my_printf(const char *format, ...)
196{
197 va_list list;
198 char *str;
199 int len;
200
201 va_start(list, format);
202 len = vasprintf(&str, format, list);
203 va_end(list);
204
205 if (len >= 0) {
206 copy_to_buffer(str, len);
207 free(str);
208 }
209 return len;
210}
211
212#undef bb_putchar
213#undef putchar
214#undef printf
215#define bb_putchar(c) my_putchar(c)
216#define putchar(c) my_putchar(c)
217#define printf(...) my_printf(__VA_ARGS__)
218#endif
219
155/* Handles %b; return 1 if output is to be short-circuited by \c */ 220/* Handles %b; return 1 if output is to be short-circuited by \c */
156static int print_esc_string(const char *str) 221static int print_esc_string(const char *str)
157{ 222{
@@ -444,6 +509,9 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
444 do { 509 do {
445 argv = argv2; 510 argv = argv2;
446 argv2 = print_formatted(format, argv, &conv_err); 511 argv2 = print_formatted(format, argv, &conv_err);
512#if ENABLE_PLATFORM_MINGW32
513 my_flush();
514#endif
447 } while (argv2 > argv && *argv2); 515 } while (argv2 > argv && *argv2);
448 516
449 /* coreutils compat (bash doesn't do this): 517 /* coreutils compat (bash doesn't do this):
diff --git a/coreutils/shred.c b/coreutils/shred.c
index 7c0be612a..9e53b4820 100644
--- a/coreutils/shred.c
+++ b/coreutils/shred.c
@@ -60,9 +60,9 @@ int shred_main(int argc UNUSED_PARAM, char **argv)
60 opt = getopt32(argv, "^" "fuzn:+vxs:" "\0" "-1"/*min 1 arg*/, &num_iter, &opt_s); 60 opt = getopt32(argv, "^" "fuzn:+vxs:" "\0" "-1"/*min 1 arg*/, &num_iter, &opt_s);
61 argv += optind; 61 argv += optind;
62 62
63 zero_fd = xopen("/dev/zero", O_RDONLY); 63 zero_fd = MINGW_SPECIAL(xopen)("/dev/zero", O_RDONLY);
64 if (num_iter != 0) 64 if (num_iter != 0)
65 rand_fd = xopen("/dev/urandom", O_RDONLY); 65 rand_fd = MINGW_SPECIAL(xopen)("/dev/urandom", O_RDONLY);
66 66
67 for (;;) { 67 for (;;) {
68 struct stat sb; 68 struct stat sb;
@@ -102,8 +102,14 @@ int shred_main(int argc UNUSED_PARAM, char **argv)
102 } 102 }
103 if (opt & OPT_u) { 103 if (opt & OPT_u) {
104 ftruncate(fd, 0); 104 ftruncate(fd, 0);
105#if ENABLE_PLATFORM_MINGW32
106 xclose(fd);
107#endif
105 xunlink(fname); 108 xunlink(fname);
106 } 109 }
110#if ENABLE_PLATFORM_MINGW32
111 else
112#endif
107 xclose(fd); 113 xclose(fd);
108 } 114 }
109 115
diff --git a/coreutils/shuf.c b/coreutils/shuf.c
index 0d23382a2..bd3f6840c 100644
--- a/coreutils/shuf.c
+++ b/coreutils/shuf.c
@@ -212,7 +212,7 @@ int shuf_main(int argc, char **argv)
212 printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol); 212 printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol);
213 else 213 else
214#endif 214#endif
215 printf("%llu%c", lo + (uintptr_t)lines[i], eol); 215 printf("%"LL_FMT"u%c", lo + (uintptr_t)lines[i], eol);
216 } else 216 } else
217 printf("%s%c", lines[i], eol); 217 printf("%s%c", lines[i], eol);
218 } 218 }
diff --git a/coreutils/split.c b/coreutils/split.c
index b6d1b9a7b..8d0e485d4 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -78,8 +78,10 @@ static char *next_file(char *old, unsigned suffix_len)
78 return old; 78 return old;
79} 79}
80 80
81#if !ENABLE_PLATFORM_MINGW32
81#define read_buffer bb_common_bufsiz1 82#define read_buffer bb_common_bufsiz1
82enum { READ_BUFFER_SIZE = COMMON_BUFSIZE - 1 }; 83enum { READ_BUFFER_SIZE = COMMON_BUFSIZE - 1 };
84#endif
83 85
84#define SPLIT_OPT_l (1<<0) 86#define SPLIT_OPT_l (1<<0)
85#define SPLIT_OPT_b (1<<1) 87#define SPLIT_OPT_b (1<<1)
@@ -97,8 +99,12 @@ int split_main(int argc UNUSED_PARAM, char **argv)
97 unsigned opt; 99 unsigned opt;
98 ssize_t bytes_read, to_write; 100 ssize_t bytes_read, to_write;
99 char *src; 101 char *src;
100 102#if ENABLE_PLATFORM_MINGW32
103 size_t READ_BUFFER_SIZE = 16*1024;
104 char *read_buffer = xmalloc(16*1024);
105#else
101 setup_common_bufsiz(); 106 setup_common_bufsiz();
107#endif
102 108
103 opt = getopt32(argv, "^" 109 opt = getopt32(argv, "^"
104 "l:b:a:+" /* -a N */ 110 "l:b:a:+" /* -a N */
diff --git a/coreutils/stat.c b/coreutils/stat.c
index 2c2909e7e..dc20c2356 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -190,6 +190,7 @@ FS_TYPE(0x012FF7B4, "xenix") \
190FS_TYPE(0x012FF7B5, "sysv4") \ 190FS_TYPE(0x012FF7B5, "sysv4") \
191FS_TYPE(0x012FF7B6, "sysv2") \ 191FS_TYPE(0x012FF7B6, "sysv2") \
192FS_TYPE(0x012FF7B7, "coh") \ 192FS_TYPE(0x012FF7B7, "coh") \
193IF_PLATFORM_MINGW32(FS_TYPE(0x15013346, "udf")) \
193FS_TYPE(0x00011954, "ufs") \ 194FS_TYPE(0x00011954, "ufs") \
194FS_TYPE(0x012FD16D, "xia") \ 195FS_TYPE(0x012FD16D, "xia") \
195FS_TYPE(0x5346544e, "ntfs") \ 196FS_TYPE(0x5346544e, "ntfs") \
@@ -784,6 +785,10 @@ int stat_main(int argc UNUSED_PARAM, char **argv)
784 selinux_or_die(); 785 selinux_or_die();
785 } 786 }
786#endif 787#endif
788#if ENABLE_FEATURE_EXTRA_FILE_DATA
789 /* Enable accurate link counts for directories */
790 count_subdirs(NULL);
791#endif
787 ok = 1; 792 ok = 1;
788 argv += optind; 793 argv += optind;
789 for (i = 0; argv[i]; ++i) 794 for (i = 0; argv[i]; ++i)
diff --git a/coreutils/sum.c b/coreutils/sum.c
index 78e69acc6..7c7cc6b6b 100644
--- a/coreutils/sum.c
+++ b/coreutils/sum.c
@@ -82,9 +82,9 @@ static unsigned sum_file(const char *file, unsigned type)
82 if (type >= SUM_SYSV) { 82 if (type >= SUM_SYSV) {
83 r = (s & 0xffff) + ((s & 0xffffffff) >> 16); 83 r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
84 s = (r & 0xffff) + (r >> 16); 84 s = (r & 0xffff) + (r >> 16);
85 printf("%u %llu %s\n", s, (total_bytes + 511) / 512, file); 85 printf("%u %"LL_FMT"u %s\n", s, (total_bytes + 511) / 512, file);
86 } else 86 } else
87 printf("%05u %5llu %s\n", s, (total_bytes + 1023) / 1024, file); 87 printf("%05u %5"LL_FMT"u %s\n", s, (total_bytes + 1023) / 1024, file);
88 return 1; 88 return 1;
89#undef buf 89#undef buf
90} 90}
diff --git a/coreutils/timeout.c b/coreutils/timeout.c
index 18aa9ebeb..0d6a2c612 100644
--- a/coreutils/timeout.c
+++ b/coreutils/timeout.c
@@ -42,11 +42,39 @@
42//usage: "[-s SIG] [-k KILL_SECS] SECS PROG ARGS" 42//usage: "[-s SIG] [-k KILL_SECS] SECS PROG ARGS"
43//usage:#define timeout_full_usage "\n\n" 43//usage:#define timeout_full_usage "\n\n"
44//usage: "Run PROG. Send SIG to it if it is not gone in SECS seconds.\n" 44//usage: "Run PROG. Send SIG to it if it is not gone in SECS seconds.\n"
45//usage: "Default SIG: TERM." 45//usage: IF_NOT_PLATFORM_MINGW32("Default SIG: TERM.")
46//usage: IF_PLATFORM_MINGW32("Default SIG: TERM.\n")
46//usage: "If it still exists in KILL_SECS seconds, send KILL.\n" 47//usage: "If it still exists in KILL_SECS seconds, send KILL.\n"
47 48
48#include "libbb.h" 49#include "libbb.h"
49 50
51#if ENABLE_PLATFORM_MINGW32
52static HANDLE child = INVALID_HANDLE_VALUE;
53
54static void kill_child(void)
55{
56 if (child != INVALID_HANDLE_VALUE) {
57 kill_signal_by_handle(child, SIGTERM);
58 }
59}
60
61/* Return TRUE if child exits before timeout expires */
62static NOINLINE int timeout_wait(int timeout, HANDLE proc, DWORD *status)
63{
64 /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */
65 while (1) {
66 sleep1();
67 if (--timeout <= 0)
68 break;
69 if (WaitForSingleObject(proc, 0) == WAIT_OBJECT_0) {
70 /* process is gone */
71 GetExitCodeProcess(proc, status);
72 return TRUE;
73 }
74 }
75 return FALSE;
76}
77#else
50static NOINLINE int timeout_wait(int timeout, pid_t pid) 78static NOINLINE int timeout_wait(int timeout, pid_t pid)
51{ 79{
52 /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */ 80 /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */
@@ -61,13 +89,19 @@ static NOINLINE int timeout_wait(int timeout, pid_t pid)
61 } 89 }
62 return EXIT_FAILURE; 90 return EXIT_FAILURE;
63} 91}
92#endif
64 93
65int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 94int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
66int timeout_main(int argc UNUSED_PARAM, char **argv) 95int timeout_main(int argc UNUSED_PARAM, char **argv)
67{ 96{
68 int signo; 97 int signo;
98#if !ENABLE_PLATFORM_MINGW32
69 int status; 99 int status;
70 int parent = 0; 100 int parent = 0;
101#else
102 intptr_t ret;
103 DWORD status = EXIT_SUCCESS;
104#endif
71 int timeout; 105 int timeout;
72 int kill_timeout; 106 int kill_timeout;
73 pid_t pid; 107 pid_t pid;
@@ -77,15 +111,27 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
77 const char *opt_s = "TERM"; 111 const char *opt_s = "TERM";
78 char *opt_k = NULL; 112 char *opt_k = NULL;
79 113
114#if ENABLE_PLATFORM_MINGW32
115 xfunc_error_retval = 125;
116#endif
117
80 /* -p option is not documented, it is needed to support NOMMU. */ 118 /* -p option is not documented, it is needed to support NOMMU. */
81 119
82 /* -t SECONDS; -p PARENT_PID */ 120 /* -t SECONDS; -p PARENT_PID */
83 /* '+': stop at first non-option */ 121 /* '+': stop at first non-option */
122#if !ENABLE_PLATFORM_MINGW32
84 getopt32(argv, "+s:k:" USE_FOR_NOMMU("p:+"), &opt_s, &opt_k, &parent); 123 getopt32(argv, "+s:k:" USE_FOR_NOMMU("p:+"), &opt_s, &opt_k, &parent);
124#else
125 getopt32(argv, "+s:k:", &opt_s, &opt_k);
126#endif
85 /*argv += optind; - no, wait for bb_daemonize_or_rexec! */ 127 /*argv += optind; - no, wait for bb_daemonize_or_rexec! */
86 128
87 signo = get_signum(opt_s); 129 signo = get_signum(opt_s);
130#if !ENABLE_PLATFORM_MINGW32
88 if (signo < 0) 131 if (signo < 0)
132#else
133 if (!is_valid_signal(signo))
134#endif
89 bb_error_msg_and_die("unknown signal '%s'", opt_s); 135 bb_error_msg_and_die("unknown signal '%s'", opt_s);
90 136
91 kill_timeout = 0; 137 kill_timeout = 0;
@@ -98,6 +144,7 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
98 if (!argv[optind]) /* no PROG? */ 144 if (!argv[optind]) /* no PROG? */
99 bb_show_usage(); 145 bb_show_usage();
100 146
147#if !ENABLE_PLATFORM_MINGW32
101 /* We want to create a grandchild which will watch 148 /* We want to create a grandchild which will watch
102 * and kill the grandparent. Other methods: 149 * and kill the grandparent. Other methods:
103 * making parent watch child disrupts parent<->child link 150 * making parent watch child disrupts parent<->child link
@@ -150,4 +197,31 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
150 argv[1] = sv2; 197 argv[1] = sv2;
151#endif 198#endif
152 BB_EXECVP_or_die(argv); 199 BB_EXECVP_or_die(argv);
200#else /* ENABLE_PLATFORM_MINGW32 */
201 argv += optind;
202 if ((ret=mingw_spawn_proc((const char **)argv)) == -1) {
203 xfunc_error_retval = errno == EACCES ? 126 : 127;
204 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
205 }
206
207 child = (HANDLE)ret;
208 atexit(kill_child);
209 if (timeout_wait(timeout, child, &status))
210 goto finish;
211 status = signo == SIGKILL ? 137 : 124;
212
213 pid = (pid_t)GetProcessId(child);
214 kill(pid, signo);
215
216 if (kill_timeout > 0) {
217 if (timeout_wait(kill_timeout, child, &status))
218 goto finish;
219 kill(pid, SIGKILL);
220 status = 137;
221 }
222 finish:
223 CloseHandle(child);
224 child = INVALID_HANDLE_VALUE;
225 return status;
226#endif
153} 227}
diff --git a/coreutils/yes.c b/coreutils/yes.c
index e04ad3ac0..493462201 100644
--- a/coreutils/yes.c
+++ b/coreutils/yes.c
@@ -31,6 +31,11 @@
31 31
32#include "libbb.h" 32#include "libbb.h"
33 33
34#if ENABLE_PLATFORM_MINGW32
35# undef putchar
36# define putchar(c) winansi_fputc(c, stdout)
37#endif
38
34int yes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 39int yes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
35int yes_main(int argc UNUSED_PARAM, char **argv) 40int yes_main(int argc UNUSED_PARAM, char **argv)
36{ 41{