aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/date.c25
-rw-r--r--coreutils/dd.c38
-rw-r--r--coreutils/du.c2
-rw-r--r--coreutils/expr.c2
-rw-r--r--coreutils/factor.c4
-rw-r--r--coreutils/ls.c42
-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.c1
-rw-r--r--coreutils/sum.c4
-rw-r--r--coreutils/timeout.c71
-rw-r--r--coreutils/yes.c4
16 files changed, 290 insertions, 16 deletions
diff --git a/coreutils/date.c b/coreutils/date.c
index abcc37c33..4e62a6fb0 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 06c1b7b9c..a3c9ababf 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -94,6 +94,9 @@
94//usage: "\n status=none Suppress all output" 94//usage: "\n status=none Suppress all output"
95//usage: ) 95//usage: )
96//usage: "\n" 96//usage: "\n"
97//usage: IF_PLATFORM_MINGW32(
98//usage: "\nif=/dev/zero and if=/dev/urandom are supported"
99//usage: )
97//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G" 100//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G"
98//usage: 101//usage:
99//usage:#define dd_example_usage 102//usage:#define dd_example_usage
@@ -301,9 +304,11 @@ static int parse_comma_flags(char *val, const char *words, const char *error_in)
301 304
302static void *alloc_buf(size_t size) 305static void *alloc_buf(size_t size)
303{ 306{
307#if !ENABLE_PLATFORM_MINGW32
304 /* Important for "{i,o}flag=direct" - buffers must be page aligned */ 308 /* Important for "{i,o}flag=direct" - buffers must be page aligned */
305 if (size >= bb_getpagesize()) 309 if (size >= bb_getpagesize())
306 return xmmap_anon(size); 310 return xmmap_anon(size);
311#endif
307 return xmalloc(size); 312 return xmalloc(size);
308} 313}
309 314
@@ -423,11 +428,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
423#if ENABLE_FEATURE_DD_IBS_OBS 428#if ENABLE_FEATURE_DD_IBS_OBS
424 if (what == OP_ibs) { 429 if (what == OP_ibs) {
425 /* Must fit into positive ssize_t */ 430 /* Must fit into positive ssize_t */
426 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 431 ibs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
427 /*continue;*/ 432 /*continue;*/
428 } 433 }
429 if (what == OP_obs) { 434 if (what == OP_obs) {
430 obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 435 obs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
431 /*continue;*/ 436 /*continue;*/
432 } 437 }
433 if (what == OP_conv) { 438 if (what == OP_conv) {
@@ -444,7 +449,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
444 } 449 }
445#endif 450#endif
446 if (what == OP_bs) { 451 if (what == OP_bs) {
447 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 452 ibs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
448 obs = ibs; 453 obs = ibs;
449 /*continue;*/ 454 /*continue;*/
450 } 455 }
@@ -504,7 +509,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
504 if (G.flags & FLAG_IDIRECT) 509 if (G.flags & FLAG_IDIRECT)
505 iflag |= O_DIRECT; 510 iflag |= O_DIRECT;
506#endif 511#endif
507 xmove_fd(xopen(infile, iflag), ifd); 512 xmove_fd(MINGW_SPECIAL(xopen)(infile, iflag), ifd);
513#if ENABLE_PLATFORM_MINGW32
514 update_special_fd(get_dev_type(infile), ifd);
515#endif
508 } else { 516 } else {
509 infile = bb_msg_standard_input; 517 infile = bb_msg_standard_input;
510 } 518 }
@@ -521,6 +529,27 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
521#endif 529#endif
522 xmove_fd(xopen(outfile, oflag), ofd); 530 xmove_fd(xopen(outfile, oflag), ofd);
523 531
532#if ENABLE_PLATFORM_MINGW32
533 {
534 off_t len = (off_t)seek * ((G.flags & FLAG_SEEK_BYTES) ? 1 : obs);
535 struct stat st;
536 int ret = fstat(ofd, &st);
537
538 if (ret == 0 && !(G.flags & FLAG_APPEND) && len > st.st_size)
539 make_sparse(ofd, st.st_size, len);
540
541 if (seek && !(G.flags & FLAG_NOTRUNC)) {
542 if (ftruncate(ofd, len) < 0) {
543 if (ret < 0
544 || S_ISREG(st.st_mode)
545 || S_ISDIR(st.st_mode)
546 ) {
547 goto die_outfile;
548 }
549 }
550 }
551 }
552#else
524 if (seek && !(G.flags & FLAG_NOTRUNC)) { 553 if (seek && !(G.flags & FLAG_NOTRUNC)) {
525 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs; 554 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs;
526 if (ftruncate(ofd, seek * blocksz) < 0) { 555 if (ftruncate(ofd, seek * blocksz) < 0) {
@@ -534,6 +563,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
534 } 563 }
535 } 564 }
536 } 565 }
566#endif
537 } else { 567 } else {
538 outfile = bb_msg_standard_output; 568 outfile = bb_msg_standard_output;
539 } 569 }
diff --git a/coreutils/du.c b/coreutils/du.c
index 832dd7594..092647468 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 760b081f9..b896acd44 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 de8ea4e11..a7a5a5030 100644
--- a/coreutils/factor.c
+++ b/coreutils/factor.c
@@ -125,7 +125,7 @@ static NOINLINE void print_w(wide_t n)
125{ 125{
126 unsigned rep = square_count; 126 unsigned rep = square_count;
127 do 127 do
128 printf(" %llu", n); 128 printf(" %"LL_FMT"u", n);
129 while (--rep != 0); 129 while (--rep != 0);
130} 130}
131static NOINLINE void print_h(half_t n) 131static NOINLINE void print_h(half_t n)
@@ -227,7 +227,7 @@ static void factorize_numstr(const char *numstr)
227 N = bb_strtoull(numstr, NULL, 10); 227 N = bb_strtoull(numstr, NULL, 10);
228 if (errno) 228 if (errno)
229 bb_show_usage(); 229 bb_show_usage();
230 printf("%llu:", N); 230 printf("%"LL_FMT"u:", N);
231 square_count = 1; 231 square_count = 1;
232 factorize(N); 232 factorize(N);
233} 233}
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 48f5eb482..58b8fde75 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -316,6 +316,9 @@ struct dnode {
316 int dn_rdev_min; 316 int dn_rdev_min;
317// dev_t dn_dev; 317// dev_t dn_dev;
318// blksize_t dn_blksize; 318// blksize_t dn_blksize;
319#if ENABLE_PLATFORM_MINGW32
320 DWORD dn_attr;
321#endif
319}; 322};
320 323
321struct globals { 324struct globals {
@@ -497,7 +500,11 @@ static NOINLINE unsigned display_single(const struct dnode *dn)
497 lpath = xmalloc_readlink_or_warn(dn->fullname); 500 lpath = xmalloc_readlink_or_warn(dn->fullname);
498 501
499 if (opt & OPT_i) /* show inode# */ 502 if (opt & OPT_i) /* show inode# */
500 column += printf("%7llu ", (long long) dn->dn_ino); 503#if !ENABLE_FEATURE_EXTRA_FILE_DATA
504 column += printf("%7"LL_FMT"u ", (long long) dn->dn_ino);
505#else
506 column += printf("%19"LL_FMT"u ", (long long) dn->dn_ino);
507#endif
501//TODO: -h should affect -s too: 508//TODO: -h should affect -s too:
502 if (opt & OPT_s) /* show allocated blocks */ 509 if (opt & OPT_s) /* show allocated blocks */
503 column += printf("%6"OFF_FMT"u ", (off_t) (dn->dn_blocks >> 1)); 510 column += printf("%6"OFF_FMT"u ", (off_t) (dn->dn_blocks >> 1));
@@ -652,7 +659,11 @@ static void display_files(struct dnode **dn, unsigned nfiles)
652 } 659 }
653 column_width += 2 660 column_width += 2
654 + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */ 661 + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */
662#if !ENABLE_FEATURE_EXTRA_FILE_DATA
655 + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */ 663 + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */
664#else
665 + ((option_mask32 & OPT_i) ? 20 : 0) /* inode# width */
666#endif
656 + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */ 667 + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */
657 ; 668 ;
658 ncols = (unsigned)G_terminal_width / column_width; 669 ncols = (unsigned)G_terminal_width / column_width;
@@ -733,6 +744,9 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f
733 744
734 /* cur->dstat = statbuf: */ 745 /* cur->dstat = statbuf: */
735 cur->dn_mode = statbuf.st_mode ; 746 cur->dn_mode = statbuf.st_mode ;
747#if ENABLE_PLATFORM_MINGW32
748 cur->dn_attr = statbuf.st_attr ;
749#endif
736 cur->dn_size = statbuf.st_size ; 750 cur->dn_size = statbuf.st_size ;
737#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES 751#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
738 cur->dn_time = statbuf.st_mtime ; 752 cur->dn_time = statbuf.st_mtime ;
@@ -942,9 +956,20 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p)
942 continue; /* if only -A, skip . and .. but show other dotfiles */ 956 continue; /* if only -A, skip . and .. but show other dotfiles */
943 } 957 }
944 } 958 }
959#if ENABLE_PLATFORM_MINGW32
960 if (has_dos_drive_prefix(path) && path[2] == '\0')
961 fullname = xasprintf("%s%s", path, entry->d_name);
962 else
963#endif
945 fullname = concat_path_file(path, entry->d_name); 964 fullname = concat_path_file(path, entry->d_name);
946 cur = my_stat(fullname, bb_basename(fullname), 0); 965 cur = my_stat(fullname, bb_basename(fullname), 0);
966#if !ENABLE_PLATFORM_MINGW32
947 if (!cur) { 967 if (!cur) {
968#else
969 if (!cur || ((cur->dn_attr & FILE_ATTRIBUTE_HIDDEN) &&
970 !(option_mask32 & (OPT_a|OPT_A)))) {
971 /* skip invalid or hidden files */
972#endif
948 free(fullname); 973 free(fullname);
949 continue; 974 continue;
950 } 975 }
@@ -1053,6 +1078,18 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first)
1053 } 1078 }
1054} 1079}
1055 1080
1081#if ENABLE_PLATFORM_MINGW32
1082static char *fix_backslash(char *p)
1083{
1084 const char *flag = getenv("BB_FIX_BACKSLASH");
1085 int value = flag ? atoi(flag) : 0;
1086
1087 if (value == 1)
1088 bs_to_slash(p);
1089 return p;
1090}
1091#endif
1092
1056 1093
1057int ls_main(int argc UNUSED_PARAM, char **argv) 1094int ls_main(int argc UNUSED_PARAM, char **argv)
1058{ /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */ 1095{ /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */
@@ -1208,6 +1245,9 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1208 dn = NULL; 1245 dn = NULL;
1209 nfiles = 0; 1246 nfiles = 0;
1210 do { 1247 do {
1248#if ENABLE_PLATFORM_MINGW32
1249 *argv = fix_backslash(*argv);
1250#endif
1211 cur = my_stat(*argv, *argv, 1251 cur = my_stat(*argv, *argv,
1212 /* follow links on command line unless -l, -i, -s or -F: */ 1252 /* follow links on command line unless -l, -i, -s or -F: */
1213 !(option_mask32 & (OPT_l|OPT_i|OPT_s|OPT_F)) 1253 !(option_mask32 & (OPT_l|OPT_i|OPT_s|OPT_F))
diff --git a/coreutils/nproc.c b/coreutils/nproc.c
index bb9bc56c5..fb673a210 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 5b5e56a21..1830aca83 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -101,6 +101,13 @@ typedef long long llong;
101# define LDBL_DIG DBL_DIG 101# define LDBL_DIG DBL_DIG
102#endif 102#endif
103 103
104#if ENABLE_PLATFORM_MINGW32
105/* symbol conflict */
106#define CHAR SIZE_CHAR
107#define SHORT SIZE_SHORT
108#define LONG SIZE_LONG
109#define INT SIZE_INT
110#endif
104enum size_spec { 111enum size_spec {
105 NO_SIZE, 112 NO_SIZE,
106 CHAR, 113 CHAR,
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 2e672d15f..da129f909 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 04bf87229..794d7b815 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 3def3d80f..81b0df453 100644
--- a/coreutils/shuf.c
+++ b/coreutils/shuf.c
@@ -166,7 +166,7 @@ int shuf_main(int argc, char **argv)
166 166
167 for (i = numlines - outlines; i < numlines; i++) { 167 for (i = numlines - outlines; i < numlines; i++) {
168 if (opts & OPT_i) 168 if (opts & OPT_i)
169 printf("%llu%c", lo + (uintptr_t)lines[i], eol); 169 printf("%"LL_FMT"u%c", lo + (uintptr_t)lines[i], eol);
170 else 170 else
171 printf("%s%c", lines[i], eol); 171 printf("%s%c", lines[i], eol);
172 } 172 }
diff --git a/coreutils/split.c b/coreutils/split.c
index 3fcfd95f2..9393423a1 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..940ade89a 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") \
diff --git a/coreutils/sum.c b/coreutils/sum.c
index 16ec44540..a15d1932d 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 06108f315..74df31d10 100644
--- a/coreutils/timeout.c
+++ b/coreutils/timeout.c
@@ -42,11 +42,38 @@
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: "Default SIG: TERM.\n"
46//usage: "If it still exists in KILL_SECS seconds, send KILL.\n" 46//usage: "If it still exists in KILL_SECS seconds, send KILL.\n"
47 47
48#include "libbb.h" 48#include "libbb.h"
49 49
50#if ENABLE_PLATFORM_MINGW32
51static HANDLE child = INVALID_HANDLE_VALUE;
52
53static void kill_child(void)
54{
55 if (child != INVALID_HANDLE_VALUE) {
56 kill_SIGTERM_by_handle(child);
57 }
58}
59
60/* Return TRUE if child exits before timeout expires */
61static NOINLINE int timeout_wait(int timeout, HANDLE proc, DWORD *status)
62{
63 /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */
64 while (1) {
65 sleep1();
66 if (--timeout <= 0)
67 break;
68 if (WaitForSingleObject(proc, 0) == WAIT_OBJECT_0) {
69 /* process is gone */
70 GetExitCodeProcess(proc, status);
71 return TRUE;
72 }
73 }
74 return FALSE;
75}
76#else
50static NOINLINE int timeout_wait(int timeout, pid_t pid) 77static NOINLINE int timeout_wait(int timeout, pid_t pid)
51{ 78{
52 /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */ 79 /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */
@@ -61,12 +88,18 @@ static NOINLINE int timeout_wait(int timeout, pid_t pid)
61 } 88 }
62 return EXIT_FAILURE; 89 return EXIT_FAILURE;
63} 90}
91#endif
64 92
65int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 93int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
66int timeout_main(int argc UNUSED_PARAM, char **argv) 94int timeout_main(int argc UNUSED_PARAM, char **argv)
67{ 95{
68 int signo; 96 int signo;
97#if !ENABLE_PLATFORM_MINGW32
69 int status; 98 int status;
99#else
100 intptr_t ret;
101 DWORD status = EXIT_SUCCESS;
102#endif
70 int parent = 0; 103 int parent = 0;
71 int timeout; 104 int timeout;
72 int kill_timeout; 105 int kill_timeout;
@@ -77,6 +110,10 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
77 const char *opt_s = "TERM"; 110 const char *opt_s = "TERM";
78 char *opt_k = NULL; 111 char *opt_k = NULL;
79 112
113#if ENABLE_PLATFORM_MINGW32
114 xfunc_error_retval = 125;
115#endif
116
80 /* -p option is not documented, it is needed to support NOMMU. */ 117 /* -p option is not documented, it is needed to support NOMMU. */
81 118
82 /* -t SECONDS; -p PARENT_PID */ 119 /* -t SECONDS; -p PARENT_PID */
@@ -85,7 +122,11 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
85 /*argv += optind; - no, wait for bb_daemonize_or_rexec! */ 122 /*argv += optind; - no, wait for bb_daemonize_or_rexec! */
86 123
87 signo = get_signum(opt_s); 124 signo = get_signum(opt_s);
125#if !ENABLE_PLATFORM_MINGW32
88 if (signo < 0) 126 if (signo < 0)
127#else
128 if (signo != SIGTERM && signo != SIGKILL && signo != 0)
129#endif
89 bb_error_msg_and_die("unknown signal '%s'", opt_s); 130 bb_error_msg_and_die("unknown signal '%s'", opt_s);
90 131
91 kill_timeout = 0; 132 kill_timeout = 0;
@@ -98,6 +139,7 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
98 if (!argv[optind]) /* no PROG? */ 139 if (!argv[optind]) /* no PROG? */
99 bb_show_usage(); 140 bb_show_usage();
100 141
142#if !ENABLE_PLATFORM_MINGW32
101 /* We want to create a grandchild which will watch 143 /* We want to create a grandchild which will watch
102 * and kill the grandparent. Other methods: 144 * and kill the grandparent. Other methods:
103 * making parent watch child disrupts parent<->child link 145 * making parent watch child disrupts parent<->child link
@@ -150,4 +192,31 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
150 argv[1] = sv2; 192 argv[1] = sv2;
151#endif 193#endif
152 BB_EXECVP_or_die(argv); 194 BB_EXECVP_or_die(argv);
195#else /* ENABLE_PLATFORM_MINGW32 */
196 argv += optind;
197 if ((ret=mingw_spawn_proc((const char **)argv)) == -1) {
198 xfunc_error_retval = errno == EACCES ? 126 : 127;
199 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
200 }
201
202 child = (HANDLE)ret;
203 atexit(kill_child);
204 if (timeout_wait(timeout, child, &status))
205 goto finish;
206 status = signo == SIGKILL ? 137 : 124;
207
208 pid = (pid_t)GetProcessId(child);
209 kill(pid, signo);
210
211 if (kill_timeout > 0) {
212 if (timeout_wait(kill_timeout, child, &status))
213 goto finish;
214 kill(parent, SIGKILL);
215 status = 137;
216 }
217 finish:
218 CloseHandle(child);
219 child = INVALID_HANDLE_VALUE;
220 return status;
221#endif
153} 222}
diff --git a/coreutils/yes.c b/coreutils/yes.c
index 161db82c0..64dfa500c 100644
--- a/coreutils/yes.c
+++ b/coreutils/yes.c
@@ -41,6 +41,10 @@ int yes_main(int argc UNUSED_PARAM, char **argv)
41 ++argv; 41 ++argv;
42 42
43 do { 43 do {
44#if ENABLE_PLATFORM_MINGW32
45 if (ferror(stdout) != 0)
46 break;
47#endif
44 pp = argv; 48 pp = argv;
45 while (1) { 49 while (1) {
46 fputs_stdout(*pp); 50 fputs_stdout(*pp);