aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libbb/Kbuild.src21
-rw-r--r--libbb/appletlib.c92
-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.c26
-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.c126
-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.c4
-rw-r--r--libbb/xconnect.c12
-rw-r--r--libbb/xreadlink.c2
20 files changed, 376 insertions, 23 deletions
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 898a51a89..fc9371db1 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -37,24 +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 46lib-y += inet_common.o
49lib-y += inode_hash.o 47lib-y += inode_hash.o
50lib-y += isdirectory.o 48lib-y += isdirectory.o
51lib-y += kernel_version.o
52lib-y += last_char_is.o 49lib-y += last_char_is.o
53lib-y += lineedit.o lineedit_ptr_hack.o 50lib-y += lineedit.o lineedit_ptr_hack.o
54lib-y += llist.o 51lib-y += llist.o
55lib-y += login.o
56lib-y += make_directory.o 52lib-y += make_directory.o
57lib-y += makedev.o
58lib-y += hash_md5_sha.o 53lib-y += hash_md5_sha.o
59# Alternative (disabled) MD5 implementation 54# Alternative (disabled) MD5 implementation
60#lib-y += hash_md5prime.o 55#lib-y += hash_md5prime.o
@@ -75,7 +70,6 @@ lib-y += progress.o
75lib-y += ptr_to_globals.o 70lib-y += ptr_to_globals.o
76lib-y += read.o 71lib-y += read.o
77lib-y += read_printf.o 72lib-y += read_printf.o
78lib-y += read_key.o
79lib-y += recursive_action.o 73lib-y += recursive_action.o
80lib-y += remove_file.o 74lib-y += remove_file.o
81lib-y += run_shell.o 75lib-y += run_shell.o
@@ -84,7 +78,6 @@ lib-y += safe_poll.o
84lib-y += safe_strncpy.o 78lib-y += safe_strncpy.o
85lib-y += safe_write.o 79lib-y += safe_write.o
86lib-y += setup_environment.o 80lib-y += setup_environment.o
87lib-y += signals.o
88lib-y += simplify_path.o 81lib-y += simplify_path.o
89lib-y += single_argv.o 82lib-y += single_argv.o
90lib-y += skip_whitespace.o 83lib-y += skip_whitespace.o
@@ -109,10 +102,20 @@ lib-y += xfuncs.o
109lib-y += xfuncs_printf.o 102lib-y += xfuncs_printf.o
110lib-y += xfunc_die.o 103lib-y += xfunc_die.o
111lib-y += xgetcwd.o 104lib-y += xgetcwd.o
112lib-y += xgethostbyname.o
113lib-y += xreadlink.o 105lib-y += xreadlink.o
114lib-y += xrealloc_vector.o 106lib-y += xrealloc_vector.o
115 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
116lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o 119lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o
117 120
118lib-$(CONFIG_FEATURE_UTMP) += utmp.o 121lib-$(CONFIG_FEATURE_UTMP) += utmp.o
@@ -124,7 +127,7 @@ lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o
124lib-$(CONFIG_UNICODE_SUPPORT) += unicode.o 127lib-$(CONFIG_UNICODE_SUPPORT) += unicode.o
125lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o 128lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o
126 129
127lib-$(CONFIG_NC) += udp_io.o 130lib-$(CONFIG_NC_110_COMPAT) += udp_io.o
128lib-$(CONFIG_DNSD) += udp_io.o 131lib-$(CONFIG_DNSD) += udp_io.o
129lib-$(CONFIG_NTPD) += udp_io.o 132lib-$(CONFIG_NTPD) += udp_io.o
130lib-$(CONFIG_TFTP) += udp_io.o 133lib-$(CONFIG_TFTP) += udp_io.o
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index ee8b4ec14..ac3e414f5 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -61,6 +61,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE;
61#if ENABLE_FEATURE_COMPRESS_USAGE 61#if ENABLE_FEATURE_COMPRESS_USAGE
62 62
63static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 63static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
64#define BB_ARCHIVE_PUBLIC
64# include "bb_archive.h" 65# include "bb_archive.h"
65static const char *unpack_usage_messages(void) 66static const char *unpack_usage_messages(void)
66{ 67{
@@ -281,6 +282,10 @@ void lbb_prepare(const char *applet
281 if (ENABLE_LOCALE_SUPPORT) 282 if (ENABLE_LOCALE_SUPPORT)
282 setlocale(LC_ALL, ""); 283 setlocale(LC_ALL, "");
283 284
285#if ENABLE_PLATFORM_MINGW32
286 init_winsock();
287#endif
288
284#if ENABLE_FEATURE_INDIVIDUAL 289#if ENABLE_FEATURE_INDIVIDUAL
285 /* Redundant for busybox (run_applet_and_exit covers that case) 290 /* Redundant for busybox (run_applet_and_exit covers that case)
286 * but needed for "individual applet" mode */ 291 * but needed for "individual applet" mode */
@@ -656,6 +661,7 @@ static void check_suid(int applet_no)
656 661
657 662
658# if ENABLE_FEATURE_INSTALLER 663# if ENABLE_FEATURE_INSTALLER
664# if !ENABLE_PLATFORM_MINGW32
659static const char usr_bin [] ALIGN1 = "/usr/bin/"; 665static const char usr_bin [] ALIGN1 = "/usr/bin/";
660static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; 666static const char usr_sbin[] ALIGN1 = "/usr/sbin/";
661static const char *const install_dir[] = { 667static const char *const install_dir[] = {
@@ -700,6 +706,29 @@ static void install_links(const char *busybox, int use_symbolic_links,
700 continue; 706 continue;
701 } 707 }
702} 708}
709# else /* ENABLE_PLATFORM_MINGW32 */
710static void install_links(const char *busybox,
711 int use_symbolic_links UNUSED_PARAM, char *custom_install_dir)
712{
713 char *fpc;
714 const char *appname = applet_names;
715 int rc;
716
717 if (!is_directory(custom_install_dir, FALSE))
718 bb_error_msg_and_die("'%s' is not a directory", custom_install_dir);
719
720 while (*appname) {
721 fpc = xasprintf("%s/%s.exe", custom_install_dir, appname);
722 rc = link(busybox, fpc);
723 if (rc != 0 && errno != EEXIST) {
724 bb_simple_perror_msg(fpc);
725 }
726 free(fpc);
727 while (*appname++ != '\0')
728 continue;
729 }
730}
731# endif
703# elif ENABLE_BUSYBOX 732# elif ENABLE_BUSYBOX
704static void install_links(const char *busybox UNUSED_PARAM, 733static void install_links(const char *busybox UNUSED_PARAM,
705 int use_symbolic_links UNUSED_PARAM, 734 int use_symbolic_links UNUSED_PARAM,
@@ -729,15 +758,25 @@ static int busybox_main(char **argv)
729 dup2(1, 2); 758 dup2(1, 2);
730 full_write2_str(bb_banner); /* reuse const string */ 759 full_write2_str(bb_banner); /* reuse const string */
731 full_write2_str(" multi-call binary.\n"); /* reuse */ 760 full_write2_str(" multi-call binary.\n"); /* reuse */
761#if defined(MINGW_VER)
762 if (strlen(MINGW_VER)) {
763 full_write2_str(MINGW_VER "\n\n");
764 }
765#endif
732 full_write2_str( 766 full_write2_str(
733 "BusyBox is copyrighted by many authors between 1998-2015.\n" 767 "BusyBox is copyrighted by many authors between 1998-2015.\n"
734 "Licensed under GPLv2. See source distribution for detailed\n" 768 "Licensed under GPLv2. See source distribution for detailed\n"
735 "copyright notices.\n" 769 "copyright notices.\n"
736 "\n" 770 "\n"
737 "Usage: busybox [function [arguments]...]\n" 771 "Usage: busybox [function [arguments]...]\n"
772 IF_NOT_PLATFORM_MINGW32(
738 " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" 773 " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n"
774 )
775 IF_PLATFORM_MINGW32(
776 " or: busybox --list\n"
777 )
739 IF_FEATURE_INSTALLER( 778 IF_FEATURE_INSTALLER(
740 " or: busybox --install [-s] [DIR]\n" 779 " or: busybox --install "IF_NOT_PLATFORM_MINGW32("[-s] ")"[DIR]\n"
741 ) 780 )
742 " or: function [arguments]...\n" 781 " or: function [arguments]...\n"
743 "\n" 782 "\n"
@@ -755,6 +794,11 @@ static int busybox_main(char **argv)
755 "\tTo run external program, use full path (/sbin/ip instead of ip).\n" 794 "\tTo run external program, use full path (/sbin/ip instead of ip).\n"
756 ) 795 )
757 "\n" 796 "\n"
797#if ENABLE_GLOBBING
798 "\tSupport for native Windows wildcards is enabled. In some\n"
799 "\tcases this may result in wildcards being processed twice.\n"
800 "\n"
801#endif
758 "Currently defined functions:\n" 802 "Currently defined functions:\n"
759 ); 803 );
760 col = 0; 804 col = 0;
@@ -786,7 +830,7 @@ static int busybox_main(char **argv)
786 const char *a = applet_names; 830 const char *a = applet_names;
787 dup2(1, 2); 831 dup2(1, 2);
788 while (*a) { 832 while (*a) {
789# if ENABLE_FEATURE_INSTALLER 833# if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32
790 if (argv[1][6]) /* --list-full? */ 834 if (argv[1][6]) /* --list-full? */
791 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); 835 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
792# endif 836# endif
@@ -800,6 +844,7 @@ static int busybox_main(char **argv)
800 } 844 }
801 845
802 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { 846 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) {
847#if !ENABLE_PLATFORM_MINGW32
803 int use_symbolic_links; 848 int use_symbolic_links;
804 const char *busybox; 849 const char *busybox;
805 850
@@ -820,6 +865,14 @@ static int busybox_main(char **argv)
820 */ 865 */
821 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); 866 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv);
822 install_links(busybox, use_symbolic_links, argv[2]); 867 install_links(busybox, use_symbolic_links, argv[2]);
868#else
869 /* busybox --install [DIR]
870 * where DIR is the directory to install to. If DIR is not
871 * provided put the links in the same directory as busybox.
872 */
873 install_links(bb_busybox_exec_path, FALSE, argv[2] ? argv[2] :
874 dirname(xstrdup(bb_busybox_exec_path)));
875#endif
823 return 0; 876 return 0;
824 } 877 }
825 878
@@ -960,6 +1013,18 @@ int main(int argc UNUSED_PARAM, char **argv)
960 } 1013 }
961#endif 1014#endif
962 1015
1016#if defined(__MINGW64_VERSION_MAJOR)
1017 if ( stdin ) {
1018 _setmode(fileno(stdin), _O_BINARY);
1019 }
1020 if ( stdout ) {
1021 _setmode(fileno(stdout), _O_BINARY);
1022 }
1023 if ( stderr ) {
1024 _setmode(fileno(stderr), _O_BINARY);
1025 }
1026#endif
1027
963#if defined(SINGLE_APPLET_MAIN) 1028#if defined(SINGLE_APPLET_MAIN)
964 1029
965 /* Only one applet is selected in .config */ 1030 /* Only one applet is selected in .config */
@@ -987,6 +1052,29 @@ int main(int argc UNUSED_PARAM, char **argv)
987 applet_name = argv[0]; 1052 applet_name = argv[0];
988 if (applet_name[0] == '-') 1053 if (applet_name[0] == '-')
989 applet_name++; 1054 applet_name++;
1055 if (ENABLE_PLATFORM_MINGW32) {
1056 const char *applet_name_env = getenv("BUSYBOX_APPLET_NAME");
1057 if (applet_name_env && *applet_name_env) {
1058 applet_name = applet_name_env;
1059 unsetenv("BUSYBOX_APPLET_NAME");
1060 }
1061 else if ( argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0 ) {
1062 argv += 2;
1063 applet_name = argv[0];
1064 }
1065 else {
1066 char *s = argv[0];
1067 int i, len = strlen(s);
1068
1069 for ( i=0; i < len; ++i ) {
1070 s[i] = tolower(s[i]);
1071 }
1072 if (len > 4 && !strcmp(s+len-4, ".exe")) {
1073 len -= 4;
1074 s[len] = '\0';
1075 }
1076 }
1077 }
990 applet_name = bb_basename(applet_name); 1078 applet_name = bb_basename(applet_name);
991 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ 1079 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */
992 run_applet_and_exit(applet_name, argv); 1080 run_applet_and_exit(applet_name, argv);
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 23c0f8320..cb6d12359 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -105,12 +105,15 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
105 return -1; 105 return -1;
106 } 106 }
107 } else { 107 } else {
108#if !ENABLE_PLATFORM_MINGW32
109 /* MinGW does not have inode, and does not use device */
108 if (source_stat.st_dev == dest_stat.st_dev 110 if (source_stat.st_dev == dest_stat.st_dev
109 && source_stat.st_ino == dest_stat.st_ino 111 && source_stat.st_ino == dest_stat.st_ino
110 ) { 112 ) {
111 bb_error_msg("'%s' and '%s' are the same file", source, dest); 113 bb_error_msg("'%s' and '%s' are the same file", source, dest);
112 return -1; 114 return -1;
113 } 115 }
116#endif
114 dest_exists = 1; 117 dest_exists = 1;
115 } 118 }
116 119
diff --git a/libbb/executable.c b/libbb/executable.c
index 3a1d4ff44..5f0ff8c6e 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..de314a3c7 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 static 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..15eb85ca8 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
@@ -26,8 +31,18 @@ char* FAST_FUNC bb_get_last_path_component_nostrip(const char *path)
26{ 31{
27 char *slash = strrchr(path, '/'); 32 char *slash = strrchr(path, '/');
28 33
34#if ENABLE_PLATFORM_MINGW32
35 const char *start = has_dos_drive_prefix(path) ? path+2 : path;
36
37 if (!slash)
38 slash = strrchr(path, '\\');
39
40 if (!slash || (slash == start && !slash[1]))
41 return (char*)path;
42#else
29 if (!slash || (slash == path && !slash[1])) 43 if (!slash || (slash == path && !slash[1]))
30 return (char*)path; 44 return (char*)path;
45#endif
31 46
32 return slash + 1; 47 return slash + 1;
33} 48}
@@ -42,9 +57,20 @@ char* FAST_FUNC bb_get_last_path_component_strip(char *path)
42{ 57{
43 char *slash = last_char_is(path, '/'); 58 char *slash = last_char_is(path, '/');
44 59
60#if ENABLE_PLATFORM_MINGW32
61 const char *start = has_dos_drive_prefix(path) ? path+2 : path;
62
63 if (!slash)
64 slash = last_char_is(path, '\\');
65
66 if (slash)
67 while ((*slash == '/' || *slash == '\\') && slash != start)
68 *slash-- = '\0';
69#else
45 if (slash) 70 if (slash)
46 while (*slash == '/' && slash != path) 71 while (*slash == '/' && slash != path)
47 *slash-- = '\0'; 72 *slash-- = '\0';
73#endif
48 74
49 return bb_get_last_path_component_nostrip(path); 75 return bb_get_last_path_component_nostrip(path);
50} 76}
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 15b6efc09..ed9352191 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -576,7 +576,7 @@ getopt32(char **argv, const char *applet_opts, ...)
576 * run_nofork_applet() does this, but we might end up here 576 * run_nofork_applet() does this, but we might end up here
577 * also via gunzip_main() -> gzip_main(). Play safe. 577 * also via gunzip_main() -> gzip_main(). Play safe.
578 */ 578 */
579#ifdef __GLIBC__ 579#if defined(__GLIBC__) || ENABLE_PLATFORM_MINGW32
580 optind = 0; 580 optind = 0;
581#else /* BSD style */ 581#else /* BSD style */
582 optind = 1; 582 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 31e392147..5d9080131 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -354,7 +354,7 @@ int adjust_width_and_validate_wc(unsigned *width_adj, int wc);
354/* Put 'command_ps[cursor]', cursor++. 354/* Put 'command_ps[cursor]', cursor++.
355 * Advance cursor on screen. If we reached right margin, scroll text up 355 * Advance cursor on screen. If we reached right margin, scroll text up
356 * and remove terminal margin effect by printing 'next_char' */ 356 * and remove terminal margin effect by printing 'next_char' */
357#define HACK_FOR_WRONG_WIDTH 1 357#define HACK_FOR_WRONG_WIDTH 1 && !ENABLE_PLATFORM_MINGW32
358static void put_cur_glyph_and_inc_cursor(void) 358static void put_cur_glyph_and_inc_cursor(void)
359{ 359{
360 CHAR_T c = command_ps[cursor]; 360 CHAR_T c = command_ps[cursor];
@@ -417,6 +417,42 @@ static void put_cur_glyph_and_inc_cursor(void)
417 } 417 }
418} 418}
419 419
420#if ENABLE_PLATFORM_MINGW32
421static void inc_cursor(void)
422{
423 CHAR_T c = command_ps[cursor];
424 unsigned width = 0;
425 int ofs_to_right;
426
427 /* advance cursor */
428 cursor++;
429 if (unicode_status == UNICODE_ON) {
430 IF_UNICODE_WIDE_WCHARS(width = cmdedit_x;)
431 c = adjust_width_and_validate_wc(&cmdedit_x, c);
432 IF_UNICODE_WIDE_WCHARS(width = cmdedit_x - width;)
433 } else {
434 cmdedit_x++;
435 }
436
437 ofs_to_right = cmdedit_x - cmdedit_termw;
438 if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right <= 0) {
439 /* cursor remains on this line */
440 printf(ESC"[1C");
441 }
442
443 if (ofs_to_right >= 0) {
444 /* we go to the next line */
445 printf(ESC"[1B");
446 bb_putchar('\r');
447 cmdedit_y++;
448 if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) {
449 width = 0;
450 }
451 cmdedit_x = width;
452 }
453}
454#endif
455
420/* Move to end of line (by printing all chars till the end) */ 456/* Move to end of line (by printing all chars till the end) */
421static void put_till_end_and_adv_cursor(void) 457static void put_till_end_and_adv_cursor(void)
422{ 458{
@@ -469,6 +505,7 @@ static void input_backward(unsigned num)
469 505
470 if (cmdedit_x >= num) { 506 if (cmdedit_x >= num) {
471 cmdedit_x -= num; 507 cmdedit_x -= num;
508#if !ENABLE_PLATFORM_MINGW32
472 if (num <= 4) { 509 if (num <= 4) {
473 /* This is longer by 5 bytes on x86. 510 /* This is longer by 5 bytes on x86.
474 * Also gets miscompiled for ARM users 511 * Also gets miscompiled for ARM users
@@ -481,6 +518,7 @@ static void input_backward(unsigned num)
481 } while (--num); 518 } while (--num);
482 return; 519 return;
483 } 520 }
521#endif
484 printf(ESC"[%uD", num); 522 printf(ESC"[%uD", num);
485 return; 523 return;
486 } 524 }
@@ -610,7 +648,11 @@ static void input_backspace(void)
610static void input_forward(void) 648static void input_forward(void)
611{ 649{
612 if (cursor < command_len) 650 if (cursor < command_len)
651#if !ENABLE_PLATFORM_MINGW32
613 put_cur_glyph_and_inc_cursor(); 652 put_cur_glyph_and_inc_cursor();
653#else
654 inc_cursor();
655#endif
614} 656}
615 657
616#if ENABLE_FEATURE_TAB_COMPLETION 658#if ENABLE_FEATURE_TAB_COMPLETION
@@ -638,6 +680,14 @@ static void add_match(char *matched)
638 num_matches++; 680 num_matches++;
639} 681}
640 682
683#if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
684static void add_partial_match(const char *part, const char *full, int plen)
685{
686 if (strncmp(part, full, plen) == 0)
687 add_match(xstrdup(full));
688}
689#endif
690
641# if ENABLE_FEATURE_USERNAME_COMPLETION 691# if ENABLE_FEATURE_USERNAME_COMPLETION
642/* Replace "~user/..." with "/homedir/...". 692/* Replace "~user/..." with "/homedir/...".
643 * The parameter is malloced, free it or return it 693 * The parameter is malloced, free it or return it
@@ -718,7 +768,11 @@ static int path_parse(char ***p)
718 tmp = (char*)pth; 768 tmp = (char*)pth;
719 npth = 1; /* path component count */ 769 npth = 1; /* path component count */
720 while (1) { 770 while (1) {
771#if ENABLE_PLATFORM_MINGW32
772 tmp = (char *)next_path_sep(tmp);
773#else
721 tmp = strchr(tmp, ':'); 774 tmp = strchr(tmp, ':');
775#endif
722 if (!tmp) 776 if (!tmp)
723 break; 777 break;
724 tmp++; 778 tmp++;
@@ -731,7 +785,11 @@ static int path_parse(char ***p)
731 res[0] = tmp = xstrdup(pth); 785 res[0] = tmp = xstrdup(pth);
732 npth = 1; 786 npth = 1;
733 while (1) { 787 while (1) {
788#if ENABLE_PLATFORM_MINGW32
789 tmp = (char *)next_path_sep(tmp);
790#else
734 tmp = strchr(tmp, ':'); 791 tmp = strchr(tmp, ':');
792#endif
735 if (!tmp) 793 if (!tmp)
736 break; 794 break;
737 *tmp++ = '\0'; /* ':' -> '\0' */ 795 *tmp++ = '\0'; /* ':' -> '\0' */
@@ -781,11 +839,11 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
781 const char *p = applet_names; 839 const char *p = applet_names;
782 840
783 while (*p) { 841 while (*p) {
784 if (strncmp(pfind, p, pf_len) == 0) 842 add_partial_match(pfind, p, pf_len);
785 add_match(xstrdup(p));
786 while (*p++ != '\0') 843 while (*p++ != '\0')
787 continue; 844 continue;
788 } 845 }
846 add_partial_match(pfind, "busybox", pf_len);
789 } 847 }
790#endif 848#endif
791 849
@@ -817,6 +875,9 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
817 if (stat(found, &st) && lstat(found, &st)) 875 if (stat(found, &st) && lstat(found, &st))
818 goto cont; /* hmm, remove in progress? */ 876 goto cont; /* hmm, remove in progress? */
819 877
878 if (type == FIND_EXE_ONLY && !file_is_executable(found))
879 goto cont;
880
820 /* Save only name */ 881 /* Save only name */
821 len = strlen(name_found); 882 len = strlen(name_found);
822 found = xrealloc(found, len + 2); /* +2: for slash and NUL */ 883 found = xrealloc(found, len + 2); /* +2: for slash and NUL */
@@ -1898,7 +1959,16 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1898 char *after_home_user; 1959 char *after_home_user;
1899 1960
1900 /* /home/user[/something] -> ~[/something] */ 1961 /* /home/user[/something] -> ~[/something] */
1962#if !ENABLE_PLATFORM_MINGW32
1901 after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf); 1963 after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf);
1964#else
1965 after_home_user = NULL;
1966 l = strlen(home_pwd_buf);
1967 if (l != 0
1968 && strncasecmp(home_pwd_buf, cwd_buf, l) == 0) {
1969 after_home_user = cwd_buf + l;
1970 }
1971#endif
1902 if (after_home_user 1972 if (after_home_user
1903 && (*after_home_user == '/' || *after_home_user == '\0') 1973 && (*after_home_user == '/' || *after_home_user == '\0')
1904 ) { 1974 ) {
@@ -2272,9 +2342,16 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2272 2342
2273 INIT_S(); 2343 INIT_S();
2274 2344
2345#if ENABLE_PLATFORM_MINGW32
2346 memset(initial_settings.c_cc, 0, sizeof(initial_settings.c_cc));
2347 initial_settings.c_cc[VINTR] = CTRL('C');
2348 initial_settings.c_cc[VEOF] = CTRL('D');
2349 if (!isatty(0) || !isatty(1)) {
2350#else
2275 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0 2351 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0
2276 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON 2352 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON
2277 ) { 2353 ) {
2354#endif
2278 /* Happens when e.g. stty -echo was run before. 2355 /* Happens when e.g. stty -echo was run before.
2279 * But if ICANON is not set, we don't come here. 2356 * But if ICANON is not set, we don't come here.
2280 * (example: interactive python ^Z-backgrounded, 2357 * (example: interactive python ^Z-backgrounded,
@@ -2383,6 +2460,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2383 } 2460 }
2384 2461
2385 ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); 2462 ic = ic_raw = lineedit_read_key(read_key_buffer, timeout);
2463#if ENABLE_PLATFORM_MINGW32
2464 /* scroll to cursor position on any keypress */
2465 if (isatty(fileno(stdin)) && isatty(fileno(stdout)))
2466 move_cursor_row(0);
2467#endif
2386 2468
2387#if ENABLE_FEATURE_REVERSE_SEARCH 2469#if ENABLE_FEATURE_REVERSE_SEARCH
2388 again: 2470 again:
@@ -2650,6 +2732,44 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2650 vi_cmdmode = 1; 2732 vi_cmdmode = 1;
2651 input_backward(1); 2733 input_backward(1);
2652 } 2734 }
2735 /* Handle a few ESC-<key> combinations the same way
2736 * standard readline bindings (IOW: bash) do.
2737 * Often, Alt-<key> generates ESC-<key>.
2738 */
2739 ic = lineedit_read_key(read_key_buffer, 20);
2740 switch (ic) {
2741 //case KEYCODE_LEFT: - bash doesn't do this
2742 case 'b':
2743 ctrl_left();
2744 break;
2745 //case KEYCODE_RIGHT: - bash doesn't do this
2746 case 'f':
2747 ctrl_right();
2748 break;
2749 //case KEYCODE_DELETE: - bash doesn't do this
2750 case 'd': /* Alt-D */
2751 {
2752 /* Delete word forward */
2753 int nc, sc = cursor;
2754 ctrl_right();
2755 nc = cursor - sc;
2756 input_backward(nc);
2757 while (--nc >= 0)
2758 input_delete(1);
2759 break;
2760 }
2761 case '\b': /* Alt-Backspace(?) */
2762 case '\x7f': /* Alt-Backspace(?) */
2763 //case 'w': - bash doesn't do this
2764 {
2765 /* Delete word backward */
2766 int sc = cursor;
2767 ctrl_left();
2768 while (sc-- > cursor)
2769 input_delete(1);
2770 break;
2771 }
2772 }
2653 break; 2773 break;
2654#endif /* FEATURE_COMMAND_EDITING_VI */ 2774#endif /* FEATURE_COMMAND_EDITING_VI */
2655 2775
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index a6b7c28df..840c525b0 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -56,6 +56,31 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
56 c = '\0'; 56 c = '\0';
57 57
58 if (flags & FILEUTILS_RECUR) { /* Get the parent */ 58 if (flags & FILEUTILS_RECUR) { /* Get the parent */
59#if ENABLE_PLATFORM_MINGW32
60 if (s == path && *s && s[1] == ':') {
61 /* skip drive letter */
62 s += 2;
63 }
64 else if (s == path && s[0] == '/' && s[1] == '/' ) {
65 /* skip UNC server and share */
66 int count = 0;
67 s += 2;
68 while (*s) {
69 if (*s == '/') {
70 do {
71 ++s;
72 } while (*s == '/');
73 if (++count == 2) {
74 --s;
75 break;
76 }
77 }
78 else {
79 ++s;
80 }
81 }
82 }
83#endif
59 /* Bypass leading non-'/'s and then subsequent '/'s */ 84 /* Bypass leading non-'/'s and then subsequent '/'s */
60 while (*s) { 85 while (*s) {
61 if (*s == '/') { 86 if (*s == '/') {
diff --git a/libbb/messages.c b/libbb/messages.c
index cb0836de8..d74c237e7 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 077d58d32..e638a178e 100644
--- a/libbb/printable_string.c
+++ b/libbb/printable_string.c
@@ -42,7 +42,7 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
42 unsigned char c = *d; 42 unsigned char c = *d;
43 if (c == '\0') 43 if (c == '\0')
44 break; 44 break;
45 if (c < ' ' || c >= 0x7f) 45 if (c < ' ' || (c >= 0x7f && !ENABLE_PLATFORM_MINGW32))
46 *d = '?'; 46 *d = '?';
47 d++; 47 d++;
48 } 48 }
diff --git a/libbb/procps.c b/libbb/procps.c
index 4edc54d48..452b50b82 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
@@ -618,6 +619,8 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
618 } 619 }
619} 620}
620 621
622#endif /* ENABLE_PLATFORM_MINGW32 */
623
621/* from kernel: 624/* from kernel:
622 // pid comm S ppid pgid sid tty_nr tty_pgrp flg 625 // pid comm S ppid pgid sid tty_nr tty_pgrp flg
623 sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ 626 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 b6a17cc36..e47ac7afe 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 c192829b5..766a89e5f 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -17,6 +17,7 @@
17 17
18#include "busybox.h" /* uses applet tables */ 18#include "busybox.h" /* uses applet tables */
19 19
20#if !ENABLE_PLATFORM_MINGW32
20/* This does a fork/exec in one call, using vfork(). Returns PID of new child, 21/* This does a fork/exec in one call, using vfork(). Returns PID of new child,
21 * -1 for failure. Runs argv[0], searching path if that has no / in it. */ 22 * -1 for failure. Runs argv[0], searching path if that has no / in it. */
22pid_t FAST_FUNC spawn(char **argv) 23pid_t FAST_FUNC spawn(char **argv)
@@ -58,6 +59,7 @@ pid_t FAST_FUNC spawn(char **argv)
58 } 59 }
59 return pid; 60 return pid;
60} 61}
62#endif
61 63
62/* Die with an error message if we can't spawn a child process. */ 64/* Die with an error message if we can't spawn a child process. */
63pid_t FAST_FUNC xspawn(char **argv) 65pid_t FAST_FUNC xspawn(char **argv)
@@ -194,7 +196,7 @@ int FAST_FUNC spawn_and_wait(char **argv)
194 { 196 {
195 return run_nofork_applet(a, argv); 197 return run_nofork_applet(a, argv);
196 } 198 }
197# if BB_MMU 199# if BB_MMU && !ENABLE_PLATFORM_MINGW32
198 /* MMU only */ 200 /* MMU only */
199 /* a->noexec is true */ 201 /* a->noexec is true */
200 rc = fork(); 202 rc = fork();
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index 3a0dc2653..ee54898e3 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -98,15 +98,15 @@ len_and_sockaddr* FAST_FUNC get_peer_lsa(int fd)
98 return get_lsa(fd, getpeername); 98 return get_lsa(fd, getpeername);
99} 99}
100 100
101void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) 101void FAST_FUNC xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen)
102{ 102{
103 if (connect(s, s_addr, addrlen) < 0) { 103 if (connect(s, saddr, addrlen) < 0) {
104 if (ENABLE_FEATURE_CLEAN_UP) 104 if (ENABLE_FEATURE_CLEAN_UP)
105 close(s); 105 close(s);
106 if (s_addr->sa_family == AF_INET) 106 if (saddr->sa_family == AF_INET)
107 bb_perror_msg_and_die("%s (%s)", 107 bb_perror_msg_and_die("%s (%s)",
108 "can't connect to remote host", 108 "can't connect to remote host",
109 inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr)); 109 inet_ntoa(((struct sockaddr_in *)saddr)->sin_addr));
110 bb_perror_msg_and_die("can't connect to remote host"); 110 bb_perror_msg_and_die("can't connect to remote host");
111 } 111 }
112} 112}
@@ -353,6 +353,10 @@ int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, int family, int sock_type)
353#if ENABLE_FEATURE_IPV6 353#if ENABLE_FEATURE_IPV6
354 fd = socket(AF_INET6, sock_type, 0); 354 fd = socket(AF_INET6, sock_type, 0);
355 if (fd >= 0) { 355 if (fd >= 0) {
356#if ENABLE_PLATFORM_MINGW32
357 DWORD buffer = 0;
358 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &buffer, sizeof(DWORD));
359#endif
356 family = AF_INET6; 360 family = AF_INET6;
357 goto done; 361 goto done;
358 } 362 }
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 }