aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Kbuild29
-rw-r--r--libbb/appletlib.c12
-rw-r--r--libbb/bb_basename.c5
-rw-r--r--libbb/copy_file.c5
-rw-r--r--libbb/execable.c35
-rw-r--r--libbb/getopt32.c2
-rw-r--r--libbb/lineedit.c10
-rw-r--r--libbb/make_directory.c15
-rw-r--r--libbb/messages.c6
-rw-r--r--libbb/platform.c15
-rw-r--r--libbb/vfork_daemon_rexec.c5
-rw-r--r--libbb/xfuncs_printf.c14
-rw-r--r--libbb/xreadlink.c2
13 files changed, 132 insertions, 23 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 1b11d5d39..a8a1da1f9 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -37,27 +37,20 @@ 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 += herror_msg_and_die.o 45lib-y += herror_msg_and_die.o
48lib-y += human_readable.o 46lib-y += human_readable.o
49lib-y += inet_common.o
50lib-y += info_msg.o 47lib-y += info_msg.o
51lib-y += inode_hash.o 48lib-y += inode_hash.o
52lib-y += isdirectory.o 49lib-y += isdirectory.o
53lib-y += kernel_version.o
54lib-y += last_char_is.o 50lib-y += last_char_is.o
55lib-y += lineedit.o lineedit_ptr_hack.o 51lib-y += lineedit.o lineedit_ptr_hack.o
56lib-y += llist.o 52lib-y += llist.o
57lib-y += login.o
58lib-y += make_directory.o 53lib-y += make_directory.o
59lib-y += makedev.o
60lib-y += match_fstype.o
61lib-y += md5.o 54lib-y += md5.o
62# Alternative (disabled) implementation 55# Alternative (disabled) implementation
63#lib-y += md5prime.o 56#lib-y += md5prime.o
@@ -81,17 +74,14 @@ lib-y += procps.o
81lib-y += progress.o 74lib-y += progress.o
82lib-y += ptr_to_globals.o 75lib-y += ptr_to_globals.o
83lib-y += read.o 76lib-y += read.o
84lib-y += read_key.o
85lib-y += recursive_action.o 77lib-y += recursive_action.o
86lib-y += remove_file.o 78lib-y += remove_file.o
87lib-y += run_shell.o 79lib-y += run_shell.o
88lib-y += safe_gethostname.o
89lib-y += safe_poll.o 80lib-y += safe_poll.o
90lib-y += safe_strncpy.o 81lib-y += safe_strncpy.o
91lib-y += safe_write.o 82lib-y += safe_write.o
92lib-y += setup_environment.o 83lib-y += setup_environment.o
93lib-y += sha1.o 84lib-y += sha1.o
94lib-y += signals.o
95lib-y += simplify_path.o 85lib-y += simplify_path.o
96lib-y += single_argv.o 86lib-y += single_argv.o
97lib-y += skip_whitespace.o 87lib-y += skip_whitespace.o
@@ -101,7 +91,6 @@ lib-y += strrstr.o
101lib-y += time.o 91lib-y += time.o
102lib-y += trim.o 92lib-y += trim.o
103lib-y += u_signal_names.o 93lib-y += u_signal_names.o
104lib-y += udp_io.o
105lib-y += uuencode.o 94lib-y += uuencode.o
106lib-y += vdprintf.o 95lib-y += vdprintf.o
107lib-y += verror_msg.o 96lib-y += verror_msg.o
@@ -111,15 +100,27 @@ lib-y += wfopen.o
111lib-y += wfopen_input.o 100lib-y += wfopen_input.o
112lib-y += write.o 101lib-y += write.o
113lib-y += xatonum.o 102lib-y += xatonum.o
114lib-y += xconnect.o 103lib-y += xfunc_die.o
115lib-y += xfuncs.o 104lib-y += xfuncs.o
116lib-y += xfuncs_printf.o 105lib-y += xfuncs_printf.o
117lib-y += xfunc_die.o
118lib-y += xgetcwd.o 106lib-y += xgetcwd.o
119lib-y += xgethostbyname.o
120lib-y += xreadlink.o 107lib-y += xreadlink.o
121lib-y += xrealloc_vector.o 108lib-y += xrealloc_vector.o
122 109
110lib-$(CONFIG_PLATFORM_POSIX) += get_console.o
111lib-$(CONFIG_PLATFORM_POSIX) += getpty.o
112lib-$(CONFIG_PLATFORM_POSIX) += inet_common.o
113lib-$(CONFIG_PLATFORM_POSIX) += kernel_version.o
114lib-$(CONFIG_PLATFORM_POSIX) += login.o
115lib-$(CONFIG_PLATFORM_POSIX) += makedev.o
116lib-$(CONFIG_PLATFORM_POSIX) += match_fstype.o
117lib-$(CONFIG_PLATFORM_POSIX) += read_key.o
118lib-$(CONFIG_PLATFORM_POSIX) += safe_gethostname.o
119lib-$(CONFIG_PLATFORM_POSIX) += signals.o
120lib-$(CONFIG_PLATFORM_POSIX) += udp_io.o
121lib-$(CONFIG_PLATFORM_POSIX) += xconnect.o
122lib-$(CONFIG_PLATFORM_POSIX) += xgethostbyname.o
123
123lib-$(CONFIG_FEATURE_UTMP) += utmp.o 124lib-$(CONFIG_FEATURE_UTMP) += utmp.o
124 125
125# A mix of optimizations (why build stuff we know won't be used) 126# A mix of optimizations (why build stuff we know won't be used)
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index a8cd8e65f..f6dc1f171 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -827,6 +827,18 @@ int main(int argc UNUSED_PARAM, char **argv)
827 applet_name = argv[0]; 827 applet_name = argv[0];
828 if (applet_name[0] == '-') 828 if (applet_name[0] == '-')
829 applet_name++; 829 applet_name++;
830 if (ENABLE_PLATFORM_MINGW32) {
831 const char *applet_name_env = getenv("BUSYBOX_APPLET_NAME");
832 if (applet_name_env && *applet_name_env) {
833 applet_name = applet_name_env;
834 unsetenv("BUSYBOX_APPLET_NAME");
835 }
836 else {
837 int len = strlen(applet_name);
838 if (len > 4 && !strcmp(applet_name+len-4, ".exe"))
839 argv[0][applet_name-argv[0]+len-4] = '\0';
840 }
841 }
830 applet_name = bb_basename(applet_name); 842 applet_name = bb_basename(applet_name);
831 843
832 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ 844 parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */
diff --git a/libbb/bb_basename.c b/libbb/bb_basename.c
index bab4166d6..cc9b246e3 100644
--- a/libbb/bb_basename.c
+++ b/libbb/bb_basename.c
@@ -14,5 +14,10 @@ const char* FAST_FUNC bb_basename(const char *name)
14 const char *cp = strrchr(name, '/'); 14 const char *cp = strrchr(name, '/');
15 if (cp) 15 if (cp)
16 return cp + 1; 16 return cp + 1;
17 if (ENABLE_PLATFORM_MINGW32) {
18 cp = strrchr(name, '\\');
19 if (cp)
20 return cp + 1;
21 }
17 return name; 22 return name;
18} 23}
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index ed765d8f0..80a64f791 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -85,7 +85,12 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
85/* Inverse of cp -d ("cp without -d") */ 85/* Inverse of cp -d ("cp without -d") */
86#define FLAGS_DEREF (flags & (FILEUTILS_DEREFERENCE + FILEUTILS_DEREFERENCE_L0)) 86#define FLAGS_DEREF (flags & (FILEUTILS_DEREFERENCE + FILEUTILS_DEREFERENCE_L0))
87 87
88#if ENABLE_PLATFORM_MINGW32
89 /* stat can't be aliased, and MinGW uses lstat anyway */
90 if (lstat(source, &source_stat) < 0) {
91#else
88 if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) { 92 if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) {
93#endif
89 /* This may be a dangling symlink. 94 /* This may be a dangling symlink.
90 * Making [sym]links to dangling symlinks works, so... */ 95 * Making [sym]links to dangling symlinks works, so... */
91 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) 96 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK))
diff --git a/libbb/execable.c b/libbb/execable.c
index 5c7ac16a2..06b1c534b 100644
--- a/libbb/execable.c
+++ b/libbb/execable.c
@@ -16,6 +16,14 @@
16int FAST_FUNC execable_file(const char *name) 16int FAST_FUNC execable_file(const char *name)
17{ 17{
18 struct stat s; 18 struct stat s;
19 if (ENABLE_PLATFORM_MINGW32) {
20 int len = strlen(name);
21 return len > 4 &&
22 (!strcasecmp(name+len-4, ".exe") ||
23 !strcasecmp(name+len-4, ".com")) &&
24 !stat(name, &s) &&
25 S_ISREG(s.st_mode);
26 }
19 return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode)); 27 return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode));
20} 28}
21 29
@@ -28,13 +36,17 @@ int FAST_FUNC execable_file(const char *name)
28 * return NULL otherwise; (PATHp is undefined) 36 * return NULL otherwise; (PATHp is undefined)
29 * in all cases (*PATHp) contents will be trashed (s/:/NUL/). 37 * in all cases (*PATHp) contents will be trashed (s/:/NUL/).
30 */ 38 */
39#if !ENABLE_PLATFORM_MINGW32
40#define next_path_sep(s) strchr(s, ':')
41#endif
42
31char* FAST_FUNC find_execable(const char *filename, char **PATHp) 43char* FAST_FUNC find_execable(const char *filename, char **PATHp)
32{ 44{
33 char *p, *n; 45 char *p, *n;
34 46
35 p = *PATHp; 47 p = *PATHp;
36 while (p) { 48 while (p) {
37 n = strchr(p, ':'); 49 n = (char*)next_path_sep(p);
38 if (n) 50 if (n)
39 *n++ = '\0'; 51 *n++ = '\0';
40 if (*p != '\0') { /* it's not a PATH="foo::bar" situation */ 52 if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
@@ -43,6 +55,27 @@ char* FAST_FUNC find_execable(const char *filename, char **PATHp)
43 *PATHp = n; 55 *PATHp = n;
44 return p; 56 return p;
45 } 57 }
58 if (ENABLE_PLATFORM_MINGW32) {
59 int len = strlen(p);
60 if (len > 4 &&
61 (!strcasecmp(p+len-4, ".exe") ||
62 !strcasecmp(p+len-4, ".com")))
63 ; /* nothing, already tested by find_execable() */
64 else {
65 char *np = xmalloc(len+4+1);
66 memcpy(np, p, len);
67 memcpy(np+len, ".exe", 5);
68 if (execable_file(np)) {
69 *PATHp = n;
70 return np;
71 }
72 memcpy(np+len, ".com", 5);
73 if (execable_file(np)) {
74 *PATHp = n;
75 return np;
76 }
77 }
78 }
46 free(p); 79 free(p);
47 } 80 }
48 p = n; 81 p = n;
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index b5f83c127..20e1b8a8b 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -534,7 +534,7 @@ getopt32(char **argv, const char *applet_opts, ...)
534 * run_nofork_applet_prime() does this, but we might end up here 534 * run_nofork_applet_prime() does this, but we might end up here
535 * also via gunzip_main() -> gzip_main(). Play safe. 535 * also via gunzip_main() -> gzip_main(). Play safe.
536 */ 536 */
537#ifdef __GLIBC__ 537#if defined(__GLIBC__) || ENABLE_PLATFORM_MINGW32
538 optind = 0; 538 optind = 0;
539#else /* BSD style */ 539#else /* BSD style */
540 optind = 1; 540 optind = 1;
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 18664b8c1..f7faf4639 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -686,7 +686,11 @@ static int path_parse(char ***p, int flags)
686 tmp = (char*)pth; 686 tmp = (char*)pth;
687 npth = 1; /* path component count */ 687 npth = 1; /* path component count */
688 while (1) { 688 while (1) {
689#if ENABLE_PLATFORM_MINGW32
690 tmp = next_path_sep(tmp);
691#else
689 tmp = strchr(tmp, ':'); 692 tmp = strchr(tmp, ':');
693#endif
690 if (!tmp) 694 if (!tmp)
691 break; 695 break;
692 if (*++tmp == '\0') 696 if (*++tmp == '\0')
@@ -698,7 +702,11 @@ static int path_parse(char ***p, int flags)
698 res[0] = tmp = xstrdup(pth); 702 res[0] = tmp = xstrdup(pth);
699 npth = 1; 703 npth = 1;
700 while (1) { 704 while (1) {
705#if ENABLE_PLATFORM_MINGW32
706 tmp = next_path_sep(tmp);
707#else
701 tmp = strchr(tmp, ':'); 708 tmp = strchr(tmp, ':');
709#endif
702 if (!tmp) 710 if (!tmp)
703 break; 711 break;
704 *tmp++ = '\0'; /* ':' -> '\0' */ 712 *tmp++ = '\0'; /* ':' -> '\0' */
@@ -1893,6 +1901,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1893 1901
1894 INIT_S(); 1902 INIT_S();
1895 1903
1904#if !ENABLE_PLATFORM_MINGW32
1896 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0 1905 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0
1897 || !(initial_settings.c_lflag & ECHO) 1906 || !(initial_settings.c_lflag & ECHO)
1898 ) { 1907 ) {
@@ -1906,6 +1915,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1906 DEINIT_S(); 1915 DEINIT_S();
1907 return len; 1916 return len;
1908 } 1917 }
1918#endif
1909 1919
1910 init_unicode(); 1920 init_unicode();
1911 1921
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 4486eb1ed..1eb8a8a49 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -31,7 +31,7 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
31 mode_t cur_mask; 31 mode_t cur_mask;
32 mode_t org_mask; 32 mode_t org_mask;
33 const char *fail_msg; 33 const char *fail_msg;
34 char *s; 34 char *s, *s2;
35 char c; 35 char c;
36 struct stat st; 36 struct stat st;
37 37
@@ -45,14 +45,21 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
45 c = '\0'; 45 c = '\0';
46 46
47 if (flags & FILEUTILS_RECUR) { /* Get the parent */ 47 if (flags & FILEUTILS_RECUR) { /* Get the parent */
48 /* skip drive letter and initial slashes */
49 if (ENABLE_PLATFORM_MINGW32 && s == path && *s && s[1] == ':') {
50 s += 2;
51 while (*s == '/')
52 s++;
53 }
48 /* Bypass leading non-'/'s and then subsequent '/'s */ 54 /* Bypass leading non-'/'s and then subsequent '/'s */
49 while (*s) { 55 while (*s) {
50 if (*s == '/') { 56 if (*s == '/') {
57 s2 = s;
58 c = *s2; /* Save the current char */
59 *s2 = 0; /* and replace it with nul. */
51 do { 60 do {
52 ++s; 61 ++s;
53 } while (*s == '/'); 62 } while (*s == '/');
54 c = *s; /* Save the current char */
55 *s = '\0'; /* and replace it with nul */
56 break; 63 break;
57 } 64 }
58 ++s; 65 ++s;
@@ -113,7 +120,7 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
113 } 120 }
114 121
115 /* Remove any inserted nul from the path (recursive mode) */ 122 /* Remove any inserted nul from the path (recursive mode) */
116 *s = c; 123 *s2 = c;
117 } /* while (1) */ 124 } /* while (1) */
118 125
119 bb_perror_msg("can't %s directory '%s'", fail_msg, path); 126 bb_perror_msg("can't %s directory '%s'", fail_msg, path);
diff --git a/libbb/messages.c b/libbb/messages.c
index 1d0e58720..ffa8d00cd 100644
--- a/libbb/messages.c
+++ b/libbb/messages.c
@@ -44,7 +44,11 @@ const char bb_path_group_file[] ALIGN1 = "/etc/group";
44const char bb_path_gshadow_file[] ALIGN1 = "/etc/gshadow"; 44const char bb_path_gshadow_file[] ALIGN1 = "/etc/gshadow";
45const char bb_path_motd_file[] ALIGN1 = "/etc/motd"; 45const char bb_path_motd_file[] ALIGN1 = "/etc/motd";
46const char bb_dev_null[] ALIGN1 = "/dev/null"; 46const char bb_dev_null[] ALIGN1 = "/dev/null";
47#if ENABLE_PLATFORM_MINGW32
48/* bb_busybox_exec_path is redefined to get_busybox_exec_path() in libbb.h */
49#else
47const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH; 50const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
51#endif
48const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; 52const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
49/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, 53/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
50 * but I want to save a few bytes here. Check libbb.h before changing! */ 54 * but I want to save a few bytes here. Check libbb.h before changing! */
@@ -57,6 +61,7 @@ const int const_int_1 = 1;
57 * and it will end up in bss */ 61 * and it will end up in bss */
58const int const_int_0 = 0; 62const int const_int_0 = 0;
59 63
64#if !ENABLE_PLATFORM_MINGW32 /* No wtmp on Windows */
60#include <utmp.h> 65#include <utmp.h>
61/* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */ 66/* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */
62const char bb_path_wtmp_file[] ALIGN1 = 67const char bb_path_wtmp_file[] ALIGN1 =
@@ -67,6 +72,7 @@ const char bb_path_wtmp_file[] ALIGN1 =
67#else 72#else
68#error unknown path to wtmp file 73#error unknown path to wtmp file
69#endif 74#endif
75#endif
70 76
71/* We use it for "global" data via *(struct global*)&bb_common_bufsiz1. 77/* We use it for "global" data via *(struct global*)&bb_common_bufsiz1.
72 * Since gcc insists on aligning struct global's members, it would be a pity 78 * Since gcc insists on aligning struct global's members, it would be a pity
diff --git a/libbb/platform.c b/libbb/platform.c
index 17ad3f75a..8642337d4 100644
--- a/libbb/platform.c
+++ b/libbb/platform.c
@@ -51,8 +51,21 @@ int fdprintf(int fd, const char *format, ...)
51 char *string_ptr; 51 char *string_ptr;
52 52
53 va_start(p, format); 53 va_start(p, format);
54 r = vasprintf(&string_ptr, format, p); 54 if (ENABLE_PLATFORM_MINGW32) {
55 string_ptr = xmalloc(1024);
56 r = vsnprintf(string_ptr, 1024, format, p);
57 }
58 else
59 r = vasprintf(&string_ptr, format, p);
55 va_end(p); 60 va_end(p);
61 if (ENABLE_PLATFORM_MINGW32 && r > 0) {
62 free(string_ptr);
63 r += 2;
64 string_ptr = xmalloc(r);
65 va_start(p, format);
66 r = vsnprintf(string_ptr, r, format, p);
67 va_end(p);
68 }
56 if (r >= 0) { 69 if (r >= 0) {
57 r = full_write(fd, string_ptr, r); 70 r = full_write(fd, string_ptr, r);
58 free(string_ptr); 71 free(string_ptr);
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 07024f5f0..08d9199c1 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -25,6 +25,9 @@ pid_t FAST_FUNC spawn(char **argv)
25 volatile int failed; 25 volatile int failed;
26 pid_t pid; 26 pid_t pid;
27 27
28 if (ENABLE_PLATFORM_MINGW32)
29 return mingw_spawn(argv);
30
28 fflush_all(); 31 fflush_all();
29 32
30 /* Be nice to nommu machines. */ 33 /* Be nice to nommu machines. */
@@ -226,7 +229,7 @@ int FAST_FUNC spawn_and_wait(char **argv)
226 { 229 {
227 return run_nofork_applet(a, argv); 230 return run_nofork_applet(a, argv);
228 } 231 }
229#if BB_MMU 232#if BB_MMU && !ENABLE_PLATFORM_MINGW32
230 /* MMU only */ 233 /* MMU only */
231 /* a->noexec is true */ 234 /* a->noexec is true */
232 rc = fork(); 235 rc = fork();
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 7207ec58a..f8b1b81cd 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -287,8 +287,22 @@ char* FAST_FUNC xasprintf(const char *format, ...)
287 char *string_ptr; 287 char *string_ptr;
288 288
289 va_start(p, format); 289 va_start(p, format);
290#if ENABLE_PLATFORM_MINGW32
291 string_ptr = xmalloc(1024);
292 r = vsnprintf(string_ptr, 1024, format, p);
293 va_end(p);
294 if (r > 0) {
295 free(string_ptr);
296 r += 2;
297 string_ptr = xmalloc(r);
298 va_start(p, format);
299 r = vsnprintf(string_ptr, r, format, p);
300 va_end(p);
301 }
302#else
290 r = vasprintf(&string_ptr, format, p); 303 r = vasprintf(&string_ptr, format, p);
291 va_end(p); 304 va_end(p);
305#endif
292 306
293 if (r < 0) 307 if (r < 0)
294 bb_error_msg_and_die(bb_msg_memory_exhausted); 308 bb_error_msg_and_die(bb_msg_memory_exhausted);
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index faa0e1646..1a012456f 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -59,7 +59,7 @@ char* FAST_FUNC xmalloc_follow_symlinks(const char *path)
59 linkpath = xmalloc_readlink(buf); 59 linkpath = xmalloc_readlink(buf);
60 if (!linkpath) { 60 if (!linkpath) {
61 /* not a symlink, or doesn't exist */ 61 /* not a symlink, or doesn't exist */
62 if (errno == EINVAL || errno == ENOENT) 62 if (errno == EINVAL || errno == ENOENT || (ENABLE_PLATFORM_MINGW32 && errno == ENOSYS))
63 return buf; 63 return buf;
64 goto free_buf_ret_null; 64 goto free_buf_ret_null;
65 } 65 }