summaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libbb/Kbuild.src20
-rw-r--r--libbb/appletlib.c44
-rw-r--r--libbb/copy_file.c3
-rw-r--r--libbb/executable.c16
-rw-r--r--libbb/find_mount_point.c37
-rw-r--r--libbb/find_pid_by_name.c4
-rw-r--r--libbb/get_last_path_component.c5
-rw-r--r--libbb/get_line_from_file.c4
-rw-r--r--libbb/getopt32.c2
-rw-r--r--libbb/inode_hash.c2
-rw-r--r--libbb/lineedit.c65
-rw-r--r--libbb/make_directory.c25
-rw-r--r--libbb/messages.c2
-rw-r--r--libbb/printable_string.c2
-rw-r--r--libbb/procps.c3
-rw-r--r--libbb/read_printf.c5
-rw-r--r--libbb/setup_environment.c11
-rw-r--r--libbb/vfork_daemon_rexec.c5
-rw-r--r--libbb/xreadlink.c2
19 files changed, 241 insertions, 16 deletions
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 7fb687227..d94b65008 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -37,25 +37,19 @@ lib-y += fgets_str.o
37lib-y += find_pid_by_name.o 37lib-y += find_pid_by_name.o
38lib-y += find_root_device.o 38lib-y += find_root_device.o
39lib-y += full_write.o 39lib-y += full_write.o
40lib-y += get_console.o
41lib-y += get_last_path_component.o 40lib-y += get_last_path_component.o
42lib-y += get_line_from_file.o 41lib-y += get_line_from_file.o
43lib-y += getopt32.o 42lib-y += getopt32.o
44lib-y += getpty.o
45lib-y += get_volsize.o 43lib-y += get_volsize.o
46lib-y += herror_msg.o 44lib-y += herror_msg.o
47lib-y += human_readable.o 45lib-y += human_readable.o
48lib-y += inet_common.o
49lib-y += info_msg.o 46lib-y += info_msg.o
50lib-y += inode_hash.o 47lib-y += inode_hash.o
51lib-y += isdirectory.o 48lib-y += isdirectory.o
52lib-y += kernel_version.o
53lib-y += last_char_is.o 49lib-y += last_char_is.o
54lib-y += lineedit.o lineedit_ptr_hack.o 50lib-y += lineedit.o lineedit_ptr_hack.o
55lib-y += llist.o 51lib-y += llist.o
56lib-y += login.o
57lib-y += make_directory.o 52lib-y += make_directory.o
58lib-y += makedev.o
59lib-y += hash_md5_sha.o 53lib-y += hash_md5_sha.o
60# Alternative (disabled) MD5 implementation 54# Alternative (disabled) MD5 implementation
61#lib-y += hash_md5prime.o 55#lib-y += hash_md5prime.o
@@ -76,7 +70,6 @@ lib-y += progress.o
76lib-y += ptr_to_globals.o 70lib-y += ptr_to_globals.o
77lib-y += read.o 71lib-y += read.o
78lib-y += read_printf.o 72lib-y += read_printf.o
79lib-y += read_key.o
80lib-y += recursive_action.o 73lib-y += recursive_action.o
81lib-y += remove_file.o 74lib-y += remove_file.o
82lib-y += run_shell.o 75lib-y += run_shell.o
@@ -85,7 +78,6 @@ lib-y += safe_poll.o
85lib-y += safe_strncpy.o 78lib-y += safe_strncpy.o
86lib-y += safe_write.o 79lib-y += safe_write.o
87lib-y += setup_environment.o 80lib-y += setup_environment.o
88lib-y += signals.o
89lib-y += simplify_path.o 81lib-y += simplify_path.o
90lib-y += single_argv.o 82lib-y += single_argv.o
91lib-y += skip_whitespace.o 83lib-y += skip_whitespace.o
@@ -110,10 +102,20 @@ lib-y += xfuncs.o
110lib-y += xfuncs_printf.o 102lib-y += xfuncs_printf.o
111lib-y += xfunc_die.o 103lib-y += xfunc_die.o
112lib-y += xgetcwd.o 104lib-y += xgetcwd.o
113lib-y += xgethostbyname.o
114lib-y += xreadlink.o 105lib-y += xreadlink.o
115lib-y += xrealloc_vector.o 106lib-y += xrealloc_vector.o
116 107
108lib-$(CONFIG_PLATFORM_POSIX) += get_console.o
109lib-$(CONFIG_PLATFORM_POSIX) += getpty.o
110lib-$(CONFIG_PLATFORM_POSIX) += inet_common.o
111lib-$(CONFIG_PLATFORM_POSIX) += kernel_version.o
112lib-$(CONFIG_PLATFORM_POSIX) += login.o
113lib-$(CONFIG_PLATFORM_POSIX) += makedev.o
114lib-$(CONFIG_PLATFORM_POSIX) += read_key.o
115lib-$(CONFIG_PLATFORM_POSIX) += signals.o
116lib-$(CONFIG_PLATFORM_POSIX) += udp_io.o
117lib-$(CONFIG_PLATFORM_POSIX) += xgethostbyname.o
118
117lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o 119lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o
118 120
119lib-$(CONFIG_FEATURE_UTMP) += utmp.o 121lib-$(CONFIG_FEATURE_UTMP) += utmp.o
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 54300bd87..dba66cc93 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -187,6 +187,10 @@ void lbb_prepare(const char *applet
187 if (ENABLE_LOCALE_SUPPORT) 187 if (ENABLE_LOCALE_SUPPORT)
188 setlocale(LC_ALL, ""); 188 setlocale(LC_ALL, "");
189 189
190#if ENABLE_PLATFORM_MINGW32
191 init_winsock();
192#endif
193
190#if ENABLE_FEATURE_INDIVIDUAL 194#if ENABLE_FEATURE_INDIVIDUAL
191 /* Redundant for busybox (run_applet_and_exit covers that case) 195 /* Redundant for busybox (run_applet_and_exit covers that case)
192 * but needed for "individual applet" mode */ 196 * but needed for "individual applet" mode */
@@ -642,10 +646,19 @@ static int busybox_main(char **argv)
642 ) 646 )
643 " or: function [arguments]...\n" 647 " or: function [arguments]...\n"
644 "\n" 648 "\n"
649 IF_NOT_FEATURE_SH_STANDALONE(
645 "\tBusyBox is a multi-call binary that combines many common Unix\n" 650 "\tBusyBox is a multi-call binary that combines many common Unix\n"
646 "\tutilities into a single executable. Most people will create a\n" 651 "\tutilities into a single executable. Most people will create a\n"
647 "\tlink to busybox for each function they wish to use and BusyBox\n" 652 "\tlink to busybox for each function they wish to use and BusyBox\n"
648 "\twill act like whatever it was invoked as.\n" 653 "\twill act like whatever it was invoked as.\n"
654 )
655 IF_FEATURE_SH_STANDALONE(
656 "\tBusyBox is a multi-call binary that combines many common Unix\n"
657 "\tutilities into a single executable. This version has been\n"
658 "\tconfigured to prefer built-in utilities to external binaries.\n"
659 "\tThis avoids having to install a link to busybox for each\n"
660 "\tfunction to be invoked.\n"
661 )
649 "\n" 662 "\n"
650 "Currently defined functions:\n" 663 "Currently defined functions:\n"
651 ); 664 );
@@ -815,6 +828,18 @@ int main(int argc UNUSED_PARAM, char **argv)
815 } 828 }
816#endif 829#endif
817 830
831#if defined(__MINGW64_VERSION_MAJOR)
832 if ( stdin ) {
833 _setmode(fileno(stdin), _O_BINARY);
834 }
835 if ( stdout ) {
836 _setmode(fileno(stdout), _O_BINARY);
837 }
838 if ( stderr ) {
839 _setmode(fileno(stderr), _O_BINARY);
840 }
841#endif
842
818#if defined(SINGLE_APPLET_MAIN) 843#if defined(SINGLE_APPLET_MAIN)
819 /* Only one applet is selected in .config */ 844 /* Only one applet is selected in .config */
820 if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) { 845 if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) {
@@ -830,6 +855,25 @@ int main(int argc UNUSED_PARAM, char **argv)
830 applet_name = argv[0]; 855 applet_name = argv[0];
831 if (applet_name[0] == '-') 856 if (applet_name[0] == '-')
832 applet_name++; 857 applet_name++;
858 if (ENABLE_PLATFORM_MINGW32) {
859 const char *applet_name_env = getenv("BUSYBOX_APPLET_NAME");
860 if (applet_name_env && *applet_name_env) {
861 applet_name = applet_name_env;
862 unsetenv("BUSYBOX_APPLET_NAME");
863 }
864 else {
865 char *s = argv[0];
866 int i, len = strlen(s);
867
868 for ( i=0; i < len; ++i ) {
869 s[i] = tolower(s[i]);
870 }
871 if (len > 4 && !strcmp(s+len-4, ".exe")) {
872 len -= 4;
873 s[len] = '\0';
874 }
875 }
876 }
833 applet_name = bb_basename(applet_name); 877 applet_name = bb_basename(applet_name);
834 878
835 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ 879 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index a4be875d2..a427c441f 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -100,12 +100,15 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
100 return -1; 100 return -1;
101 } 101 }
102 } else { 102 } else {
103#if !ENABLE_PLATFORM_MINGW32
104 /* MinGW does not have inode, and does not use device */
103 if (source_stat.st_dev == dest_stat.st_dev 105 if (source_stat.st_dev == dest_stat.st_dev
104 && source_stat.st_ino == dest_stat.st_ino 106 && source_stat.st_ino == dest_stat.st_ino
105 ) { 107 ) {
106 bb_error_msg("'%s' and '%s' are the same file", source, dest); 108 bb_error_msg("'%s' and '%s' are the same file", source, dest);
107 return -1; 109 return -1;
108 } 110 }
111#endif
109 dest_exists = 1; 112 dest_exists = 1;
110 } 113 }
111 114
diff --git a/libbb/executable.c b/libbb/executable.c
index 85ecc3e6c..12a48cea3 100644
--- a/libbb/executable.c
+++ b/libbb/executable.c
@@ -28,6 +28,10 @@ int FAST_FUNC file_is_executable(const char *name)
28 * return NULL otherwise; (PATHp is undefined) 28 * return NULL otherwise; (PATHp is undefined)
29 * in all cases (*PATHp) contents will be trashed (s/:/NUL/). 29 * in all cases (*PATHp) contents will be trashed (s/:/NUL/).
30 */ 30 */
31#if !ENABLE_PLATFORM_MINGW32
32#define next_path_sep(s) strchr(s, ':')
33#endif
34
31char* FAST_FUNC find_executable(const char *filename, char **PATHp) 35char* FAST_FUNC find_executable(const char *filename, char **PATHp)
32{ 36{
33 /* About empty components in $PATH: 37 /* About empty components in $PATH:
@@ -39,10 +43,13 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp)
39 * following the rest of the list. 43 * following the rest of the list.
40 */ 44 */
41 char *p, *n; 45 char *p, *n;
46#if ENABLE_PLATFORM_MINGW32
47 char *w;
48#endif
42 49
43 p = *PATHp; 50 p = *PATHp;
44 while (p) { 51 while (p) {
45 n = strchr(p, ':'); 52 n = (char*)next_path_sep(p);
46 if (n) 53 if (n)
47 *n++ = '\0'; 54 *n++ = '\0';
48 p = concat_path_file( 55 p = concat_path_file(
@@ -53,6 +60,13 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp)
53 *PATHp = n; 60 *PATHp = n;
54 return p; 61 return p;
55 } 62 }
63#if ENABLE_PLATFORM_MINGW32
64 else if ((w=file_is_win32_executable(p))) {
65 *PATHp = n;
66 free(p);
67 return w;
68 }
69#endif
56 free(p); 70 free(p);
57 p = n; 71 p = n;
58 } /* on loop exit p == NULL */ 72 } /* on loop exit p == NULL */
diff --git a/libbb/find_mount_point.c b/libbb/find_mount_point.c
index 9676b5f52..b9bc1dd76 100644
--- a/libbb/find_mount_point.c
+++ b/libbb/find_mount_point.c
@@ -24,10 +24,18 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too)
24 struct mntent *mountEntry; 24 struct mntent *mountEntry;
25 dev_t devno_of_name; 25 dev_t devno_of_name;
26 bool block_dev; 26 bool block_dev;
27#if ENABLE_PLATFORM_MINGW32
28 static char mnt_fsname[4];
29 static char mnt_dir[4];
30 struct mntent my_mount_entry = { mnt_fsname, mnt_dir, "", "", 0, 0 };
31 char *current, *path;
32 DWORD len;
33#endif
27 34
28 if (stat(name, &s) != 0) 35 if (stat(name, &s) != 0)
29 return NULL; 36 return NULL;
30 37
38#if !ENABLE_PLATFORM_MINGW32
31 devno_of_name = s.st_dev; 39 devno_of_name = s.st_dev;
32 block_dev = 0; 40 block_dev = 0;
33 /* Why S_ISCHR? - UBI volumes use char devices, not block */ 41 /* Why S_ISCHR? - UBI volumes use char devices, not block */
@@ -64,6 +72,35 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too)
64 break; 72 break;
65 } 73 }
66 endmntent(mtab_fp); 74 endmntent(mtab_fp);
75#else
76 mountEntry = NULL;
77 path = NULL;
78 current = NULL;
79
80 if ( isalpha(name[0]) && name[1] == ':' ) {
81 path = name;
82 }
83 else {
84 if ( (len=GetCurrentDirectory(0, NULL)) > 0 &&
85 (current=malloc(len+1)) != NULL &&
86 GetCurrentDirectory(len, current) ) {
87 path = current;
88 }
89 }
90
91 if ( path && isalpha(path[0]) && path[1] == ':' ) {
92 mnt_fsname[0] = path[0];
93 mnt_fsname[1] = path[1];
94 mnt_fsname[2] = '\0';
95 mnt_dir[0] = path[0];
96 mnt_dir[1] = path[1];
97 mnt_dir[2] = '\\';
98 mnt_dir[3] = '\0';
99
100 mountEntry = &my_mount_entry;
101 }
102 free(current);
103#endif
67 104
68 return mountEntry; 105 return mountEntry;
69} 106}
diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c
index db823d05b..d4bea8ab5 100644
--- a/libbb/find_pid_by_name.c
+++ b/libbb/find_pid_by_name.c
@@ -56,6 +56,7 @@ static int comm_match(procps_status_t *p, const char *procName)
56 * This can be crazily_long_script_name.sh! 56 * This can be crazily_long_script_name.sh!
57 * The telltale sign is basename(argv[1]) == procName */ 57 * The telltale sign is basename(argv[1]) == procName */
58 58
59#if !ENABLE_PLATFORM_MINGW32
59 if (!p->argv0) 60 if (!p->argv0)
60 return 0; 61 return 0;
61 62
@@ -66,6 +67,7 @@ static int comm_match(procps_status_t *p, const char *procName)
66 67
67 if (strcmp(bb_basename(argv1), procName) != 0) 68 if (strcmp(bb_basename(argv1), procName) != 0)
68 return 0; 69 return 0;
70#endif
69 71
70 return 1; 72 return 1;
71} 73}
@@ -88,10 +90,12 @@ pid_t* FAST_FUNC find_pid_by_name(const char *procName)
88 pidList = xzalloc(sizeof(*pidList)); 90 pidList = xzalloc(sizeof(*pidList));
89 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) { 91 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) {
90 if (comm_match(p, procName) 92 if (comm_match(p, procName)
93#if !ENABLE_PLATFORM_MINGW32
91 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ 94 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
92 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) 95 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
93 /* or we require /proc/PID/exe link to match */ 96 /* or we require /proc/PID/exe link to match */
94 || (p->exe && strcmp(bb_basename(p->exe), procName) == 0) 97 || (p->exe && strcmp(bb_basename(p->exe), procName) == 0)
98#endif
95 ) { 99 ) {
96 pidList = xrealloc_vector(pidList, 2, i); 100 pidList = xrealloc_vector(pidList, 2, i);
97 pidList[i++] = p->pid; 101 pidList[i++] = p->pid;
diff --git a/libbb/get_last_path_component.c b/libbb/get_last_path_component.c
index 04fdf2a3e..db4be68ad 100644
--- a/libbb/get_last_path_component.c
+++ b/libbb/get_last_path_component.c
@@ -13,6 +13,11 @@ const char* FAST_FUNC bb_basename(const char *name)
13 const char *cp = strrchr(name, '/'); 13 const char *cp = strrchr(name, '/');
14 if (cp) 14 if (cp)
15 return cp + 1; 15 return cp + 1;
16#if ENABLE_PLATFORM_MINGW32
17 cp = strrchr(name, '\\');
18 if (cp)
19 return cp + 1;
20#endif
16 return name; 21 return name;
17} 22}
18 23
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c
index a98dd35eb..2038fac7d 100644
--- a/libbb/get_line_from_file.c
+++ b/libbb/get_line_from_file.c
@@ -57,6 +57,10 @@ char* FAST_FUNC xmalloc_fgetline(FILE *file)
57 57
58 if (i && c[--i] == '\n') 58 if (i && c[--i] == '\n')
59 c[i] = '\0'; 59 c[i] = '\0';
60#if ENABLE_PLATFORM_MINGW32
61 if (i && c[--i] == '\r')
62 c[i] = '\0';
63#endif
60 64
61 return c; 65 return c;
62} 66}
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index d0e83d88e..ae019b26b 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -540,7 +540,7 @@ getopt32(char **argv, const char *applet_opts, ...)
540 * run_nofork_applet() does this, but we might end up here 540 * run_nofork_applet() does this, but we might end up here
541 * also via gunzip_main() -> gzip_main(). Play safe. 541 * also via gunzip_main() -> gzip_main(). Play safe.
542 */ 542 */
543#ifdef __GLIBC__ 543#if defined(__GLIBC__) || ENABLE_PLATFORM_MINGW32
544 optind = 0; 544 optind = 0;
545#else /* BSD style */ 545#else /* BSD style */
546 optind = 1; 546 optind = 1;
diff --git a/libbb/inode_hash.c b/libbb/inode_hash.c
index f11c2afb2..64f43b885 100644
--- a/libbb/inode_hash.c
+++ b/libbb/inode_hash.c
@@ -59,6 +59,7 @@ char* FAST_FUNC is_in_ino_dev_hashtable(const struct stat *statbuf)
59/* Add statbuf to statbuf hash table */ 59/* Add statbuf to statbuf hash table */
60void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) 60void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
61{ 61{
62#if !ENABLE_PLATFORM_MINGW32
62 int i; 63 int i;
63 ino_dev_hashtable_bucket_t *bucket; 64 ino_dev_hashtable_bucket_t *bucket;
64 65
@@ -76,6 +77,7 @@ void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char *
76 i = hash_inode(statbuf->st_ino); 77 i = hash_inode(statbuf->st_ino);
77 bucket->next = ino_dev_hashtable[i]; 78 bucket->next = ino_dev_hashtable[i];
78 ino_dev_hashtable[i] = bucket; 79 ino_dev_hashtable[i] = bucket;
80#endif
79} 81}
80 82
81#if ENABLE_DU || ENABLE_FEATURE_CLEAN_UP 83#if ENABLE_DU || ENABLE_FEATURE_CLEAN_UP
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 720a4951e..3d96a8e9f 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -346,7 +346,7 @@ int adjust_width_and_validate_wc(unsigned *width_adj, int wc);
346/* Put 'command_ps[cursor]', cursor++. 346/* Put 'command_ps[cursor]', cursor++.
347 * Advance cursor on screen. If we reached right margin, scroll text up 347 * Advance cursor on screen. If we reached right margin, scroll text up
348 * and remove terminal margin effect by printing 'next_char' */ 348 * and remove terminal margin effect by printing 'next_char' */
349#define HACK_FOR_WRONG_WIDTH 1 349#define HACK_FOR_WRONG_WIDTH 1 && !ENABLE_PLATFORM_MINGW32
350static void put_cur_glyph_and_inc_cursor(void) 350static void put_cur_glyph_and_inc_cursor(void)
351{ 351{
352 CHAR_T c = command_ps[cursor]; 352 CHAR_T c = command_ps[cursor];
@@ -409,6 +409,42 @@ static void put_cur_glyph_and_inc_cursor(void)
409 } 409 }
410} 410}
411 411
412#if ENABLE_PLATFORM_MINGW32
413static void inc_cursor(void)
414{
415 CHAR_T c = command_ps[cursor];
416 unsigned width = 0;
417 int ofs_to_right;
418
419 /* advance cursor */
420 cursor++;
421 if (unicode_status == UNICODE_ON) {
422 IF_UNICODE_WIDE_WCHARS(width = cmdedit_x;)
423 c = adjust_width_and_validate_wc(&cmdedit_x, c);
424 IF_UNICODE_WIDE_WCHARS(width = cmdedit_x - width;)
425 } else {
426 cmdedit_x++;
427 }
428
429 ofs_to_right = cmdedit_x - cmdedit_termw;
430 if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right <= 0) {
431 /* cursor remains on this line */
432 printf(ESC"[1C");
433 }
434
435 if (ofs_to_right >= 0) {
436 /* we go to the next line */
437 printf(ESC"[1B");
438 bb_putchar('\r');
439 cmdedit_y++;
440 if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) {
441 width = 0;
442 }
443 cmdedit_x = width;
444 }
445}
446#endif
447
412/* Move to end of line (by printing all chars till the end) */ 448/* Move to end of line (by printing all chars till the end) */
413static void put_till_end_and_adv_cursor(void) 449static void put_till_end_and_adv_cursor(void)
414{ 450{
@@ -465,6 +501,7 @@ static void input_backward(unsigned num)
465 501
466 if (cmdedit_x >= num) { 502 if (cmdedit_x >= num) {
467 cmdedit_x -= num; 503 cmdedit_x -= num;
504#if !ENABLE_PLATFORM_MINGW32
468 if (num <= 4) { 505 if (num <= 4) {
469 /* This is longer by 5 bytes on x86. 506 /* This is longer by 5 bytes on x86.
470 * Also gets miscompiled for ARM users 507 * Also gets miscompiled for ARM users
@@ -477,6 +514,7 @@ static void input_backward(unsigned num)
477 } while (--num); 514 } while (--num);
478 return; 515 return;
479 } 516 }
517#endif
480 printf(ESC"[%uD", num); 518 printf(ESC"[%uD", num);
481 return; 519 return;
482 } 520 }
@@ -608,7 +646,11 @@ static void input_backspace(void)
608static void input_forward(void) 646static void input_forward(void)
609{ 647{
610 if (cursor < command_len) 648 if (cursor < command_len)
649#if !ENABLE_PLATFORM_MINGW32
611 put_cur_glyph_and_inc_cursor(); 650 put_cur_glyph_and_inc_cursor();
651#else
652 inc_cursor();
653#endif
612} 654}
613 655
614#if ENABLE_FEATURE_TAB_COMPLETION 656#if ENABLE_FEATURE_TAB_COMPLETION
@@ -719,7 +761,11 @@ static int path_parse(char ***p)
719 tmp = (char*)pth; 761 tmp = (char*)pth;
720 npth = 1; /* path component count */ 762 npth = 1; /* path component count */
721 while (1) { 763 while (1) {
764#if ENABLE_PLATFORM_MINGW32
765 tmp = next_path_sep(tmp);
766#else
722 tmp = strchr(tmp, ':'); 767 tmp = strchr(tmp, ':');
768#endif
723 if (!tmp) 769 if (!tmp)
724 break; 770 break;
725 tmp++; 771 tmp++;
@@ -732,7 +778,11 @@ static int path_parse(char ***p)
732 res[0] = tmp = xstrdup(pth); 778 res[0] = tmp = xstrdup(pth);
733 npth = 1; 779 npth = 1;
734 while (1) { 780 while (1) {
781#if ENABLE_PLATFORM_MINGW32
782 tmp = next_path_sep(tmp);
783#else
735 tmp = strchr(tmp, ':'); 784 tmp = strchr(tmp, ':');
785#endif
736 if (!tmp) 786 if (!tmp)
737 break; 787 break;
738 *tmp++ = '\0'; /* ':' -> '\0' */ 788 *tmp++ = '\0'; /* ':' -> '\0' */
@@ -1886,7 +1936,11 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1886 /* /home/user[/something] -> ~[/something] */ 1936 /* /home/user[/something] -> ~[/something] */
1887 l = strlen(home_pwd_buf); 1937 l = strlen(home_pwd_buf);
1888 if (l != 0 1938 if (l != 0
1939#if !ENABLE_PLATFORM_MINGW32
1889 && strncmp(home_pwd_buf, cwd_buf, l) == 0 1940 && strncmp(home_pwd_buf, cwd_buf, l) == 0
1941#else
1942 && strncasecmp(home_pwd_buf, cwd_buf, l) == 0
1943#endif
1890 && (cwd_buf[l] == '/' || cwd_buf[l] == '\0') 1944 && (cwd_buf[l] == '/' || cwd_buf[l] == '\0')
1891 ) { 1945 ) {
1892 cwd_buf[0] = '~'; 1946 cwd_buf[0] = '~';
@@ -2255,9 +2309,16 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2255 2309
2256 INIT_S(); 2310 INIT_S();
2257 2311
2312#if ENABLE_PLATFORM_MINGW32
2313 memset(initial_settings.c_cc, sizeof(initial_settings.c_cc), 0);
2314 initial_settings.c_cc[VINTR] = CTRL('C');
2315 initial_settings.c_cc[VEOF] = CTRL('D');
2316 if (!isatty(0) || !isatty(1)) {
2317#else
2258 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0 2318 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0
2259 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON 2319 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON
2260 ) { 2320 ) {
2321#endif
2261 /* Happens when e.g. stty -echo was run before. 2322 /* Happens when e.g. stty -echo was run before.
2262 * But if ICANON is not set, we don't come here. 2323 * But if ICANON is not set, we don't come here.
2263 * (example: interactive python ^Z-backgrounded, 2324 * (example: interactive python ^Z-backgrounded,
@@ -2611,7 +2672,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2611 * standard readline bindings (IOW: bash) do. 2672 * standard readline bindings (IOW: bash) do.
2612 * Often, Alt-<key> generates ESC-<key>. 2673 * Often, Alt-<key> generates ESC-<key>.
2613 */ 2674 */
2614 ic = lineedit_read_key(read_key_buffer, 50); 2675 ic = lineedit_read_key(read_key_buffer, 20);
2615 switch (ic) { 2676 switch (ic) {
2616 //case KEYCODE_LEFT: - bash doesn't do this 2677 //case KEYCODE_LEFT: - bash doesn't do this
2617 case 'b': 2678 case 'b':
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 89352ca1f..3980376ec 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -45,6 +45,31 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
45 c = '\0'; 45 c = '\0';
46 46
47 if (flags & FILEUTILS_RECUR) { /* Get the parent */ 47 if (flags & FILEUTILS_RECUR) { /* Get the parent */
48#if ENABLE_PLATFORM_MINGW32
49 if (s == path && *s && s[1] == ':') {
50 /* skip drive letter */
51 s += 2;
52 }
53 else if (s == path && s[0] == '/' && s[1] == '/' ) {
54 /* skip UNC server and share */
55 int count = 0;
56 s += 2;
57 while (*s) {
58 if (*s == '/') {
59 do {
60 ++s;
61 } while (*s == '/');
62 if (++count == 2) {
63 --s;
64 break;
65 }
66 }
67 else {
68 ++s;
69 }
70 }
71 }
72#endif
48 /* Bypass leading non-'/'s and then subsequent '/'s */ 73 /* Bypass leading non-'/'s and then subsequent '/'s */
49 while (*s) { 74 while (*s) {
50 if (*s == '/') { 75 if (*s == '/') {
diff --git a/libbb/messages.c b/libbb/messages.c
index fad82c9da..ef42b30d7 100644
--- a/libbb/messages.c
+++ b/libbb/messages.c
@@ -35,7 +35,9 @@ const char bb_msg_standard_output[] ALIGN1 = "standard output";
35 35
36const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF"; 36const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
37 37
38#if !ENABLE_PLATFORM_MINGW32
38const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH; 39const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
40#endif
39const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; 41const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
40/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, 42/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
41 * but I want to save a few bytes here. Check libbb.h before changing! */ 43 * but I want to save a few bytes here. Check libbb.h before changing! */
diff --git a/libbb/printable_string.c b/libbb/printable_string.c
index a316f60de..3e768d0b9 100644
--- a/libbb/printable_string.c
+++ b/libbb/printable_string.c
@@ -45,7 +45,7 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
45 unsigned char c = *d; 45 unsigned char c = *d;
46 if (c == '\0') 46 if (c == '\0')
47 break; 47 break;
48 if (c < ' ' || c >= 0x7f) 48 if (c < ' ' || (c >= 0x7f && !ENABLE_PLATFORM_MINGW32))
49 *d = '?'; 49 *d = '?';
50 d++; 50 d++;
51 } 51 }
diff --git a/libbb/procps.c b/libbb/procps.c
index 5b68d3431..3c99ac6e7 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -75,6 +75,7 @@ const char* FAST_FUNC get_cached_groupname(gid_t gid)
75 return get_cached(&groupname, gid, gid2group_utoa); 75 return get_cached(&groupname, gid, gid2group_utoa);
76} 76}
77 77
78#if !ENABLE_PLATFORM_MINGW32
78 79
79#define PROCPS_BUFSIZE 1024 80#define PROCPS_BUFSIZE 1024
80 81
@@ -620,6 +621,8 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
620 } 621 }
621} 622}
622 623
624#endif /* ENABLE_PLATFORM_MINGW32 */
625
623/* from kernel: 626/* from kernel:
624 // pid comm S ppid pgid sid tty_nr tty_pgrp flg 627 // pid comm S ppid pgid sid tty_nr tty_pgrp flg
625 sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ 628 sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
diff --git a/libbb/read_printf.c b/libbb/read_printf.c
index 5ed6e3632..ef4911cd5 100644
--- a/libbb/read_printf.c
+++ b/libbb/read_printf.c
@@ -93,6 +93,11 @@ char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p)
93 break; 93 break;
94 p++; 94 p++;
95 } 95 }
96#if ENABLE_PLATFORM_MINGW32
97 if ( p != buf && *(p-1) == '\r' ) {
98 --p;
99 }
100#endif
96 *p = '\0'; 101 *p = '\0';
97 if (maxsz_p) 102 if (maxsz_p)
98 *maxsz_p = p - buf; 103 *maxsz_p = p - buf;
diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c
index 4258656fe..944ac5538 100644
--- a/libbb/setup_environment.c
+++ b/libbb/setup_environment.c
@@ -30,6 +30,14 @@
30 30
31#include "libbb.h" 31#include "libbb.h"
32 32
33#if ENABLE_PLATFORM_MINGW32
34static void xsetenv_if_unset(const char *key, const char *value)
35{
36 if (!getenv(key))
37 xsetenv(key, value);
38}
39#endif
40
33void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw) 41void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw)
34{ 42{
35 if (!shell || !shell[0]) 43 if (!shell || !shell[0])
@@ -61,6 +69,9 @@ void FAST_FUNC setup_environment(const char *shell, int flags, const struct pass
61 //xsetenv("HOME", pw->pw_dir); 69 //xsetenv("HOME", pw->pw_dir);
62 //xsetenv("SHELL", shell); 70 //xsetenv("SHELL", shell);
63 } else if (flags & SETUP_ENV_CHANGEENV) { 71 } else if (flags & SETUP_ENV_CHANGEENV) {
72#if ENABLE_PLATFORM_MINGW32
73#define xsetenv(k, v) xsetenv_if_unset(k, v)
74#endif
64 /* Set HOME, SHELL, and if not becoming a super-user, 75 /* Set HOME, SHELL, and if not becoming a super-user,
65 * USER and LOGNAME. */ 76 * USER and LOGNAME. */
66 if (pw->pw_uid) { 77 if (pw->pw_uid) {
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index ed1f86f0c..6611dabfa 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -25,6 +25,9 @@ pid_t FAST_FUNC spawn(char **argv)
25 volatile int failed; 25 volatile int failed;
26 pid_t pid; 26 pid_t pid;
27 27
28 if (ENABLE_PLATFORM_MINGW32)
29 return mingw_spawn(argv);
30
28 fflush_all(); 31 fflush_all();
29 32
30 /* Be nice to nommu machines. */ 33 /* Be nice to nommu machines. */
@@ -183,7 +186,7 @@ int FAST_FUNC spawn_and_wait(char **argv)
183 { 186 {
184 return run_nofork_applet(a, argv); 187 return run_nofork_applet(a, argv);
185 } 188 }
186# if BB_MMU 189# if BB_MMU && !ENABLE_PLATFORM_MINGW32
187 /* MMU only */ 190 /* MMU only */
188 /* a->noexec is true */ 191 /* a->noexec is true */
189 rc = fork(); 192 rc = fork();
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index 7d4cb60a5..2c5a9ef39 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -65,7 +65,7 @@ char* FAST_FUNC xmalloc_follow_symlinks(const char *path)
65 linkpath = xmalloc_readlink(buf); 65 linkpath = xmalloc_readlink(buf);
66 if (!linkpath) { 66 if (!linkpath) {
67 /* not a symlink, or doesn't exist */ 67 /* not a symlink, or doesn't exist */
68 if (errno == EINVAL || errno == ENOENT) 68 if (errno == EINVAL || errno == ENOENT || (ENABLE_PLATFORM_MINGW32 && errno == ENOSYS))
69 return buf; 69 return buf;
70 goto free_buf_ret_null; 70 goto free_buf_ret_null;
71 } 71 }