aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Kbuild.src56
-rw-r--r--libbb/appletlib.c195
-rw-r--r--libbb/bb_qsort.c12
-rw-r--r--libbb/compare_string_array.c41
-rw-r--r--libbb/copy_file.c6
-rw-r--r--libbb/executable.c14
-rw-r--r--libbb/find_mount_point.c45
-rw-r--r--libbb/find_pid_by_name.c6
-rw-r--r--libbb/get_last_path_component.c28
-rw-r--r--libbb/get_line_from_file.c4
-rw-r--r--libbb/human_readable.c6
-rw-r--r--libbb/inode_hash.c5
-rw-r--r--libbb/lineedit.c126
-rw-r--r--libbb/make_directory.c8
-rw-r--r--libbb/messages.c2
-rw-r--r--libbb/mode_string.c2
-rw-r--r--libbb/parse_config.c4
-rw-r--r--libbb/printable_string.c2
-rw-r--r--libbb/procps.c3
-rw-r--r--libbb/read_printf.c5
-rw-r--r--libbb/u_signal_names.c4
-rw-r--r--libbb/vfork_daemon_rexec.c6
-rw-r--r--libbb/xatonum_template.c5
-rw-r--r--libbb/xconnect.c14
-rw-r--r--libbb/xfuncs.c4
-rw-r--r--libbb/xfuncs_printf.c2
-rw-r--r--libbb/xreadlink.c2
27 files changed, 558 insertions, 49 deletions
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 8c9ba8cca..799f6d01a 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -12,14 +12,11 @@ INSERT
12 12
13lib-y += appletlib.o 13lib-y += appletlib.o
14lib-y += ask_confirmation.o 14lib-y += ask_confirmation.o
15lib-y += bb_askpass.o
16lib-y += bb_bswap_64.o 15lib-y += bb_bswap_64.o
17lib-y += bb_do_delay.o
18lib-y += bb_pwd.o 16lib-y += bb_pwd.o
19lib-y += bb_qsort.o 17lib-y += bb_qsort.o
20#lib-y += bb_strtod.o 18#lib-y += bb_strtod.o
21lib-y += bb_strtonum.o 19lib-y += bb_strtonum.o
22lib-y += change_identity.o
23lib-y += chomp.o 20lib-y += chomp.o
24lib-y += compare_string_array.o 21lib-y += compare_string_array.o
25lib-y += concat_path_file.o 22lib-y += concat_path_file.o
@@ -28,32 +25,23 @@ lib-y += copy_file.o
28lib-y += copyfd.o 25lib-y += copyfd.o
29lib-y += crc32.o 26lib-y += crc32.o
30lib-y += default_error_retval.o 27lib-y += default_error_retval.o
31lib-y += device_open.o
32lib-y += dump.o 28lib-y += dump.o
33lib-y += executable.o 29lib-y += executable.o
34lib-y += fclose_nonstdin.o 30lib-y += fclose_nonstdin.o
35lib-y += fflush_stdout_and_exit.o 31lib-y += fflush_stdout_and_exit.o
36lib-y += fgets_str.o 32lib-y += fgets_str.o
37lib-y += find_pid_by_name.o 33lib-y += find_pid_by_name.o
38lib-y += find_root_device.o
39lib-y += full_write.o 34lib-y += full_write.o
40lib-y += get_console.o
41lib-y += get_last_path_component.o 35lib-y += get_last_path_component.o
42lib-y += get_line_from_file.o 36lib-y += get_line_from_file.o
43lib-y += getpty.o 37lib-y += getopt32.o
44lib-y += get_volsize.o
45lib-y += herror_msg.o 38lib-y += herror_msg.o
46lib-y += human_readable.o 39lib-y += human_readable.o
47lib-y += inet_common.o
48lib-y += inode_hash.o
49lib-y += isdirectory.o 40lib-y += isdirectory.o
50lib-y += kernel_version.o
51lib-y += last_char_is.o 41lib-y += last_char_is.o
52lib-y += lineedit.o lineedit_ptr_hack.o 42lib-y += lineedit.o lineedit_ptr_hack.o
53lib-y += llist.o 43lib-y += llist.o
54lib-y += login.o
55lib-y += make_directory.o 44lib-y += make_directory.o
56lib-y += makedev.o
57lib-y += hash_md5_sha.o 45lib-y += hash_md5_sha.o
58# Alternative (disabled) MD5 implementation 46# Alternative (disabled) MD5 implementation
59#lib-y += hash_md5prime.o 47#lib-y += hash_md5prime.o
@@ -61,20 +49,15 @@ lib-y += messages.o
61lib-y += mode_string.o 49lib-y += mode_string.o
62lib-y += parse_mode.o 50lib-y += parse_mode.o
63lib-y += perror_msg.o 51lib-y += perror_msg.o
64lib-y += perror_nomsg.o
65lib-y += perror_nomsg_and_die.o 52lib-y += perror_nomsg_and_die.o
66lib-y += pidfile.o
67lib-y += platform.o 53lib-y += platform.o
68lib-y += printable.o 54lib-y += printable.o
69lib-y += printable_string.o 55lib-y += printable_string.o
70lib-y += print_flags.o
71lib-y += process_escape_sequence.o 56lib-y += process_escape_sequence.o
72lib-y += procps.o 57lib-y += procps.o
73lib-y += progress.o
74lib-y += ptr_to_globals.o 58lib-y += ptr_to_globals.o
75lib-y += read.o 59lib-y += read.o
76lib-y += read_printf.o 60lib-y += read_printf.o
77lib-y += read_key.o
78lib-y += recursive_action.o 61lib-y += recursive_action.o
79lib-y += remove_file.o 62lib-y += remove_file.o
80lib-y += run_shell.o 63lib-y += run_shell.o
@@ -83,12 +66,8 @@ lib-y += safe_poll.o
83lib-y += safe_strncpy.o 66lib-y += safe_strncpy.o
84lib-y += safe_write.o 67lib-y += safe_write.o
85lib-y += securetty.o 68lib-y += securetty.o
86lib-y += setup_environment.o
87lib-y += signals.o
88lib-y += simplify_path.o
89lib-y += single_argv.o 69lib-y += single_argv.o
90lib-y += skip_whitespace.o 70lib-y += skip_whitespace.o
91lib-y += speed_table.o
92lib-y += str_tolower.o 71lib-y += str_tolower.o
93lib-y += strrstr.o 72lib-y += strrstr.o
94lib-y += sysconf.o 73lib-y += sysconf.o
@@ -98,20 +77,45 @@ lib-y += u_signal_names.o
98lib-y += uuencode.o 77lib-y += uuencode.o
99lib-y += verror_msg.o 78lib-y += verror_msg.o
100lib-y += vfork_daemon_rexec.o 79lib-y += vfork_daemon_rexec.o
101lib-y += warn_ignoring_args.o
102lib-y += wfopen.o 80lib-y += wfopen.o
103lib-y += wfopen_input.o 81lib-y += wfopen_input.o
104lib-y += write.o
105lib-y += xatonum.o 82lib-y += xatonum.o
106lib-y += xconnect.o 83lib-y += xconnect.o
107lib-y += xfuncs.o 84lib-y += xfuncs.o
108lib-y += xfuncs_printf.o 85lib-y += xfuncs_printf.o
109lib-y += xfunc_die.o 86lib-y += xfunc_die.o
110lib-y += xgetcwd.o 87lib-y += xgetcwd.o
111lib-y += xgethostbyname.o
112lib-y += xreadlink.o 88lib-y += xreadlink.o
113lib-y += xrealloc_vector.o 89lib-y += xrealloc_vector.o
114 90
91lib-$(CONFIG_PLATFORM_POSIX) += bb_askpass.o
92lib-$(CONFIG_PLATFORM_POSIX) += bb_do_delay.o
93lib-$(CONFIG_PLATFORM_POSIX) += change_identity.o
94lib-$(CONFIG_PLATFORM_POSIX) += device_open.o
95lib-$(CONFIG_PLATFORM_POSIX) += find_root_device.o
96lib-$(CONFIG_PLATFORM_POSIX) += get_console.o
97lib-$(CONFIG_PLATFORM_POSIX) += getpty.o
98lib-$(CONFIG_PLATFORM_POSIX) += get_volsize.o
99lib-$(CONFIG_PLATFORM_POSIX) += inet_common.o
100lib-$(CONFIG_PLATFORM_POSIX) += inode_hash.o
101lib-$(CONFIG_FEATURE_EXTRA_FILE_DATA) += inode_hash.o
102lib-$(CONFIG_PLATFORM_POSIX) += kernel_version.o
103lib-$(CONFIG_PLATFORM_POSIX) += login.o
104lib-$(CONFIG_PLATFORM_POSIX) += makedev.o
105lib-$(CONFIG_PLATFORM_POSIX) += perror_nomsg.o
106lib-$(CONFIG_PLATFORM_POSIX) += pidfile.o
107lib-$(CONFIG_PLATFORM_POSIX) += print_flags.o
108lib-$(CONFIG_PLATFORM_POSIX) += progress.o
109lib-$(CONFIG_PLATFORM_POSIX) += read_key.o
110lib-$(CONFIG_PLATFORM_POSIX) += setup_environment.o
111lib-$(CONFIG_PLATFORM_POSIX) += signals.o
112lib-$(CONFIG_PLATFORM_POSIX) += simplify_path.o
113lib-$(CONFIG_PLATFORM_POSIX) += speed_table.o
114lib-$(CONFIG_PLATFORM_POSIX) += udp_io.o
115lib-$(CONFIG_PLATFORM_POSIX) += warn_ignoring_args.o
116lib-$(CONFIG_PLATFORM_POSIX) += write.o
117lib-$(CONFIG_PLATFORM_POSIX) += xgethostbyname.o
118
115lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o 119lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o
116 120
117lib-$(CONFIG_FEATURE_UTMP) += utmp.o 121lib-$(CONFIG_FEATURE_UTMP) += utmp.o
@@ -123,7 +127,7 @@ lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o
123lib-$(CONFIG_UNICODE_SUPPORT) += unicode.o 127lib-$(CONFIG_UNICODE_SUPPORT) += unicode.o
124lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o 128lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o
125 129
126lib-$(CONFIG_NC) += udp_io.o 130lib-$(CONFIG_NC_110_COMPAT) += udp_io.o
127lib-$(CONFIG_NETCAT) += udp_io.o 131lib-$(CONFIG_NETCAT) += udp_io.o
128lib-$(CONFIG_DNSD) += udp_io.o 132lib-$(CONFIG_DNSD) += udp_io.o
129lib-$(CONFIG_NTPD) += udp_io.o 133lib-$(CONFIG_NTPD) += udp_io.o
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index f842e73cc..17ce463ea 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -48,6 +48,15 @@
48# define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ 48# define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__
49#endif 49#endif
50 50
51#if (ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32) || \
52 (ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \
53 || ENABLE_FEATURE_SH_STANDALONE \
54 || ENABLE_FEATURE_SH_NOFORK))
55# define IF_FULL_LIST_OPTION(...) __VA_ARGS__
56#else
57# define IF_FULL_LIST_OPTION(...)
58#endif
59
51#include "usage_compressed.h" 60#include "usage_compressed.h"
52 61
53#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS 62#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
@@ -57,6 +66,7 @@
57# define NUM_SCRIPTS 0 66# define NUM_SCRIPTS 0
58#endif 67#endif
59#if NUM_SCRIPTS > 0 68#if NUM_SCRIPTS > 0
69# define BB_ARCHIVE_PUBLIC
60# include "bb_archive.h" 70# include "bb_archive.h"
61static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; 71static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS };
62#endif 72#endif
@@ -106,6 +116,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE;
106#if ENABLE_FEATURE_COMPRESS_USAGE 116#if ENABLE_FEATURE_COMPRESS_USAGE
107 117
108static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 118static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
119# define BB_ARCHIVE_PUBLIC
109# include "bb_archive.h" 120# include "bb_archive.h"
110# define unpack_usage_messages() \ 121# define unpack_usage_messages() \
111 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) 122 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE))
@@ -149,7 +160,11 @@ void FAST_FUNC bb_show_usage(void)
149 ap--; 160 ap--;
150 } 161 }
151 full_write2_str(bb_banner); 162 full_write2_str(bb_banner);
163#if ENABLE_PLATFORM_MINGW32
164 full_write2_str(" multi-call binary\n");
165#else
152 full_write2_str(" multi-call binary.\n"); /* common string */ 166 full_write2_str(" multi-call binary.\n"); /* common string */
167#endif
153 if (*p == '\b') 168 if (*p == '\b')
154 full_write2_str("\nNo help available\n"); 169 full_write2_str("\nNo help available\n");
155 else { 170 else {
@@ -312,6 +327,10 @@ void lbb_prepare(const char *applet
312 if (ENABLE_LOCALE_SUPPORT) 327 if (ENABLE_LOCALE_SUPPORT)
313 setlocale(LC_ALL, ""); 328 setlocale(LC_ALL, "");
314 329
330#if ENABLE_PLATFORM_MINGW32
331 init_winsock();
332#endif
333
315#if ENABLE_FEATURE_INDIVIDUAL 334#if ENABLE_FEATURE_INDIVIDUAL
316 /* Redundant for busybox (run_applet_and_exit covers that case) 335 /* Redundant for busybox (run_applet_and_exit covers that case)
317 * but needed for "individual applet" mode */ 336 * but needed for "individual applet" mode */
@@ -702,6 +721,7 @@ static void check_suid(int applet_no)
702 721
703 722
704# if ENABLE_FEATURE_INSTALLER 723# if ENABLE_FEATURE_INSTALLER
724# if !ENABLE_PLATFORM_MINGW32
705static const char usr_bin [] ALIGN1 = "/usr/bin/"; 725static const char usr_bin [] ALIGN1 = "/usr/bin/";
706static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; 726static const char usr_sbin[] ALIGN1 = "/usr/sbin/";
707static const char *const install_dir[] = { 727static const char *const install_dir[] = {
@@ -746,6 +766,30 @@ static void install_links(const char *busybox, int use_symbolic_links,
746 continue; 766 continue;
747 } 767 }
748} 768}
769# else /* ENABLE_PLATFORM_MINGW32 */
770static void install_links(const char *busybox,
771 int use_symbolic_links UNUSED_PARAM, char *custom_install_dir)
772{
773 char *fpc;
774 const char *appname = applet_names;
775 int rc;
776
777 if (!is_directory(custom_install_dir, FALSE))
778 bb_error_msg_and_die("'%s' is not a directory", custom_install_dir);
779
780 while (*appname) {
781 fpc = xasprintf("%s/%s.exe", custom_install_dir, appname);
782 rc = link(busybox, fpc);
783 if (rc != 0 && (errno != EEXIST ||
784 strcmp("busybox.exe", bb_basename(fpc)) != 0)) {
785 bb_simple_perror_msg(fpc);
786 }
787 free(fpc);
788 while (*appname++ != '\0')
789 continue;
790 }
791}
792# endif
749# elif ENABLE_BUSYBOX 793# elif ENABLE_BUSYBOX
750static void install_links(const char *busybox UNUSED_PARAM, 794static void install_links(const char *busybox UNUSED_PARAM,
751 int use_symbolic_links UNUSED_PARAM, 795 int use_symbolic_links UNUSED_PARAM,
@@ -830,20 +874,35 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
830 874
831 dup2(1, 2); 875 dup2(1, 2);
832 full_write2_str(bb_banner); /* reuse const string */ 876 full_write2_str(bb_banner); /* reuse const string */
877#if ENABLE_PLATFORM_MINGW32
878 full_write2_str(" multi-call binary\n"); /* reuse */
879#else
833 full_write2_str(" multi-call binary.\n"); /* reuse */ 880 full_write2_str(" multi-call binary.\n"); /* reuse */
881#endif
882#if defined(MINGW_VER)
883 if (sizeof(MINGW_VER) > 5) {
884 full_write2_str(MINGW_VER "\n\n");
885 }
886#endif
834 full_write2_str( 887 full_write2_str(
835 "BusyBox is copyrighted by many authors between 1998-2015.\n" 888 "BusyBox is copyrighted by many authors between 1998-2020.\n"
836 "Licensed under GPLv2. See source distribution for detailed\n" 889 "Licensed under GPLv2. See source distribution for detailed\n"
837 "copyright notices.\n" 890 "copyright notices.\n"
838 "\n" 891 "\n"
839 "Usage: busybox [function [arguments]...]\n" 892 "Usage: busybox [function [arguments]...]\n"
840 " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" 893 " or: busybox --list"IF_FULL_LIST_OPTION("[-full]")"\n"
841# if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0 894# if ENABLE_FEATURE_SHOW_SCRIPT && NUM_SCRIPTS > 0
842 " or: busybox --show SCRIPT\n" 895 " or: busybox --show SCRIPT\n"
843# endif 896# endif
844 IF_FEATURE_INSTALLER( 897 IF_FEATURE_INSTALLER(
898 IF_NOT_PLATFORM_MINGW32(
845 " or: busybox --install [-s] [DIR]\n" 899 " or: busybox --install [-s] [DIR]\n"
846 ) 900 )
901 IF_PLATFORM_MINGW32(
902 " or: busybox --install [DIR]\n"
903 " or: busybox --uninstall [-n] file\n"
904 )
905 )
847 " or: function [arguments]...\n" 906 " or: function [arguments]...\n"
848 "\n" 907 "\n"
849 IF_NOT_FEATURE_SH_STANDALONE( 908 IF_NOT_FEATURE_SH_STANDALONE(
@@ -860,6 +919,11 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
860 "\tTo run external program, use full path (/sbin/ip instead of ip).\n" 919 "\tTo run external program, use full path (/sbin/ip instead of ip).\n"
861 ) 920 )
862 "\n" 921 "\n"
922#if ENABLE_GLOBBING
923 "\tSupport for native Windows wildcards is enabled. In some\n"
924 "\tcases this may result in wildcards being processed twice.\n"
925 "\n"
926#endif
863 "Currently defined functions:\n" 927 "Currently defined functions:\n"
864 ); 928 );
865 col = 0; 929 col = 0;
@@ -904,9 +968,27 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
904 const char *a = applet_names; 968 const char *a = applet_names;
905 dup2(1, 2); 969 dup2(1, 2);
906 while (*a) { 970 while (*a) {
907# if ENABLE_FEATURE_INSTALLER 971# if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32
908 if (argv[1][6]) /* --list-full? */ 972 if (argv[1][6]) /* --list-full? */
909 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); 973 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
974# elif ENABLE_PLATFORM_MINGW32 && (ENABLE_FEATURE_PREFER_APPLETS \
975 || ENABLE_FEATURE_SH_STANDALONE \
976 || ENABLE_FEATURE_SH_NOFORK)
977 if (argv[1][6]) { /* --list-full? */
978 const char *str;
979
980 if (APPLET_IS_NOFORK(i))
981 str = "NOFORK ";
982 else if (APPLET_IS_NOEXEC(i))
983 str = "noexec ";
984# if NUM_SCRIPTS > 0
985 else if (applet_main[i] == scripted_main)
986 str = "script ";
987# endif
988 else
989 str = " ";
990 full_write2_str(str);
991 }
910# endif 992# endif
911 full_write2_str(a); 993 full_write2_str(a);
912 full_write2_str("\n"); 994 full_write2_str("\n");
@@ -918,6 +1000,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
918 } 1000 }
919 1001
920 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { 1002 if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) {
1003#if !ENABLE_PLATFORM_MINGW32
921 int use_symbolic_links; 1004 int use_symbolic_links;
922 const char *busybox; 1005 const char *busybox;
923 1006
@@ -938,9 +1021,40 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
938 */ 1021 */
939 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); 1022 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv);
940 install_links(busybox, use_symbolic_links, argv[2]); 1023 install_links(busybox, use_symbolic_links, argv[2]);
1024#else
1025 /* busybox --install [DIR]
1026 * where DIR is the directory to install to. If DIR is not
1027 * provided put the links in the same directory as busybox.
1028 */
1029 install_links(bb_busybox_exec_path, FALSE, argv[2] ? argv[2] :
1030 dirname(xstrdup(bb_busybox_exec_path)));
1031#endif
941 return 0; 1032 return 0;
942 } 1033 }
943 1034
1035#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_INSTALLER
1036 if (strcmp(argv[1], "--uninstall") == 0) {
1037 char name[PATH_MAX];
1038 int dry_run = (argv[2] && strcmp(argv[2], "-n") == 0 && ++argv);
1039 const char *file = argv[2];
1040
1041 if (!argv[2])
1042 bb_error_msg_and_die(bb_msg_requires_arg, "--uninstall");
1043
1044 while (enumerate_links(file, name)) {
1045 if (dry_run) {
1046 full_write1_str(name);
1047 full_write1_str("\n");
1048 }
1049 else if (unlink(name) != 0) {
1050 bb_simple_perror_msg(name);
1051 }
1052 file = NULL;
1053 }
1054 return 0;
1055 }
1056#endif
1057
944 if (strcmp(argv[1], "--help") == 0) { 1058 if (strcmp(argv[1], "--help") == 0) {
945 /* "busybox --help [<applet>]" */ 1059 /* "busybox --help [<applet>]" */
946 if (!argv[2]) 1060 if (!argv[2])
@@ -960,15 +1074,42 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
960# endif 1074# endif
961 1075
962# if NUM_APPLETS > 0 1076# if NUM_APPLETS > 0
1077
1078# if ENABLE_PLATFORM_MINGW32
1079static int interp = 0;
1080char bb_comm[COMM_LEN];
1081char bb_command_line[128];
1082# endif
1083
963void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) 1084void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv)
964{ 1085{
965 int argc = string_array_len(argv); 1086 int argc = string_array_len(argv);
1087# if ENABLE_PLATFORM_MINGW32
1088 int i;
1089 const char *vmask;
1090 unsigned int mask;
1091# endif
966 1092
967 /* 1093 /*
968 * We do not use argv[0]: do not want to repeat massaging of 1094 * We do not use argv[0]: do not want to repeat massaging of
969 * "-/sbin/halt" -> "halt", for example. 1095 * "-/sbin/halt" -> "halt", for example.
970 */ 1096 */
971 applet_name = name; 1097 applet_name = name;
1098# if ENABLE_PLATFORM_MINGW32
1099 safe_strncpy(bb_comm,
1100 interp ? bb_basename(argv[interp]) : applet_name,
1101 sizeof(bb_comm));
1102
1103 safe_strncpy(bb_command_line, applet_name, sizeof(bb_command_line));
1104 for (i=1; i < argc && argv[i] &&
1105 strlen(bb_command_line) + strlen(argv[i]) + 2 < 128; ++i) {
1106 strcat(strcat(bb_command_line, " "), argv[i]);
1107 }
1108
1109 vmask = getenv("BB_UMASK");
1110 if (vmask && sscanf(vmask, "%o", &mask) == 1)
1111 umask((mode_t)(mask&0777));
1112# endif
972 1113
973 /* Special case. POSIX says "test --help" 1114 /* Special case. POSIX says "test --help"
974 * should be no different from e.g. "test --foo". 1115 * should be no different from e.g. "test --foo".
@@ -994,6 +1135,7 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
994 } 1135 }
995 if (ENABLE_FEATURE_SUID) 1136 if (ENABLE_FEATURE_SUID)
996 check_suid(applet_no); 1137 check_suid(applet_no);
1138
997 xfunc_error_retval = applet_main[applet_no](argc, argv); 1139 xfunc_error_retval = applet_main[applet_no](argc, argv);
998 /* Note: applet_main() may also not return (die on a xfunc or such) */ 1140 /* Note: applet_main() may also not return (die on a xfunc or such) */
999 xfunc_die(); 1141 xfunc_die();
@@ -1076,6 +1218,38 @@ int main(int argc UNUSED_PARAM, char **argv)
1076 argv[0][0] &= 0x7f; 1218 argv[0][0] &= 0x7f;
1077 } 1219 }
1078#endif 1220#endif
1221#if ENABLE_PLATFORM_MINGW32
1222 /* detect if we're running an interpreted script */
1223 if (argv[0][1] == ':' && argv[0][2] == '/') {
1224 switch (argv[0][0]) {
1225 case '2':
1226 ++interp;
1227 /* fall through */
1228 case '1':
1229 ++interp;
1230 argv[0] += 3;
1231 break;
1232 }
1233 }
1234# if ENABLE_FEATURE_EURO
1235 init_codepage();
1236# endif
1237 /* Ignore critical errors, such as calling GetVolumeInformation() on
1238 * a floppy or CDROM drive with no media. */
1239 SetErrorMode(SEM_FAILCRITICALERRORS);
1240#endif
1241
1242#if defined(__MINGW64_VERSION_MAJOR)
1243 if ( stdin ) {
1244 _setmode(fileno(stdin), _O_BINARY);
1245 }
1246 if ( stdout ) {
1247 _setmode(fileno(stdout), _O_BINARY);
1248 }
1249 if ( stderr ) {
1250 _setmode(fileno(stderr), _O_BINARY);
1251 }
1252#endif
1079 1253
1080#if defined(SINGLE_APPLET_MAIN) 1254#if defined(SINGLE_APPLET_MAIN)
1081 1255
@@ -1108,6 +1282,21 @@ int main(int argc UNUSED_PARAM, char **argv)
1108 applet_name = argv[0]; 1282 applet_name = argv[0];
1109 if (applet_name[0] == '-') 1283 if (applet_name[0] == '-')
1110 applet_name++; 1284 applet_name++;
1285# if ENABLE_PLATFORM_MINGW32
1286 if ( argv[1] && argv[2] && strcmp(argv[1], "--busybox") == 0 ) {
1287 argv += 2;
1288 applet_name = argv[0];
1289 }
1290 else {
1291 char *s;
1292
1293 str_tolower(argv[0]);
1294 bs_to_slash(argv[0]);
1295 if (has_exe_suffix_or_dot(argv[0]) && (s=strrchr(argv[0], '.'))) {
1296 *s = '\0';
1297 }
1298 }
1299# endif
1111 applet_name = bb_basename(applet_name); 1300 applet_name = bb_basename(applet_name);
1112 1301
1113 /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */ 1302 /* If we are a result of execv("/proc/self/exe"), fix ugly comm of "exe" */
diff --git a/libbb/bb_qsort.c b/libbb/bb_qsort.c
index 505045533..7afddf468 100644
--- a/libbb/bb_qsort.c
+++ b/libbb/bb_qsort.c
@@ -17,3 +17,15 @@ void FAST_FUNC qsort_string_vector(char **sv, unsigned count)
17{ 17{
18 qsort(sv, count, sizeof(char*), bb_pstrcmp); 18 qsort(sv, count, sizeof(char*), bb_pstrcmp);
19} 19}
20
21#if ENABLE_PLATFORM_MINGW32
22static int bb_pstrcasecmp(const void *a, const void *b)
23{
24 return strcasecmp(*(char**)a, *(char**)b);
25}
26
27void FAST_FUNC qsort_string_vector_case(char **sv, unsigned count)
28{
29 qsort(sv, count, sizeof(char*), bb_pstrcasecmp);
30}
31#endif
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
index 01a9df0e2..856739c41 100644
--- a/libbb/compare_string_array.c
+++ b/libbb/compare_string_array.c
@@ -27,11 +27,25 @@ char* FAST_FUNC is_prefixed_with(const char *string, const char *key)
27#endif 27#endif
28} 28}
29 29
30#if ENABLE_PLATFORM_MINGW32
31char* FAST_FUNC is_prefixed_with_case(const char *string, const char *key)
32{
33 while (*key != '\0') {
34 if (tolower(*key) != tolower(*string))
35 return NULL;
36 key++;
37 string++;
38 }
39 return (char*)string;
40}
41#endif
42
30/* 43/*
31 * Return NULL if string is not suffixed with key. Return pointer to the 44 * Return NULL if string is not suffixed with key. Return pointer to the
32 * beginning of prefix key in string. If key is an empty string return pointer 45 * beginning of prefix key in string. If key is an empty string return pointer
33 * to the end of string. 46 * to the end of string.
34 */ 47 */
48#if !ENABLE_PLATFORM_MINGW32
35char* FAST_FUNC is_suffixed_with(const char *string, const char *key) 49char* FAST_FUNC is_suffixed_with(const char *string, const char *key)
36{ 50{
37 size_t key_len = strlen(key); 51 size_t key_len = strlen(key);
@@ -46,6 +60,33 @@ char* FAST_FUNC is_suffixed_with(const char *string, const char *key)
46 60
47 return NULL; 61 return NULL;
48} 62}
63#else
64static char* FAST_FUNC is_suffixed(const char *string, const char *key,
65 int (*fn)(const char *, const char*))
66{
67 size_t key_len = strlen(key);
68 ssize_t len_diff = strlen(string) - key_len;
69
70 if (len_diff >= 0) {
71 string += len_diff;
72 if (fn(string, key) == 0) {
73 return (char*)string;
74 }
75 }
76
77 return NULL;
78}
79
80char* FAST_FUNC is_suffixed_with(const char *string, const char *key)
81{
82 return is_suffixed(string, key, strcmp);
83}
84
85char* FAST_FUNC is_suffixed_with_case(const char *string, const char *key)
86{
87 return is_suffixed(string, key, strcasecmp);
88}
89#endif
49 90
50/* returns the array index of the string */ 91/* returns the array index of the string */
51/* (index of first match is returned, or -1) */ 92/* (index of first match is returned, or -1) */
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 49d1ec9c6..9b10dda1f 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -105,12 +105,18 @@ 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_POSIX || ENABLE_FEATURE_EXTRA_FILE_DATA
108 if (source_stat.st_dev == dest_stat.st_dev 109 if (source_stat.st_dev == dest_stat.st_dev
109 && source_stat.st_ino == dest_stat.st_ino 110 && source_stat.st_ino == dest_stat.st_ino
111# if ENABLE_FEATURE_EXTRA_FILE_DATA
112 /* ignore invalid inode numbers */
113 && source_stat.st_ino != 0
114# endif
110 ) { 115 ) {
111 bb_error_msg("'%s' and '%s' are the same file", source, dest); 116 bb_error_msg("'%s' and '%s' are the same file", source, dest);
112 return -1; 117 return -1;
113 } 118 }
119#endif
114 dest_exists = 1; 120 dest_exists = 1;
115 } 121 }
116 122
diff --git a/libbb/executable.c b/libbb/executable.c
index 29d2a2c85..87a40eeda 100644
--- a/libbb/executable.c
+++ b/libbb/executable.c
@@ -39,19 +39,29 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp)
39 * following the rest of the list. 39 * following the rest of the list.
40 */ 40 */
41 char *p, *n; 41 char *p, *n;
42#if ENABLE_PLATFORM_MINGW32
43 char *w;
44#endif
42 45
43 p = *PATHp; 46 p = *PATHp;
44 while (p) { 47 while (p) {
45 int ex; 48 int ex;
46 49
47 n = strchr(p, ':'); 50 n = strchr(p, PATH_SEP);
48 if (n) *n = '\0'; 51 if (n) *n = '\0';
49 p = concat_path_file( 52 p = concat_path_file(
50 p[0] ? p : ".", /* handle "::" case */ 53 p[0] ? p : ".", /* handle "::" case */
51 filename 54 filename
52 ); 55 );
56 if (n) *n++ = PATH_SEP;
57#if ENABLE_PLATFORM_MINGW32
58 if ((w=alloc_win32_extension(p))) {
59 free(p);
60 p = w;
61 /* following test will succeed */
62 }
63#endif
53 ex = file_is_executable(p); 64 ex = file_is_executable(p);
54 if (n) *n++ = ':';
55 if (ex) { 65 if (ex) {
56 *PATHp = n; 66 *PATHp = n;
57 return p; 67 return p;
diff --git a/libbb/find_mount_point.c b/libbb/find_mount_point.c
index 0e1be3820..edf734614 100644
--- a/libbb/find_mount_point.c
+++ b/libbb/find_mount_point.c
@@ -19,14 +19,28 @@
19struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) 19struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too)
20{ 20{
21 struct stat s; 21 struct stat s;
22 FILE *mtab_fp;
23 struct mntent *mountEntry; 22 struct mntent *mountEntry;
23#if !ENABLE_PLATFORM_MINGW32
24 FILE *mtab_fp;
24 dev_t devno_of_name; 25 dev_t devno_of_name;
25 bool block_dev; 26 bool block_dev;
27#else
28 static char mnt_fsname[4];
29 static char mnt_dir[4];
30 static char mnt_type[1];
31 static char mnt_opts[1];
32 static struct mntent my_mount_entry = {
33 mnt_fsname, mnt_dir, mnt_type, mnt_opts, 0, 0
34 };
35 char *current;
36 const char *path;
37 DWORD len;
38#endif
26 39
27 if (stat(name, &s) != 0) 40 if (stat(name, &s) != 0)
28 return NULL; 41 return NULL;
29 42
43#if !ENABLE_PLATFORM_MINGW32
30 devno_of_name = s.st_dev; 44 devno_of_name = s.st_dev;
31 block_dev = 0; 45 block_dev = 0;
32 /* Why S_ISCHR? - UBI volumes use char devices, not block */ 46 /* Why S_ISCHR? - UBI volumes use char devices, not block */
@@ -74,6 +88,35 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too)
74 } 88 }
75 } 89 }
76 endmntent(mtab_fp); 90 endmntent(mtab_fp);
91#else
92 mountEntry = NULL;
93 path = NULL;
94 current = NULL;
95
96 if ( isalpha(name[0]) && name[1] == ':' ) {
97 path = name;
98 }
99 else {
100 if ( (len=GetCurrentDirectory(0, NULL)) > 0 &&
101 (current=malloc(len+1)) != NULL &&
102 GetCurrentDirectory(len, current) ) {
103 path = current;
104 }
105 }
106
107 if ( path && isalpha(path[0]) && path[1] == ':' ) {
108 mnt_fsname[0] = path[0];
109 mnt_fsname[1] = path[1];
110 mnt_fsname[2] = '\0';
111 mnt_dir[0] = path[0];
112 mnt_dir[1] = path[1];
113 mnt_dir[2] = '\\';
114 mnt_dir[3] = '\0';
115
116 mountEntry = &my_mount_entry;
117 }
118 free(current);
119#endif
77 120
78 return mountEntry; 121 return mountEntry;
79} 122}
diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c
index fe13f7211..0b6d5a206 100644
--- a/libbb/find_pid_by_name.c
+++ b/libbb/find_pid_by_name.c
@@ -39,8 +39,10 @@ and therefore comm field contains "exe".
39 39
40static int comm_match(procps_status_t *p, const char *procName) 40static int comm_match(procps_status_t *p, const char *procName)
41{ 41{
42#if !ENABLE_PLATFORM_MINGW32
42 int argv1idx; 43 int argv1idx;
43 const char *argv1; 44 const char *argv1;
45#endif
44 46
45 if (strncmp(p->comm, procName, 15) != 0) 47 if (strncmp(p->comm, procName, 15) != 0)
46 return 0; /* comm does not match */ 48 return 0; /* comm does not match */
@@ -55,6 +57,7 @@ static int comm_match(procps_status_t *p, const char *procName)
55 * This can be crazily_long_script_name.sh! 57 * This can be crazily_long_script_name.sh!
56 * The telltale sign is basename(argv[1]) == procName */ 58 * The telltale sign is basename(argv[1]) == procName */
57 59
60#if !ENABLE_PLATFORM_MINGW32
58 if (!p->argv0) 61 if (!p->argv0)
59 return 0; 62 return 0;
60 63
@@ -65,6 +68,7 @@ static int comm_match(procps_status_t *p, const char *procName)
65 68
66 if (strcmp(bb_basename(argv1), procName) != 0) 69 if (strcmp(bb_basename(argv1), procName) != 0)
67 return 0; 70 return 0;
71#endif
68 72
69 return 1; 73 return 1;
70} 74}
@@ -87,6 +91,7 @@ pid_t* FAST_FUNC find_pid_by_name(const char *procName)
87 pidList = xzalloc(sizeof(*pidList)); 91 pidList = xzalloc(sizeof(*pidList));
88 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) { 92 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) {
89 if (comm_match(p, procName) 93 if (comm_match(p, procName)
94#if !ENABLE_PLATFORM_MINGW32
90 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ 95 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
91 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) 96 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
92 /* or we require /proc/PID/exe link to match */ 97 /* or we require /proc/PID/exe link to match */
@@ -95,6 +100,7 @@ pid_t* FAST_FUNC find_pid_by_name(const char *procName)
95 : bb_basename(p->exe), 100 : bb_basename(p->exe),
96 procName 101 procName
97 ) == 0) 102 ) == 0)
103#endif
98 ) { 104 ) {
99 pidList = xrealloc_vector(pidList, 2, i); 105 pidList = xrealloc_vector(pidList, 2, i);
100 pidList[i++] = p->pid; 106 pidList[i++] = p->pid;
diff --git a/libbb/get_last_path_component.c b/libbb/get_last_path_component.c
index 04fdf2a3e..3a9b9237e 100644
--- a/libbb/get_last_path_component.c
+++ b/libbb/get_last_path_component.c
@@ -10,9 +10,16 @@
10 10
11const char* FAST_FUNC bb_basename(const char *name) 11const char* FAST_FUNC bb_basename(const char *name)
12{ 12{
13#if ENABLE_PLATFORM_MINGW32
14 const char *cp;
15 for (cp = name; *cp; cp++)
16 if (*cp == '/' || *cp == '\\')
17 name = cp + 1;
18#else
13 const char *cp = strrchr(name, '/'); 19 const char *cp = strrchr(name, '/');
14 if (cp) 20 if (cp)
15 return cp + 1; 21 return cp + 1;
22#endif
16 return name; 23 return name;
17} 24}
18 25
@@ -26,8 +33,18 @@ char* FAST_FUNC bb_get_last_path_component_nostrip(const char *path)
26{ 33{
27 char *slash = strrchr(path, '/'); 34 char *slash = strrchr(path, '/');
28 35
36#if ENABLE_PLATFORM_MINGW32
37 const char *start = has_dos_drive_prefix(path) ? path+2 : path;
38
39 if (!slash)
40 slash = strrchr(path, '\\');
41
42 if (!slash || (slash == start && !slash[1]))
43 return (char*)path;
44#else
29 if (!slash || (slash == path && !slash[1])) 45 if (!slash || (slash == path && !slash[1]))
30 return (char*)path; 46 return (char*)path;
47#endif
31 48
32 return slash + 1; 49 return slash + 1;
33} 50}
@@ -42,9 +59,20 @@ char* FAST_FUNC bb_get_last_path_component_strip(char *path)
42{ 59{
43 char *slash = last_char_is(path, '/'); 60 char *slash = last_char_is(path, '/');
44 61
62#if ENABLE_PLATFORM_MINGW32
63 const char *start = has_dos_drive_prefix(path) ? path+2 : path;
64
65 if (!slash)
66 slash = last_char_is(path, '\\');
67
68 if (slash)
69 while ((*slash == '/' || *slash == '\\') && slash != start)
70 *slash-- = '\0';
71#else
45 if (slash) 72 if (slash)
46 while (*slash == '/' && slash != path) 73 while (*slash == '/' && slash != path)
47 *slash-- = '\0'; 74 *slash-- = '\0';
75#endif
48 76
49 return bb_get_last_path_component_nostrip(path); 77 return bb_get_last_path_component_nostrip(path);
50} 78}
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c
index 903ff1fb6..929bab78a 100644
--- a/libbb/get_line_from_file.c
+++ b/libbb/get_line_from_file.c
@@ -59,6 +59,10 @@ char* FAST_FUNC xmalloc_fgetline(FILE *file)
59 59
60 if (i && c[--i] == '\n') 60 if (i && c[--i] == '\n')
61 c[i] = '\0'; 61 c[i] = '\0';
62#if ENABLE_PLATFORM_MINGW32
63 if (i && c[--i] == '\r')
64 c[i] = '\0';
65#endif
62 66
63 return c; 67 return c;
64} 68}
diff --git a/libbb/human_readable.c b/libbb/human_readable.c
index 09221a186..3199ede6e 100644
--- a/libbb/human_readable.c
+++ b/libbb/human_readable.c
@@ -38,7 +38,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val,
38 if (val == 0) 38 if (val == 0)
39 return "0"; 39 return "0";
40 40
41 fmt = "%llu"; 41 fmt = "%"LL_FMT"u";
42 if (block_size > 1) 42 if (block_size > 1)
43 val *= block_size; 43 val *= block_size;
44 frac = 0; 44 frac = 0;
@@ -52,7 +52,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val,
52 while ((val >= 1024) 52 while ((val >= 1024)
53 /* && (u < unit_chars + sizeof(unit_chars) - 1) - always true */ 53 /* && (u < unit_chars + sizeof(unit_chars) - 1) - always true */
54 ) { 54 ) {
55 fmt = "%llu.%u%c"; 55 fmt = "%"LL_FMT"u.%u%c";
56 u++; 56 u++;
57 frac = (((unsigned)val % 1024) * 10 + 1024/2) / 1024; 57 frac = (((unsigned)val % 1024) * 10 + 1024/2) / 1024;
58 val /= 1024; 58 val /= 1024;
@@ -67,7 +67,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val,
67 if (frac >= 5) { 67 if (frac >= 5) {
68 ++val; 68 ++val;
69 } 69 }
70 fmt = "%llu%*c"; 70 fmt = "%"LL_FMT"u%*c";
71 frac = 1; 71 frac = 1;
72 } 72 }
73#endif 73#endif
diff --git a/libbb/inode_hash.c b/libbb/inode_hash.c
index a125244ca..f2cc417bc 100644
--- a/libbb/inode_hash.c
+++ b/libbb/inode_hash.c
@@ -61,6 +61,11 @@ void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char *
61 int i; 61 int i;
62 ino_dev_hashtable_bucket_t *bucket; 62 ino_dev_hashtable_bucket_t *bucket;
63 63
64#if ENABLE_FEATURE_EXTRA_FILE_DATA
65 /* ignore invalid inode numbers */
66 if (statbuf->st_ino == 0)
67 return;
68#endif
64 if (!name) 69 if (!name)
65 name = ""; 70 name = "";
66 bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + strlen(name)); 71 bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + strlen(name));
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index de236dea0..14eb16873 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -363,7 +363,7 @@ int adjust_width_and_validate_wc(unsigned *width_adj, int wc);
363/* Put 'command_ps[cursor]', cursor++. 363/* Put 'command_ps[cursor]', cursor++.
364 * Advance cursor on screen. If we reached right margin, scroll text up 364 * Advance cursor on screen. If we reached right margin, scroll text up
365 * and remove terminal margin effect by printing 'next_char' */ 365 * and remove terminal margin effect by printing 'next_char' */
366#define HACK_FOR_WRONG_WIDTH 1 366#define HACK_FOR_WRONG_WIDTH 1 && !ENABLE_PLATFORM_MINGW32
367static void put_cur_glyph_and_inc_cursor(void) 367static void put_cur_glyph_and_inc_cursor(void)
368{ 368{
369 CHAR_T c = command_ps[cursor]; 369 CHAR_T c = command_ps[cursor];
@@ -426,6 +426,42 @@ static void put_cur_glyph_and_inc_cursor(void)
426 } 426 }
427} 427}
428 428
429#if ENABLE_PLATFORM_MINGW32
430static void inc_cursor(void)
431{
432 CHAR_T c = command_ps[cursor];
433 unsigned width = 0;
434 int ofs_to_right;
435
436 /* advance cursor */
437 cursor++;
438 if (unicode_status == UNICODE_ON) {
439 IF_UNICODE_WIDE_WCHARS(width = cmdedit_x;)
440 c = adjust_width_and_validate_wc(&cmdedit_x, c);
441 IF_UNICODE_WIDE_WCHARS(width = cmdedit_x - width;)
442 } else {
443 cmdedit_x++;
444 }
445
446 ofs_to_right = cmdedit_x - cmdedit_termw;
447 if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right <= 0) {
448 /* cursor remains on this line */
449 printf(ESC"[1C");
450 }
451
452 if (ofs_to_right >= 0) {
453 /* we go to the next line */
454 printf(ESC"[1B");
455 bb_putchar('\r');
456 cmdedit_y++;
457 if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) {
458 width = 0;
459 }
460 cmdedit_x = width;
461 }
462}
463#endif
464
429/* Move to end of line (by printing all chars till the end) */ 465/* Move to end of line (by printing all chars till the end) */
430static void put_till_end_and_adv_cursor(void) 466static void put_till_end_and_adv_cursor(void)
431{ 467{
@@ -485,6 +521,7 @@ static void input_backward(unsigned num)
485 521
486 if (cmdedit_x >= num) { 522 if (cmdedit_x >= num) {
487 cmdedit_x -= num; 523 cmdedit_x -= num;
524#if !ENABLE_PLATFORM_MINGW32
488 if (num <= 4) { 525 if (num <= 4) {
489 /* This is longer by 5 bytes on x86. 526 /* This is longer by 5 bytes on x86.
490 * Also gets miscompiled for ARM users 527 * Also gets miscompiled for ARM users
@@ -497,6 +534,7 @@ static void input_backward(unsigned num)
497 } while (--num); 534 } while (--num);
498 return; 535 return;
499 } 536 }
537#endif
500 printf(ESC"[%uD", num); 538 printf(ESC"[%uD", num);
501 return; 539 return;
502 } 540 }
@@ -635,7 +673,11 @@ static void input_backspace(void)
635static void input_forward(void) 673static void input_forward(void)
636{ 674{
637 if (cursor < command_len) 675 if (cursor < command_len)
676#if !ENABLE_PLATFORM_MINGW32
638 put_cur_glyph_and_inc_cursor(); 677 put_cur_glyph_and_inc_cursor();
678#else
679 inc_cursor();
680#endif
639} 681}
640 682
641#if ENABLE_FEATURE_TAB_COMPLETION 683#if ENABLE_FEATURE_TAB_COMPLETION
@@ -646,6 +688,14 @@ static void input_forward(void)
646//Also, perhaps "foo b<TAB> needs to complete to "foo bar" <cursor>, 688//Also, perhaps "foo b<TAB> needs to complete to "foo bar" <cursor>,
647//not "foo bar <cursor>... 689//not "foo bar <cursor>...
648 690
691# if ENABLE_PLATFORM_MINGW32
692/* use case-insensitive comparisons for filenames */
693# define is_prefixed_with(s, k) is_prefixed_with_case(s, k)
694# define qsort_string_vector(s, c) qsort_string_vector_case(s, c)
695# define strcmp(s, t) strcasecmp(s, t)
696# define strncmp(s, t, n) strncasecmp(s, t, n)
697# endif
698
649static void free_tab_completion_data(void) 699static void free_tab_completion_data(void)
650{ 700{
651 if (matches) { 701 if (matches) {
@@ -662,8 +712,12 @@ static void add_match(char *matched)
662 while (*p) { 712 while (*p) {
663 /* ESC attack fix: drop any string with control chars */ 713 /* ESC attack fix: drop any string with control chars */
664 if (*p < ' ' 714 if (*p < ' '
715# if !ENABLE_PLATFORM_MINGW32
665 || (!ENABLE_UNICODE_SUPPORT && *p >= 0x7f) 716 || (!ENABLE_UNICODE_SUPPORT && *p >= 0x7f)
666 || (ENABLE_UNICODE_SUPPORT && *p == 0x7f) 717 || (ENABLE_UNICODE_SUPPORT && *p == 0x7f)
718# else
719 || *p == 0x7f
720# endif
667 ) { 721 ) {
668 free(matched); 722 free(matched);
669 return; 723 return;
@@ -682,13 +736,16 @@ static void add_match(char *matched)
682 */ 736 */
683static char *username_path_completion(char *ud) 737static char *username_path_completion(char *ud)
684{ 738{
739# if !ENABLE_PLATFORM_MINGW32
685 struct passwd *entry; 740 struct passwd *entry;
741#endif
686 char *tilde_name = ud; 742 char *tilde_name = ud;
687 char *home = NULL; 743 char *home = NULL;
688 744
689 ud++; /* skip ~ */ 745 ud++; /* skip ~ */
690 if (*ud == '/') { /* "~/..." */ 746 if (*ud == '/') { /* "~/..." */
691 home = home_pwd_buf; 747 home = home_pwd_buf;
748# if !ENABLE_PLATFORM_MINGW32
692 } else { 749 } else {
693 /* "~user/..." */ 750 /* "~user/..." */
694 ud = strchr(ud, '/'); 751 ud = strchr(ud, '/');
@@ -697,6 +754,7 @@ static char *username_path_completion(char *ud)
697 *ud = '/'; /* restore "~user/..." */ 754 *ud = '/'; /* restore "~user/..." */
698 if (entry) 755 if (entry)
699 home = entry->pw_dir; 756 home = entry->pw_dir;
757# endif
700 } 758 }
701 if (home) { 759 if (home) {
702 ud = concat_path_file(home, ud); 760 ud = concat_path_file(home, ud);
@@ -706,6 +764,7 @@ static char *username_path_completion(char *ud)
706 return tilde_name; 764 return tilde_name;
707} 765}
708 766
767# if !ENABLE_PLATFORM_MINGW32
709/* ~use<tab> - find all users with this prefix. 768/* ~use<tab> - find all users with this prefix.
710 * Return the length of the prefix used for matching. 769 * Return the length of the prefix used for matching.
711 */ 770 */
@@ -728,6 +787,7 @@ static NOINLINE unsigned complete_username(const char *ud)
728 787
729 return 1 + userlen; 788 return 1 + userlen;
730} 789}
790# endif
731# endif /* FEATURE_USERNAME_COMPLETION */ 791# endif /* FEATURE_USERNAME_COMPLETION */
732 792
733enum { 793enum {
@@ -755,7 +815,7 @@ static int path_parse(char ***p)
755 tmp = (char*)pth; 815 tmp = (char*)pth;
756 npth = 1; /* path component count */ 816 npth = 1; /* path component count */
757 while (1) { 817 while (1) {
758 tmp = strchr(tmp, ':'); 818 tmp = strchr(tmp, PATH_SEP);
759 if (!tmp) 819 if (!tmp)
760 break; 820 break;
761 tmp++; 821 tmp++;
@@ -768,7 +828,7 @@ static int path_parse(char ***p)
768 res[0] = tmp = xstrdup(pth); 828 res[0] = tmp = xstrdup(pth);
769 npth = 1; 829 npth = 1;
770 while (1) { 830 while (1) {
771 tmp = strchr(tmp, ':'); 831 tmp = strchr(tmp, PATH_SEP);
772 if (!tmp) 832 if (!tmp)
773 break; 833 break;
774 *tmp++ = '\0'; /* ':' -> '\0' */ 834 *tmp++ = '\0'; /* ':' -> '\0' */
@@ -796,6 +856,17 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
796 path1[0] = (char*)"."; 856 path1[0] = (char*)".";
797 857
798 pfind = strrchr(command, '/'); 858 pfind = strrchr(command, '/');
859#if ENABLE_PLATFORM_MINGW32
860 if (!pfind && has_dos_drive_prefix(command) && command[2] != '\0') {
861 char buffer[PATH_MAX];
862
863 /* path is of form c:path with no '/' */
864 if (get_drive_cwd(command, buffer, PATH_MAX)) {
865 pfind = command + 2;
866 path1[0] = xstrdup(buffer);
867 }
868 } else
869#endif
799 if (!pfind) { 870 if (!pfind) {
800 if (type == FIND_EXE_ONLY) 871 if (type == FIND_EXE_ONLY)
801 npaths = path_parse(&paths); 872 npaths = path_parse(&paths);
@@ -865,6 +936,12 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
865 if (stat(found, &st) && lstat(found, &st)) 936 if (stat(found, &st) && lstat(found, &st))
866 goto cont; /* hmm, remove in progress? */ 937 goto cont; /* hmm, remove in progress? */
867 938
939# if ENABLE_PLATFORM_MINGW32
940 if (type == FIND_EXE_ONLY && !S_ISDIR(st.st_mode) &&
941 !file_is_executable(found))
942 goto cont;
943# endif
944
868 /* Save only name */ 945 /* Save only name */
869 len = strlen(name_found); 946 len = strlen(name_found);
870 found = xrealloc(found, len + 2); /* +2: for slash and NUL */ 947 found = xrealloc(found, len + 2); /* +2: for slash and NUL */
@@ -1184,7 +1261,7 @@ static NOINLINE void input_tab(smallint *lastWasTab)
1184 /* Free up any memory already allocated */ 1261 /* Free up any memory already allocated */
1185 free_tab_completion_data(); 1262 free_tab_completion_data();
1186 1263
1187# if ENABLE_FEATURE_USERNAME_COMPLETION 1264# if ENABLE_FEATURE_USERNAME_COMPLETION && !ENABLE_PLATFORM_MINGW32
1188 /* If the word starts with ~ and there is no slash in the word, 1265 /* If the word starts with ~ and there is no slash in the word,
1189 * then try completing this word as a username. */ 1266 * then try completing this word as a username. */
1190 if (state->flags & USERNAME_COMPLETION) 1267 if (state->flags & USERNAME_COMPLETION)
@@ -1235,7 +1312,11 @@ static NOINLINE void input_tab(smallint *lastWasTab)
1235 for (cp = chosen_match; *cp; cp++) { 1312 for (cp = chosen_match; *cp; cp++) {
1236 unsigned n; 1313 unsigned n;
1237 for (n = 1; n < num_matches; n++) { 1314 for (n = 1; n < num_matches; n++) {
1315# if !ENABLE_PLATFORM_MINGW32
1238 if (matches[n][cp - chosen_match] != *cp) { 1316 if (matches[n][cp - chosen_match] != *cp) {
1317# else
1318 if (tolower(matches[n][cp - chosen_match]) != tolower(*cp)) {
1319# endif
1239 goto stop; 1320 goto stop;
1240 } 1321 }
1241 } 1322 }
@@ -1271,7 +1352,11 @@ static NOINLINE void input_tab(smallint *lastWasTab)
1271 /* save tail */ 1352 /* save tail */
1272 strcpy(match_buf, &command_ps[cursor]); 1353 strcpy(match_buf, &command_ps[cursor]);
1273 /* add match and tail */ 1354 /* add match and tail */
1355#if ENABLE_PLATFORM_MINGW32
1356 sprintf(&command_ps[cursor-match_pfx_len], "%s%s", chosen_match, match_buf);
1357#else
1274 sprintf(&command_ps[cursor], "%s%s", chosen_match + match_pfx_len, match_buf); 1358 sprintf(&command_ps[cursor], "%s%s", chosen_match + match_pfx_len, match_buf);
1359#endif
1275 command_len = strlen(command_ps); 1360 command_len = strlen(command_ps);
1276 /* new pos */ 1361 /* new pos */
1277 pos = cursor + len_found - match_pfx_len; 1362 pos = cursor + len_found - match_pfx_len;
@@ -1308,6 +1393,13 @@ static NOINLINE void input_tab(smallint *lastWasTab)
1308 free(match_buf); 1393 free(match_buf);
1309} 1394}
1310 1395
1396# if ENABLE_PLATFORM_MINGW32
1397# undef is_prefixed_with
1398# undef qsort_string_vector
1399# undef strcmp
1400# undef strncmp
1401# endif
1402
1311#endif /* FEATURE_TAB_COMPLETION */ 1403#endif /* FEATURE_TAB_COMPLETION */
1312 1404
1313 1405
@@ -2350,7 +2442,7 @@ static void sigaction2(int sig, struct sigaction *act)
2350 */ 2442 */
2351int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) 2443int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize)
2352{ 2444{
2353 int len, n; 2445 int len IF_NOT_PLATFORM_MINGW32(, n);
2354 int timeout; 2446 int timeout;
2355#if ENABLE_FEATURE_TAB_COMPLETION 2447#if ENABLE_FEATURE_TAB_COMPLETION
2356 smallint lastWasTab = 0; 2448 smallint lastWasTab = 0;
@@ -2360,15 +2452,23 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2360 smallint vi_cmdmode = 0; 2452 smallint vi_cmdmode = 0;
2361#endif 2453#endif
2362 struct termios initial_settings; 2454 struct termios initial_settings;
2455#if !ENABLE_PLATFORM_MINGW32
2363 struct termios new_settings; 2456 struct termios new_settings;
2457#endif
2364 char read_key_buffer[KEYCODE_BUFFER_SIZE]; 2458 char read_key_buffer[KEYCODE_BUFFER_SIZE];
2365 2459
2366 INIT_S(); 2460 INIT_S();
2367 2461
2462#if !ENABLE_PLATFORM_MINGW32
2368 n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 2463 n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0
2369 | TERMIOS_CLEAR_ISIG /* turn off INTR (ctrl-C), QUIT, SUSP */ 2464 | TERMIOS_CLEAR_ISIG /* turn off INTR (ctrl-C), QUIT, SUSP */
2370 ); 2465 );
2371 if (n != 0 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON) { 2466 if (n != 0 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON) {
2467#else
2468 initial_settings.c_cc[VINTR] = CTRL('C');
2469 initial_settings.c_cc[VEOF] = CTRL('D');
2470 if (!isatty(0) || !isatty(1)) {
2471#endif
2372 /* Happens when e.g. stty -echo was run before. 2472 /* Happens when e.g. stty -echo was run before.
2373 * But if ICANON is not set, we don't come here. 2473 * But if ICANON is not set, we don't come here.
2374 * (example: interactive python ^Z-backgrounded, 2474 * (example: interactive python ^Z-backgrounded,
@@ -2422,7 +2522,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2422#endif 2522#endif
2423#define command command_must_not_be_used 2523#define command command_must_not_be_used
2424 2524
2525#if !ENABLE_PLATFORM_MINGW32
2425 tcsetattr_stdin_TCSANOW(&new_settings); 2526 tcsetattr_stdin_TCSANOW(&new_settings);
2527#endif
2426 2528
2427#if ENABLE_USERNAME_OR_HOMEDIR 2529#if ENABLE_USERNAME_OR_HOMEDIR
2428 { 2530 {
@@ -2475,6 +2577,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2475 } 2577 }
2476#endif 2578#endif
2477 ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); 2579 ic = ic_raw = lineedit_read_key(read_key_buffer, timeout);
2580#if ENABLE_PLATFORM_MINGW32
2581 /* scroll to cursor position on any keypress */
2582 if (isatty(fileno(stdin)) && isatty(fileno(stdout)))
2583 move_cursor_row(0);
2584#endif
2478 2585
2479#if ENABLE_FEATURE_REVERSE_SEARCH 2586#if ENABLE_FEATURE_REVERSE_SEARCH
2480 again: 2587 again:
@@ -2536,6 +2643,13 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2536 input_tab(&lastWasTab); 2643 input_tab(&lastWasTab);
2537 break; 2644 break;
2538#endif 2645#endif
2646#if ENABLE_PLATFORM_MINGW32
2647 case CTRL('Z'):
2648 command_ps[command_len] = '\0';
2649 bs_to_slash(command_ps);
2650 redraw(cmdedit_y, 0);
2651 break;
2652#endif
2539 case CTRL('K'): 2653 case CTRL('K'):
2540 /* Control-k -- clear to end of line */ 2654 /* Control-k -- clear to end of line */
2541 command_ps[cursor] = BB_NUL; 2655 command_ps[cursor] = BB_NUL;
@@ -2908,8 +3022,10 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2908 free_tab_completion_data(); 3022 free_tab_completion_data();
2909#endif 3023#endif
2910 3024
3025#if !ENABLE_PLATFORM_MINGW32
2911 /* restore initial_settings */ 3026 /* restore initial_settings */
2912 tcsetattr_stdin_TCSANOW(&initial_settings); 3027 tcsetattr_stdin_TCSANOW(&initial_settings);
3028#endif
2913#if ENABLE_FEATURE_EDITING_WINCH 3029#if ENABLE_FEATURE_EDITING_WINCH
2914 /* restore SIGWINCH handler */ 3030 /* restore SIGWINCH handler */
2915 sigaction_set(SIGWINCH, &S.SIGWINCH_handler); 3031 sigaction_set(SIGWINCH, &S.SIGWINCH_handler);
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 9b03bb8d0..e0fd486d8 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -49,11 +49,19 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
49 } 49 }
50 50
51 org_mask = cur_mask = (mode_t)-1L; 51 org_mask = cur_mask = (mode_t)-1L;
52#if ENABLE_PLATFORM_MINGW32
53 /* normalise path separators, path is already assumed writable */
54 bs_to_slash(path);
55#endif
52 s = path; 56 s = path;
53 while (1) { 57 while (1) {
54 c = '\0'; 58 c = '\0';
55 59
56 if (flags & FILEUTILS_RECUR) { /* Get the parent */ 60 if (flags & FILEUTILS_RECUR) { /* Get the parent */
61#if ENABLE_PLATFORM_MINGW32
62 if (s == path)
63 s += root_len(path);
64#endif
57 /* Bypass leading non-'/'s and then subsequent '/'s */ 65 /* Bypass leading non-'/'s and then subsequent '/'s */
58 while (*s) { 66 while (*s) {
59 if (*s == '/') { 67 if (*s == '/') {
diff --git a/libbb/messages.c b/libbb/messages.c
index 6914d5701..f5bbd3e32 100644
--- a/libbb/messages.c
+++ b/libbb/messages.c
@@ -27,7 +27,9 @@ const char bb_msg_standard_output[] ALIGN1 = "standard output";
27 27
28const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF"; 28const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
29 29
30#if !ENABLE_PLATFORM_MINGW32
30const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH; 31const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
32#endif
31const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; 33const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
32/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, 34/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
33 * but I want to save a few bytes here. Check libbb.h before changing! */ 35 * but I want to save a few bytes here. Check libbb.h before changing! */
diff --git a/libbb/mode_string.c b/libbb/mode_string.c
index 5ffd5683e..6c5c08acd 100644
--- a/libbb/mode_string.c
+++ b/libbb/mode_string.c
@@ -17,7 +17,7 @@
17#endif 17#endif
18 18
19#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \ 19#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \
20 || ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 ) \ 20 || ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 && S_IFBLK != 0030000 ) \
21 || ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \ 21 || ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \
22 || ( S_IFIFO != 0010000 ) 22 || ( S_IFIFO != 0010000 )
23#warning mode type bitflag value assumption(s) violated! falling back to larger version 23#warning mode type bitflag value assumption(s) violated! falling back to larger version
diff --git a/libbb/parse_config.c b/libbb/parse_config.c
index 8701b010c..f7a2b81b9 100644
--- a/libbb/parse_config.c
+++ b/libbb/parse_config.c
@@ -115,6 +115,10 @@ static int get_line_with_continuation(parser_t *parser)
115 parser->lineno++; 115 parser->lineno++;
116 if (line[len - 1] == '\n') 116 if (line[len - 1] == '\n')
117 len--; 117 len--;
118#if ENABLE_PLATFORM_MINGW32
119 if (line[len - 1] == '\r')
120 len--;
121#endif
118 if (len == 0 || line[len - 1] != '\\') 122 if (len == 0 || line[len - 1] != '\\')
119 break; 123 break;
120 len--; 124 len--;
diff --git a/libbb/printable_string.c b/libbb/printable_string.c
index a814fd03c..2e8895a4f 100644
--- a/libbb/printable_string.c
+++ b/libbb/printable_string.c
@@ -42,7 +42,7 @@ const char* FAST_FUNC printable_string2(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 af3ad86ff..e6892d7ff 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -74,6 +74,7 @@ const char* FAST_FUNC get_cached_groupname(gid_t gid)
74 return get_cached(&groupname, gid, gid2group_utoa); 74 return get_cached(&groupname, gid, gid2group_utoa);
75} 75}
76 76
77#if !ENABLE_PLATFORM_MINGW32
77 78
78#define PROCPS_BUFSIZE 1024 79#define PROCPS_BUFSIZE 1024
79 80
@@ -621,6 +622,8 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
621 } 622 }
622} 623}
623 624
625#endif /* ENABLE_PLATFORM_MINGW32 */
626
624/* from kernel: 627/* from kernel:
625 // pid comm S ppid pgid sid tty_nr tty_pgrp flg 628 // pid comm S ppid pgid sid tty_nr tty_pgrp flg
626 sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ 629 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 0cd04ab7b..379dd2448 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/u_signal_names.c b/libbb/u_signal_names.c
index f7d598c7a..036ad0038 100644
--- a/libbb/u_signal_names.c
+++ b/libbb/u_signal_names.c
@@ -27,6 +27,10 @@
27 27
28#include "libbb.h" 28#include "libbb.h"
29 29
30#if ENABLE_PLATFORM_MINGW32
31# undef SIGPIPE
32#endif
33
30/* Believe it or not, but some arches have more than 32 SIGs! 34/* Believe it or not, but some arches have more than 32 SIGs!
31 * HPPA: SIGSTKFLT == 36. */ 35 * HPPA: SIGSTKFLT == 36. */
32 36
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 65271e84f..26e1776a4 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -150,6 +150,7 @@ void FAST_FUNC run_noexec_applet_and_exit(int a, const char *name, char **argv)
150 * Higher-level code, hiding optional NOFORK/NOEXEC trickery. 150 * Higher-level code, hiding optional NOFORK/NOEXEC trickery.
151 */ 151 */
152 152
153#if !ENABLE_PLATFORM_MINGW32
153/* This does a fork/exec in one call, using vfork(). Returns PID of new child, 154/* This does a fork/exec in one call, using vfork(). Returns PID of new child,
154 * -1 for failure. Runs argv[0], searching path if that has no / in it. */ 155 * -1 for failure. Runs argv[0], searching path if that has no / in it. */
155pid_t FAST_FUNC spawn(char **argv) 156pid_t FAST_FUNC spawn(char **argv)
@@ -191,6 +192,7 @@ pid_t FAST_FUNC spawn(char **argv)
191 } 192 }
192 return pid; 193 return pid;
193} 194}
195#endif
194 196
195/* Die with an error message if we can't spawn a child process. */ 197/* Die with an error message if we can't spawn a child process. */
196pid_t FAST_FUNC xspawn(char **argv) 198pid_t FAST_FUNC xspawn(char **argv)
@@ -211,6 +213,7 @@ int FAST_FUNC spawn_and_wait(char **argv)
211 if (APPLET_IS_NOFORK(a)) 213 if (APPLET_IS_NOFORK(a))
212 return run_nofork_applet(a, argv); 214 return run_nofork_applet(a, argv);
213# if BB_MMU /* NOEXEC needs fork(), thus this is done only on MMU machines: */ 215# if BB_MMU /* NOEXEC needs fork(), thus this is done only on MMU machines: */
216# if !ENABLE_PLATFORM_MINGW32 /* and then only if not on Microsoft Windows */
214 if (APPLET_IS_NOEXEC(a)) { 217 if (APPLET_IS_NOEXEC(a)) {
215 fflush_all(); 218 fflush_all();
216 rc = fork(); 219 rc = fork();
@@ -220,6 +223,7 @@ int FAST_FUNC spawn_and_wait(char **argv)
220 /* child */ 223 /* child */
221 run_noexec_applet_and_exit(a, argv[0], argv); 224 run_noexec_applet_and_exit(a, argv[0], argv);
222 } 225 }
226# endif
223# endif 227# endif
224 } 228 }
225#endif 229#endif
@@ -227,6 +231,7 @@ int FAST_FUNC spawn_and_wait(char **argv)
227 return wait4pid(rc); 231 return wait4pid(rc);
228} 232}
229 233
234#if !ENABLE_PLATFORM_MINGW32
230#if !BB_MMU 235#if !BB_MMU
231void FAST_FUNC re_exec(char **argv) 236void FAST_FUNC re_exec(char **argv)
232{ 237{
@@ -314,3 +319,4 @@ void FAST_FUNC bb_sanitize_stdio(void)
314{ 319{
315 bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE, NULL); 320 bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE, NULL);
316} 321}
322#endif /* !MINGW32 */
diff --git a/libbb/xatonum_template.c b/libbb/xatonum_template.c
index e0471983c..0d5d35b47 100644
--- a/libbb/xatonum_template.c
+++ b/libbb/xatonum_template.c
@@ -67,7 +67,7 @@ unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base,
67 if (r >= lower && r <= upper) 67 if (r >= lower && r <= upper)
68 return r; 68 return r;
69 range: 69 range:
70 bb_error_msg_and_die("number %s is not in %llu..%llu range", 70 bb_error_msg_and_die("number %s is not in %"LL_FMT"u..%"LL_FMT"u range",
71 numstr, (unsigned long long)lower, 71 numstr, (unsigned long long)lower,
72 (unsigned long long)upper); 72 (unsigned long long)upper);
73 inval: 73 inval:
@@ -144,7 +144,8 @@ type FAST_FUNC xstrto(_range_sfx)(const char *numstr, int base,
144 } 144 }
145 145
146 if (r < lower || r > upper) { 146 if (r < lower || r > upper) {
147 bb_error_msg_and_die("number %s is not in %lld..%lld range", 147 bb_error_msg_and_die("number %s is not in "
148 "%"LL_FMT"d..%"LL_FMT"d range",
148 numstr, (long long)lower, (long long)upper); 149 numstr, (long long)lower, (long long)upper);
149 } 150 }
150 151
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index e9a2470e4..38faef38e 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -71,6 +71,7 @@ int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM,
71} 71}
72#endif 72#endif
73 73
74#if !ENABLE_PLATFORM_MINGW32
74static len_and_sockaddr* get_lsa(int fd, int (*get_name)(int fd, struct sockaddr *addr, socklen_t *addrlen)) 75static len_and_sockaddr* get_lsa(int fd, int (*get_name)(int fd, struct sockaddr *addr, socklen_t *addrlen))
75{ 76{
76 len_and_sockaddr lsa; 77 len_and_sockaddr lsa;
@@ -99,16 +100,17 @@ len_and_sockaddr* FAST_FUNC get_peer_lsa(int fd)
99{ 100{
100 return get_lsa(fd, getpeername); 101 return get_lsa(fd, getpeername);
101} 102}
103#endif
102 104
103void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) 105void FAST_FUNC xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen)
104{ 106{
105 if (connect(s, s_addr, addrlen) < 0) { 107 if (connect(s, saddr, addrlen) < 0) {
106 if (ENABLE_FEATURE_CLEAN_UP) 108 if (ENABLE_FEATURE_CLEAN_UP)
107 close(s); 109 close(s);
108 if (s_addr->sa_family == AF_INET) 110 if (saddr->sa_family == AF_INET)
109 bb_perror_msg_and_die("%s (%s)", 111 bb_perror_msg_and_die("%s (%s)",
110 "can't connect to remote host", 112 "can't connect to remote host",
111 inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr)); 113 inet_ntoa(((struct sockaddr_in *)saddr)->sin_addr));
112 bb_simple_perror_msg_and_die("can't connect to remote host"); 114 bb_simple_perror_msg_and_die("can't connect to remote host");
113 } 115 }
114} 116}
@@ -356,6 +358,10 @@ int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, int family, int sock_type)
356#if ENABLE_FEATURE_IPV6 358#if ENABLE_FEATURE_IPV6
357 fd = socket(AF_INET6, sock_type, 0); 359 fd = socket(AF_INET6, sock_type, 0);
358 if (fd >= 0) { 360 if (fd >= 0) {
361#if ENABLE_PLATFORM_MINGW32
362 DWORD buffer = 0;
363 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &buffer, sizeof(DWORD));
364#endif
359 family = AF_INET6; 365 family = AF_INET6;
360 goto done; 366 goto done;
361 } 367 }
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index ee2dbdef1..c92436683 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -268,6 +268,7 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh
268 int err; 268 int err;
269 int close_me = -1; 269 int close_me = -1;
270 270
271#if !ENABLE_PLATFORM_MINGW32
271 if (fd == -1) { 272 if (fd == -1) {
272 if (isatty(STDOUT_FILENO)) 273 if (isatty(STDOUT_FILENO))
273 fd = STDOUT_FILENO; 274 fd = STDOUT_FILENO;
@@ -280,6 +281,7 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh
280 else 281 else
281 close_me = fd = open("/dev/tty", O_RDONLY); 282 close_me = fd = open("/dev/tty", O_RDONLY);
282 } 283 }
284#endif
283 285
284 win.ws_row = 0; 286 win.ws_row = 0;
285 win.ws_col = 0; 287 win.ws_col = 0;
@@ -303,6 +305,7 @@ int FAST_FUNC get_terminal_width(int fd)
303 return width; 305 return width;
304} 306}
305 307
308#if !ENABLE_PLATFORM_MINGW32
306int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) 309int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
307{ 310{
308 return tcsetattr(STDIN_FILENO, TCSANOW, tp); 311 return tcsetattr(STDIN_FILENO, TCSANOW, tp);
@@ -383,6 +386,7 @@ int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags)
383 get_termios_and_make_raw(fd, &newterm, oldterm, flags); 386 get_termios_and_make_raw(fd, &newterm, oldterm, flags);
384 return tcsetattr(fd, TCSANOW, &newterm); 387 return tcsetattr(fd, TCSANOW, &newterm);
385} 388}
389#endif
386 390
387pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) 391pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
388{ 392{
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 93f325c62..cfe062a47 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -511,6 +511,7 @@ void FAST_FUNC xfstat(int fd, struct stat *stat_buf, const char *errmsg)
511 bb_simple_perror_msg_and_die(errmsg); 511 bb_simple_perror_msg_and_die(errmsg);
512} 512}
513 513
514#if !ENABLE_PLATFORM_MINGW32
514// selinux_or_die() - die if SELinux is disabled. 515// selinux_or_die() - die if SELinux is disabled.
515void FAST_FUNC selinux_or_die(void) 516void FAST_FUNC selinux_or_die(void)
516{ 517{
@@ -693,3 +694,4 @@ void FAST_FUNC xvfork_parent_waits_and_exits(void)
693 } 694 }
694 /* Child continues */ 695 /* Child continues */
695} 696}
697#endif /* !ENABLE_PLATFORM_MINGW32 */
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index a18dd0748..ca53e12d3 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -64,7 +64,7 @@ char* FAST_FUNC xmalloc_follow_symlinks(const char *path)
64 linkpath = xmalloc_readlink(buf); 64 linkpath = xmalloc_readlink(buf);
65 if (!linkpath) { 65 if (!linkpath) {
66 /* not a symlink, or doesn't exist */ 66 /* not a symlink, or doesn't exist */
67 if (errno == EINVAL || errno == ENOENT) 67 if (errno == EINVAL || errno == ENOENT || (ENABLE_PLATFORM_MINGW32 && errno == ENOSYS))
68 return buf; 68 return buf;
69 goto free_buf_ret_null; 69 goto free_buf_ret_null;
70 } 70 }