aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/.gitignore1
-rw-r--r--include/bb_archive.h14
-rw-r--r--include/libbb.h169
-rw-r--r--include/mingw.h671
-rw-r--r--include/platform.h45
-rw-r--r--include/unicode.h19
6 files changed, 904 insertions, 15 deletions
diff --git a/include/.gitignore b/include/.gitignore
index 13a96e018..91575ed3f 100644
--- a/include/.gitignore
+++ b/include/.gitignore
@@ -3,6 +3,7 @@
3/applets.h 3/applets.h
4/applet_tables.h 4/applet_tables.h
5/autoconf.h 5/autoconf.h
6/BB_VER.h
6/bbconfigopts_bz2.h 7/bbconfigopts_bz2.h
7/bbconfigopts.h 8/bbconfigopts.h
8/embedded_scripts.h 9/embedded_scripts.h
diff --git a/include/bb_archive.h b/include/bb_archive.h
index e0ef8fc4e..3422c9656 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -2,6 +2,16 @@
2#ifndef UNARCHIVE_H 2#ifndef UNARCHIVE_H
3#define UNARCHIVE_H 1 3#define UNARCHIVE_H 1
4 4
5#if !defined(BB_ARCHIVE_PUBLIC) && ENABLE_PLATFORM_MINGW32
6/* treat mingw as a non-MMU platform */
7#undef BB_MMU
8#undef USE_FOR_NOMMU
9#undef USE_FOR_MMU
10#define BB_MMU 0
11#define USE_FOR_NOMMU(...) __VA_ARGS__
12#define USE_FOR_MMU(...)
13#endif
14
5PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 15PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
6 16
7enum { 17enum {
@@ -277,7 +287,11 @@ enum {
277 BBUNPK_SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION, 287 BBUNPK_SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION,
278}; 288};
279 289
290#if !ENABLE_PLATFORM_MINGW32
280void check_errors_in_children(int signo); 291void check_errors_in_children(int signo);
292#else
293#define check_errors_in_children(s) ((void)0)
294#endif
281#if BB_MMU 295#if BB_MMU
282void fork_transformer(int fd, 296void fork_transformer(int fd,
283 int signature_skipped, 297 int signature_skipped,
diff --git a/include/libbb.h b/include/libbb.h
index 4d6193795..bc1453e12 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -10,6 +10,12 @@
10#ifndef LIBBB_H 10#ifndef LIBBB_H
11#define LIBBB_H 1 11#define LIBBB_H 1
12 12
13#if ENABLE_PLATFORM_MINGW32
14/* We have our own nanosleep(), clock_gettime() and clock_settime(). */
15/* Skip the Windows include file that declares them. */
16# define WIN_PTHREADS_TIME_H
17#endif
18
13#include "platform.h" 19#include "platform.h"
14 20
15#include <ctype.h> 21#include <ctype.h>
@@ -143,6 +149,9 @@
143# include <arpa/inet.h> 149# include <arpa/inet.h>
144#elif defined __APPLE__ 150#elif defined __APPLE__
145# include <netinet/in.h> 151# include <netinet/in.h>
152#elif ENABLE_PLATFORM_MINGW32
153# include <winsock2.h>
154# include <ws2tcpip.h>
146#else 155#else
147# include <arpa/inet.h> 156# include <arpa/inet.h>
148//This breaks on bionic: 157//This breaks on bionic:
@@ -182,7 +191,9 @@
182 191
183/* Some libc's forget to declare these, do it ourself */ 192/* Some libc's forget to declare these, do it ourself */
184 193
194#if !ENABLE_PLATFORM_MINGW32
185extern char **environ; 195extern char **environ;
196#endif
186/* klogctl is in libc's klog.h, but we cheat and not #include that */ 197/* klogctl is in libc's klog.h, but we cheat and not #include that */
187int klogctl(int type, char *b, int len); 198int klogctl(int type, char *b, int len);
188#ifndef PATH_MAX 199#ifndef PATH_MAX
@@ -192,6 +203,13 @@ int klogctl(int type, char *b, int len);
192# define BUFSIZ 4096 203# define BUFSIZ 4096
193#endif 204#endif
194 205
206#if ENABLE_PLATFORM_MINGW32
207# include "mingw.h"
208# define MINGW_SPECIAL(a) mingw_ ## a
209#else
210# define MINGW_SPECIAL(a) a
211#endif
212
195#if __GNUC_PREREQ(5,0) 213#if __GNUC_PREREQ(5,0)
196/* Since musl is apparently unable to get it right and would use 214/* Since musl is apparently unable to get it right and would use
197 * a function call to a single-instruction function of "bswap %eax", 215 * a function call to a single-instruction function of "bswap %eax",
@@ -276,6 +294,20 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
276 : ((T)1 << (sizeof(T)*8-1)) \ 294 : ((T)1 << (sizeof(T)*8-1)) \
277 ) 295 )
278 296
297// UCRT supports both "ll" and "I64", but gcc warns on "I64" with UCRT mingw
298#if ENABLE_PLATFORM_MINGW32 && !defined(_UCRT) && \
299 (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)
300#define LL_FMT "I64"
301#else
302#define LL_FMT "ll"
303#endif
304
305#if ENABLE_PLATFORM_MINGW32 && defined(_WIN64)
306#define PID_FMT LL_FMT
307#else
308#define PID_FMT
309#endif
310
279/* Large file support */ 311/* Large file support */
280/* Note that CONFIG_LFS=y forces bbox to be built with all common ops 312/* Note that CONFIG_LFS=y forces bbox to be built with all common ops
281 * (stat, lseek etc) mapped to "largefile" variants by libc. 313 * (stat, lseek etc) mapped to "largefile" variants by libc.
@@ -301,7 +333,7 @@ typedef unsigned long long uoff_t;
301# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX) 333# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX)
302# define BB_STRTOOFF bb_strtoull 334# define BB_STRTOOFF bb_strtoull
303# define STRTOOFF strtoull 335# define STRTOOFF strtoull
304# define OFF_FMT "ll" 336# define OFF_FMT LL_FMT
305# endif 337# endif
306#else 338#else
307/* CONFIG_LFS is off */ 339/* CONFIG_LFS is off */
@@ -570,13 +602,20 @@ char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
570const char *bb_basename(const char *name) FAST_FUNC; 602const char *bb_basename(const char *name) FAST_FUNC;
571/* NB: can violate const-ness (similarly to strchr) */ 603/* NB: can violate const-ness (similarly to strchr) */
572char *last_char_is(const char *s, int c) FAST_FUNC; 604char *last_char_is(const char *s, int c) FAST_FUNC;
605char *last_char_is_dir_sep(const char *s) FAST_FUNC;
573const char* endofname(const char *name) FAST_FUNC; 606const char* endofname(const char *name) FAST_FUNC;
574char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; 607char *is_prefixed_with(const char *string, const char *key) FAST_FUNC;
575char *is_suffixed_with(const char *string, const char *key) FAST_FUNC; 608char *is_suffixed_with(const char *string, const char *key) FAST_FUNC;
576 609
610#if !ENABLE_PLATFORM_MINGW32
577int ndelay_on(int fd) FAST_FUNC; 611int ndelay_on(int fd) FAST_FUNC;
578int ndelay_off(int fd) FAST_FUNC; 612int ndelay_off(int fd) FAST_FUNC;
579void close_on_exec_on(int fd) FAST_FUNC; 613void close_on_exec_on(int fd) FAST_FUNC;
614#else
615static inline int ndelay_on(int fd UNUSED_PARAM) { return 0; }
616static inline int ndelay_off(int fd UNUSED_PARAM) { return 0; }
617static inline void close_on_exec_on(int fd UNUSED_PARAM) { return; }
618#endif
580void xdup2(int, int) FAST_FUNC; 619void xdup2(int, int) FAST_FUNC;
581void xmove_fd(int, int) FAST_FUNC; 620void xmove_fd(int, int) FAST_FUNC;
582 621
@@ -610,20 +649,37 @@ enum {
610 * Dance around with long long to guard against that... 649 * Dance around with long long to guard against that...
611 */ 650 */
612 BB_FATAL_SIGS = (int)(0 651 BB_FATAL_SIGS = (int)(0
652#ifdef SIGHUP
613 + (1LL << SIGHUP) 653 + (1LL << SIGHUP)
654#endif
614 + (1LL << SIGINT) 655 + (1LL << SIGINT)
615 + (1LL << SIGTERM) 656 + (1LL << SIGTERM)
616 + (1LL << SIGPIPE) // Write to pipe with no readers 657 + (1LL << SIGPIPE) // Write to pipe with no readers
658#ifdef SIGQUIT
617 + (1LL << SIGQUIT) // Quit from keyboard 659 + (1LL << SIGQUIT) // Quit from keyboard
660#endif
618 + (1LL << SIGABRT) // Abort signal from abort(3) 661 + (1LL << SIGABRT) // Abort signal from abort(3)
662#ifdef SIGALRM
619 + (1LL << SIGALRM) // Timer signal from alarm(2) 663 + (1LL << SIGALRM) // Timer signal from alarm(2)
664#endif
665#ifdef SIGVTALRM
620 + (1LL << SIGVTALRM) // Virtual alarm clock 666 + (1LL << SIGVTALRM) // Virtual alarm clock
667#endif
668#ifdef SIGXCPU
621 + (1LL << SIGXCPU) // CPU time limit exceeded 669 + (1LL << SIGXCPU) // CPU time limit exceeded
670#endif
671#ifdef SIGXFSZ
622 + (1LL << SIGXFSZ) // File size limit exceeded 672 + (1LL << SIGXFSZ) // File size limit exceeded
673#endif
674#ifdef SIGUSR1
623 + (1LL << SIGUSR1) // Yes kids, these are also fatal! 675 + (1LL << SIGUSR1) // Yes kids, these are also fatal!
676#endif
677#ifdef SIGUSR1
624 + (1LL << SIGUSR2) 678 + (1LL << SIGUSR2)
679#endif
625 + 0), 680 + 0),
626}; 681};
682#if !ENABLE_PLATFORM_MINGW32
627void bb_signals(int sigs, void (*f)(int)) FAST_FUNC; 683void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
628/* Unlike signal() and bb_signals, sets handler with sigaction() 684/* Unlike signal() and bb_signals, sets handler with sigaction()
629 * and in a way that while signal handler is run, no other signals 685 * and in a way that while signal handler is run, no other signals
@@ -643,6 +699,10 @@ int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
643int sigprocmask_allsigs(int how) FAST_FUNC; 699int sigprocmask_allsigs(int how) FAST_FUNC;
644/* Return old set in the same set: */ 700/* Return old set in the same set: */
645int sigprocmask2(int how, sigset_t *set) FAST_FUNC; 701int sigprocmask2(int how, sigset_t *set) FAST_FUNC;
702#else
703#define bb_signals(s, f)
704#define kill_myself_with_sig(s)
705#endif
646/* Standard handler which just records signo */ 706/* Standard handler which just records signo */
647extern smallint bb_got_signal; 707extern smallint bb_got_signal;
648void record_signo(int signo); /* not FAST_FUNC! */ 708void record_signo(int signo); /* not FAST_FUNC! */
@@ -726,7 +786,7 @@ void xsettimeofday(const struct timeval *tv) FAST_FUNC;
726int xsocket(int domain, int type, int protocol) FAST_FUNC; 786int xsocket(int domain, int type, int protocol) FAST_FUNC;
727void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC; 787void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
728void xlisten(int s, int backlog) FAST_FUNC; 788void xlisten(int s, int backlog) FAST_FUNC;
729void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC; 789void xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen) FAST_FUNC;
730ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, 790ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
731 socklen_t tolen) FAST_FUNC; 791 socklen_t tolen) FAST_FUNC;
732 792
@@ -933,7 +993,7 @@ int bb_putchar(int ch) FAST_FUNC;
933/* Note: does not use stdio, writes to fd 2 directly */ 993/* Note: does not use stdio, writes to fd 2 directly */
934int bb_putchar_stderr(char ch) FAST_FUNC; 994int bb_putchar_stderr(char ch) FAST_FUNC;
935int fputs_stdout(const char *s) FAST_FUNC; 995int fputs_stdout(const char *s) FAST_FUNC;
936char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; 996char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) RETURNS_MALLOC;
937char *auto_string(char *str) FAST_FUNC; 997char *auto_string(char *str) FAST_FUNC;
938// gcc-4.1.1 still isn't good enough at optimizing it 998// gcc-4.1.1 still isn't good enough at optimizing it
939// (+200 bytes compared to macro) 999// (+200 bytes compared to macro)
@@ -1208,12 +1268,20 @@ gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC;
1208struct cached_groupinfo { 1268struct cached_groupinfo {
1209 uid_t euid; 1269 uid_t euid;
1210 gid_t egid; 1270 gid_t egid;
1271#if !ENABLE_PLATFORM_MINGW32
1272 // If these are ever restored on Windows it will be necessary to alter
1273 // globals_misc_size()/globals_misc_copy() in ash.
1211 int ngroups; 1274 int ngroups;
1212 gid_t *supplementary_array; 1275 gid_t *supplementary_array;
1276#endif
1213}; 1277};
1214uid_t FAST_FUNC get_cached_euid(uid_t *euid); 1278uid_t FAST_FUNC get_cached_euid(uid_t *euid);
1215gid_t FAST_FUNC get_cached_egid(gid_t *egid); 1279gid_t FAST_FUNC get_cached_egid(gid_t *egid);
1280#if !ENABLE_PLATFORM_MINGW32
1216int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid); 1281int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid);
1282#else
1283# define is_in_supplementary_groups(g, i) (FALSE)
1284#endif
1217 1285
1218#if ENABLE_FEATURE_UTMP 1286#if ENABLE_FEATURE_UTMP
1219void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); 1287void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
@@ -1249,6 +1317,7 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1249 1317
1250/* xvfork() can't be a _function_, return after vfork in child mangles stack 1318/* xvfork() can't be a _function_, return after vfork in child mangles stack
1251 * in the parent. It must be a macro. */ 1319 * in the parent. It must be a macro. */
1320#if !ENABLE_PLATFORM_MINGW32
1252#define xvfork() \ 1321#define xvfork() \
1253({ \ 1322({ \
1254 pid_t bb__xvfork_pid = vfork(); \ 1323 pid_t bb__xvfork_pid = vfork(); \
@@ -1256,6 +1325,9 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1256 bb_simple_perror_msg_and_die("vfork"); \ 1325 bb_simple_perror_msg_and_die("vfork"); \
1257 bb__xvfork_pid; \ 1326 bb__xvfork_pid; \
1258}) 1327})
1328#else
1329#define xvfork() vfork()
1330#endif
1259#if BB_MMU 1331#if BB_MMU
1260pid_t xfork(void) FAST_FUNC; 1332pid_t xfork(void) FAST_FUNC;
1261#endif 1333#endif
@@ -1290,6 +1362,15 @@ void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN F
1290#ifndef BUILD_INDIVIDUAL 1362#ifndef BUILD_INDIVIDUAL
1291int find_applet_by_name(const char *name) FAST_FUNC; 1363int find_applet_by_name(const char *name) FAST_FUNC;
1292void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; 1364void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC;
1365# if ENABLE_PLATFORM_MINGW32
1366# if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE
1367int prefer_applet(const char *name, const char *path) FAST_FUNC;
1368int find_applet_by_name_for_sh(const char *name, const char *path) FAST_FUNC;
1369# endif
1370# else
1371# define prefer_applet(n, p) (1)
1372# define find_applet_by_name_for_sh(n, p) find_applet_by_name(n)
1373# endif
1293#endif 1374#endif
1294void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; 1375void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC;
1295#if defined(__linux__) 1376#if defined(__linux__)
@@ -1370,12 +1451,12 @@ char* single_argv(char **argv) FAST_FUNC;
1370char **skip_dash_dash(char **argv) FAST_FUNC; 1451char **skip_dash_dash(char **argv) FAST_FUNC;
1371extern const char *const bb_argv_dash[]; /* { "-", NULL } */ 1452extern const char *const bb_argv_dash[]; /* { "-", NULL } */
1372extern uint32_t option_mask32; 1453extern uint32_t option_mask32;
1373uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; 1454uint32_t getopt32(char **argv, const char *applet_opts, ...);
1374# define No_argument "\0" 1455# define No_argument "\0"
1375# define Required_argument "\001" 1456# define Required_argument "\001"
1376# define Optional_argument "\002" 1457# define Optional_argument "\002"
1377#if ENABLE_LONG_OPTS 1458#if ENABLE_LONG_OPTS
1378uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...) FAST_FUNC; 1459uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...);
1379#else 1460#else
1380#define getopt32long(argv,optstring,longopts,...) \ 1461#define getopt32long(argv,optstring,longopts,...) \
1381 getopt32(argv,optstring,##__VA_ARGS__) 1462 getopt32(argv,optstring,##__VA_ARGS__)
@@ -1450,17 +1531,17 @@ extern uint8_t xfunc_error_retval;
1450extern void (*die_func)(void); 1531extern void (*die_func)(void);
1451void xfunc_die(void) NORETURN FAST_FUNC; 1532void xfunc_die(void) NORETURN FAST_FUNC;
1452void bb_show_usage(void) NORETURN FAST_FUNC; 1533void bb_show_usage(void) NORETURN FAST_FUNC;
1453void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1534void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1454void bb_simple_error_msg(const char *s) FAST_FUNC; 1535void bb_simple_error_msg(const char *s) FAST_FUNC;
1455void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1536void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
1456void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC; 1537void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC;
1457void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1538void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1458void bb_simple_perror_msg(const char *s) FAST_FUNC; 1539void bb_simple_perror_msg(const char *s) FAST_FUNC;
1459void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1540void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
1460void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC; 1541void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1461void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1542void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1462void bb_simple_herror_msg(const char *s) FAST_FUNC; 1543void bb_simple_herror_msg(const char *s) FAST_FUNC;
1463void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1544void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
1464void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC; 1545void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1465void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; 1546void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1466void bb_perror_nomsg(void) FAST_FUNC; 1547void bb_perror_nomsg(void) FAST_FUNC;
@@ -1476,7 +1557,7 @@ void bb_logenv_override(void) FAST_FUNC;
1476typedef smalluint exitcode_t; 1557typedef smalluint exitcode_t;
1477 1558
1478#if ENABLE_FEATURE_SYSLOG_INFO 1559#if ENABLE_FEATURE_SYSLOG_INFO
1479void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1560void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1480void bb_simple_info_msg(const char *s) FAST_FUNC; 1561void bb_simple_info_msg(const char *s) FAST_FUNC;
1481void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC; 1562void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC;
1482#else 1563#else
@@ -1853,8 +1934,8 @@ int get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *ol
1853int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC; 1934int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC;
1854 1935
1855/* NB: "unsigned request" is crucial! "int request" will break some arches! */ 1936/* NB: "unsigned request" is crucial! "int request" will break some arches! */
1856int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; 1937int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
1857int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; 1938int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
1858#if ENABLE_IOCTL_HEX2STR_ERROR 1939#if ENABLE_IOCTL_HEX2STR_ERROR
1859int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC; 1940int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
1860int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC; 1941int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
@@ -1867,9 +1948,15 @@ int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
1867#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp) 1948#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp)
1868#endif 1949#endif
1869 1950
1951#if !ENABLE_PLATFORM_MINGW32 || ENABLE_FEATURE_EXTRA_FILE_DATA
1870char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC; 1952char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC;
1871void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC; 1953void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
1872void reset_ino_dev_hashtable(void) FAST_FUNC; 1954void reset_ino_dev_hashtable(void) FAST_FUNC;
1955#else
1956#define add_to_ino_dev_hashtable(s, n) (void)0
1957#define is_in_ino_dev_hashtable(s) NULL
1958#define reset_ino_dev_hashtable()
1959#endif
1873#ifdef __GLIBC__ 1960#ifdef __GLIBC__
1874/* At least glibc has horrendously large inline for this, so wrap it */ 1961/* At least glibc has horrendously large inline for this, so wrap it */
1875unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC; 1962unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
@@ -1947,6 +2034,9 @@ enum {
1947 * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout 2034 * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout
1948 */ 2035 */
1949int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC; 2036int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
2037#if ENABLE_PLATFORM_MINGW32
2038int64_t windows_read_key(int fd, char *buffer, int timeout) FAST_FUNC;
2039#endif
1950/* This version loops on EINTR: */ 2040/* This version loops on EINTR: */
1951int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC; 2041int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC;
1952void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC; 2042void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
@@ -1960,8 +2050,14 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1960# else 2050# else
1961# define MAX_HISTORY 0 2051# define MAX_HISTORY 0
1962# endif 2052# endif
2053# if defined CONFIG_FEATURE_EDITING_HISTORY_DEFAULT && CONFIG_FEATURE_EDITING_HISTORY_DEFAULT > 0
2054# define DEFAULT_HISTORY (CONFIG_FEATURE_EDITING_HISTORY_DEFAULT + 0)
2055# else
2056# define DEFAULT_HISTORY 0
2057# endif
1963typedef const char *get_exe_name_t(int i) FAST_FUNC; 2058typedef const char *get_exe_name_t(int i) FAST_FUNC;
1964typedef const char *sh_get_var_t(const char *name) FAST_FUNC; 2059typedef const char *sh_get_var_t(const char *name) FAST_FUNC;
2060typedef int sh_accept_glob_t(const char *name) FAST_FUNC;
1965typedef struct line_input_t { 2061typedef struct line_input_t {
1966 int flags; 2062 int flags;
1967 int timeout; 2063 int timeout;
@@ -1975,6 +2071,9 @@ typedef struct line_input_t {
1975# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH 2071# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
1976 /* function to fetch additional application-specific names to match */ 2072 /* function to fetch additional application-specific names to match */
1977 get_exe_name_t *get_exe_name; 2073 get_exe_name_t *get_exe_name;
2074# if ENABLE_ASH_GLOB_OPTIONS
2075 sh_accept_glob_t *sh_accept_glob;
2076# endif
1978# endif 2077# endif
1979# endif 2078# endif
1980# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ 2079# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \
@@ -2009,6 +2108,9 @@ enum {
2009 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI, 2108 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI,
2010 WITH_PATH_LOOKUP = 0x10, 2109 WITH_PATH_LOOKUP = 0x10,
2011 LI_INTERRUPTIBLE = 0x20, 2110 LI_INTERRUPTIBLE = 0x20,
2111#if ENABLE_PLATFORM_MINGW32
2112 IGNORE_CTRL_C = 0x40,
2113#endif
2012 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION | LI_INTERRUPTIBLE, 2114 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION | LI_INTERRUPTIBLE,
2013}; 2115};
2014line_input_t *new_line_input_t(int flags) FAST_FUNC; 2116line_input_t *new_line_input_t(int flags) FAST_FUNC;
@@ -2038,6 +2140,10 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
2038 2140
2039unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz); 2141unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz);
2040 2142
2143#if ENABLE_PLATFORM_MINGW32
2144# undef COMM_LEN
2145# define COMM_LEN 32
2146#endif
2041#ifndef COMM_LEN 2147#ifndef COMM_LEN
2042# ifdef TASK_COMM_LEN 2148# ifdef TASK_COMM_LEN
2043enum { COMM_LEN = TASK_COMM_LEN }; 2149enum { COMM_LEN = TASK_COMM_LEN };
@@ -2075,7 +2181,13 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
2075 void (*cb)(struct smaprec *, void *), void *data); 2181 void (*cb)(struct smaprec *, void *), void *data);
2076 2182
2077typedef struct procps_status_t { 2183typedef struct procps_status_t {
2184#if !ENABLE_PLATFORM_MINGW32
2078 DIR *dir; 2185 DIR *dir;
2186#else
2187 HANDLE snapshot;
2188 DWORD *pids;
2189 int npids;
2190#endif
2079 IF_FEATURE_SHOW_THREADS(DIR *task_dir;) 2191 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
2080 uint8_t shift_pages_to_bytes; 2192 uint8_t shift_pages_to_bytes;
2081 uint8_t shift_pages_to_kb; 2193 uint8_t shift_pages_to_kb;
@@ -2309,11 +2421,18 @@ extern const char bb_path_wtmp_file[] ALIGN1;
2309#define bb_path_motd_file "/etc/motd" 2421#define bb_path_motd_file "/etc/motd"
2310 2422
2311#define bb_dev_null "/dev/null" 2423#define bb_dev_null "/dev/null"
2424#if ENABLE_PLATFORM_MINGW32
2425#define bb_busybox_exec_path get_busybox_exec_path()
2426extern char bb_comm[];
2427extern char bb_command_line[];
2428#else
2312extern const char bb_busybox_exec_path[] ALIGN1; 2429extern const char bb_busybox_exec_path[] ALIGN1;
2430#endif
2313/* allow default system PATH to be extended via CFLAGS */ 2431/* allow default system PATH to be extended via CFLAGS */
2314#ifndef BB_ADDITIONAL_PATH 2432#ifndef BB_ADDITIONAL_PATH
2315#define BB_ADDITIONAL_PATH "" 2433#define BB_ADDITIONAL_PATH ""
2316#endif 2434#endif
2435#if !ENABLE_PLATFORM_MINGW32
2317#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH 2436#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH
2318extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */ 2437extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2319#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH")) 2438#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
@@ -2321,6 +2440,23 @@ extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2321 * but I want to save a few bytes here: 2440 * but I want to save a few bytes here:
2322 */ 2441 */
2323#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) 2442#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
2443#define PATH_SEP ':'
2444#define PATH_SEP_STR ":"
2445#else
2446#define BB_PATH_ROOT_PATH "PATH=C:/Windows/System32;C:/Windows" BB_ADDITIONAL_PATH
2447extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2448#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
2449#define bb_default_path (bb_PATH_root_path + sizeof("PATH"))
2450#define PATH_SEP ';'
2451#define PATH_SEP_STR ";"
2452extern const char bbvar[] ALIGN1;
2453#define bbafter(p) (p + sizeof(#p))
2454#define BB_OVERRIDE_APPLETS bbvar
2455#define BB_SKIP_ANSI_EMULATION bbafter(BB_OVERRIDE_APPLETS)
2456#define BB_TERMINAL_MODE bbafter(BB_SKIP_ANSI_EMULATION)
2457#define BB_SYSTEMROOT bbafter(BB_TERMINAL_MODE)
2458#define BB_CRITICAL_ERROR_DIALOGS bbafter(BB_SYSTEMROOT)
2459#endif
2324 2460
2325extern const int const_int_0; 2461extern const int const_int_0;
2326//extern const int const_int_1; 2462//extern const int const_int_1;
@@ -2350,10 +2486,15 @@ static ALWAYS_INLINE void* not_const_pp(const void *p)
2350 ); 2486 );
2351 return pp; 2487 return pp;
2352} 2488}
2489# if !ENABLE_PLATFORM_MINGW32
2353# define ASSIGN_CONST_PTR(pptr, v) do { \ 2490# define ASSIGN_CONST_PTR(pptr, v) do { \
2354 *(void**)not_const_pp(pptr) = (void*)(v); \ 2491 *(void**)not_const_pp(pptr) = (void*)(v); \
2355 barrier(); \ 2492 barrier(); \
2356} while (0) 2493} while (0)
2494#else
2495/* On Windows it seems necessary for this to be a function too. */
2496void ASSIGN_CONST_PTR(const void *pptr, const void *ptr) FAST_FUNC;
2497#endif
2357/* XZALLOC_CONST_PTR() is an out-of-line function to prevent 2498/* XZALLOC_CONST_PTR() is an out-of-line function to prevent
2358 * clang from reading pointer before it is assigned. 2499 * clang from reading pointer before it is assigned.
2359 */ 2500 */
diff --git a/include/mingw.h b/include/mingw.h
new file mode 100644
index 000000000..c41c0f91e
--- /dev/null
+++ b/include/mingw.h
@@ -0,0 +1,671 @@
1
2#define NOIMPL(name,...) static inline int name(__VA_ARGS__) { errno = ENOSYS; return -1; }
3#define IMPL(name,ret,retval,...) static inline ret name(__VA_ARGS__) { return retval; }
4
5/* Use 64-bit time on 32-bit platforms. */
6#if !defined(_WIN64)
7# define time_t __time64_t
8# define ctime(t) _ctime64(t)
9# define localtime(t) _localtime64(t)
10# define time(t) _time64(t)
11# define gmtime(t) _gmtime64(t)
12# define mktime(t) _mktime64(t)
13# define timespec _timespec64
14#endif
15
16/*
17 * sys/types.h
18 */
19typedef int gid_t;
20typedef int uid_t;
21
22#define DEFAULT_UID 4095
23#define DEFAULT_GID DEFAULT_UID
24
25/*
26 * arpa/inet.h
27 */
28static inline unsigned int git_ntohl(unsigned int x) { return (unsigned int)ntohl(x); }
29#define ntohl git_ntohl
30int inet_aton(const char *cp, struct in_addr *inp);
31int inet_pton(int af, const char *src, void *dst);
32
33/*
34 * fcntl.h
35 */
36#define F_DUPFD 0
37#define F_GETFD 1
38#define F_SETFD 2
39#define F_GETFL 3
40#define F_SETFL 3
41#define FD_CLOEXEC 0x1
42#define O_NONBLOCK 0
43#define O_NOFOLLOW 0
44#define O_NOCTTY 0
45#define O_DIRECT 0
46#define O_SPECIAL 0x800000
47
48#define AT_FDCWD -100
49#define AT_SYMLINK_NOFOLLOW 0x100
50
51/*
52 * grp.h
53 */
54
55struct group {
56 char *gr_name;
57 char *gr_passwd;
58 gid_t gr_gid;
59 char **gr_mem;
60};
61IMPL(getgrnam,struct group *,NULL,const char *name UNUSED_PARAM);
62struct group *getgrgid(gid_t gid);
63NOIMPL(initgroups,const char *group UNUSED_PARAM,gid_t gid UNUSED_PARAM);
64static inline void endgrent(void) {}
65int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
66
67/*
68 * limits.h
69 */
70#define NAME_MAX 255
71#define MAXSYMLINKS 20
72
73#ifdef LONG_MAX
74# if LONG_MAX == 2147483647
75# define LONG_BIT 32
76# else
77/* Safe assumption. */
78# define LONG_BIT 64
79# endif
80#elif defined __LONG_MAX__
81# if __LONG_MAX__ == 2147483647
82# define LONG_BIT 32
83# else
84/* Safe assumption. */
85# define LONG_BIT 64
86# endif
87#endif
88
89/*
90 * netdb.h
91 */
92
93typedef int sa_family_t;
94
95/*
96 * linux/un.h
97 */
98struct sockaddr_un {
99 sa_family_t sun_family;
100 char sun_path[1]; /* to make compiler happy, don't bother */
101};
102
103/*
104 * pwd.h
105 */
106struct passwd {
107 char *pw_name;
108 char *pw_passwd;
109 char *pw_gecos;
110 char *pw_dir;
111 char *pw_shell;
112 uid_t pw_uid;
113 gid_t pw_gid;
114};
115
116struct passwd *getpwnam(const char *name);
117struct passwd *getpwuid(uid_t uid);
118static inline void setpwent(void) {}
119static inline void endpwent(void) {}
120IMPL(getpwent_r,int,ENOENT,struct passwd *pwbuf UNUSED_PARAM,char *buf UNUSED_PARAM,size_t buflen UNUSED_PARAM,struct passwd **pwbufp UNUSED_PARAM);
121IMPL(getpwent,struct passwd *,NULL,void)
122
123/*
124 * signal.h
125 */
126#define SIGHUP 1
127#define SIGQUIT 3
128#define SIGKILL 9
129#define SIGPIPE 13
130
131#define SIG_UNBLOCK 1
132
133typedef void (*sighandler_t)(int);
134sighandler_t winansi_signal(int signum, sighandler_t handler);
135#define signal(s, h) winansi_signal(s, h)
136
137/*
138 * stdio.h
139 */
140#undef fseeko
141#define fseeko(f,o,w) fseek(f,o,w)
142
143int fdprintf(int fd, const char *format, ...);
144FILE* mingw_fopen(const char *filename, const char *mode);
145int mingw_rename(const char*, const char*);
146#define fopen mingw_fopen
147#define rename mingw_rename
148
149FILE *mingw_popen(const char *cmd, const char *mode);
150int mingw_popen_fd(const char *exe, const char *cmd, const char *mode,
151 int fd0, pid_t *pid);
152int mingw_pclose(FILE *fd);
153pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode);
154#undef popen
155#undef pclose
156#define popen mingw_popen
157#define pclose mingw_pclose
158
159IMPL(setlinebuf, void, ,FILE *fd UNUSED_PARAM)
160
161/*
162 * ANSI emulation wrappers
163 */
164
165BOOL conToCharBuffA(LPSTR d, DWORD len);
166BOOL conToCharA(LPSTR d);
167
168// same as ReadConsoleInputA, but delivers UTF8 regardless of console CP
169BOOL readConsoleInput_utf8(HANDLE h, INPUT_RECORD *r, DWORD len, DWORD *got);
170
171void set_title(const char *str);
172int get_title(char *buf, int len);
173void move_cursor_row(int n);
174void reset_screen(void);
175int winansi_putchar(int c);
176int winansi_puts(const char *s);
177size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
178int winansi_fputs(const char *str, FILE *stream);
179int winansi_fputc(int c, FILE *stream);
180int winansi_vsnprintf(char *buf, size_t size, const char *format, va_list list);
181int winansi_vfprintf(FILE *stream, const char *format, va_list list);
182int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
183int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
184int winansi_write(int fd, const void *buf, size_t count);
185int winansi_read(int fd, void *buf, size_t count);
186size_t winansi_fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
187int winansi_getc(FILE *stream);
188int winansi_getchar(void);
189char *winansi_fgets(char *s, int size, FILE *stream);
190void console_write(const char *str, int len);
191
192#define putchar winansi_putchar
193#define puts winansi_puts
194#define fwrite winansi_fwrite
195#define fputs winansi_fputs
196#define fputc winansi_fputc
197#if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO
198#define vsnprintf(buf, size, ...) winansi_vsnprintf(buf, size, __VA_ARGS__)
199#endif
200#define vfprintf(stream, ...) winansi_vfprintf(stream, __VA_ARGS__)
201#define vprintf(...) winansi_vfprintf(stdout, __VA_ARGS__)
202#define printf(...) winansi_printf(__VA_ARGS__)
203#define fprintf(...) winansi_fprintf(__VA_ARGS__)
204#define write winansi_write
205#define read winansi_read
206#define fread winansi_fread
207#define getc winansi_getc
208#define fgetc winansi_getc
209#define getchar winansi_getchar
210#define fgets winansi_fgets
211
212/*
213 * stdlib.h
214 */
215#define WTERMSIG(x) ((x) & 0x7f)
216#define WIFEXITED(x) (WTERMSIG(x) == 0)
217#define WEXITSTATUS(x) (((x) & 0xff00) >> 8)
218#define WIFSIGNALED(x) (((signed char) (((x) & 0x7f) + 1) >> 1) > 0)
219#define WCOREDUMP(x) 0
220#define WIFSTOPPED(x) 0
221
222int mingw_system(const char *cmd);
223#define system mingw_system
224
225int clearenv(void);
226char *mingw_getenv(const char *name);
227int mingw_putenv(const char *env);
228char *mingw_mktemp(char *template);
229int mkstemp(char *template);
230char *realpath(const char *path, char *resolved_path);
231int setenv(const char *name, const char *value, int replace);
232int unsetenv(const char *env);
233
234#define getenv mingw_getenv
235#define putenv mingw_putenv
236#define mktemp mingw_mktemp
237
238/*
239 * string.h
240 */
241char *strndup(char const *s, size_t n);
242char *mingw_strerror(int errnum);
243char *strsignal(int sig);
244int strverscmp(const char *s1, const char *s2);
245
246#define strerror mingw_strerror
247
248/*
249 * strings.h
250 */
251#if !defined(__GNUC__)
252int ffs(int i);
253#else
254# define ffs(i) __builtin_ffs(i)
255#endif
256
257/*
258 * sys/ioctl.h
259 */
260
261#define TIOCGWINSZ 0x5413
262
263int ioctl(int fd, int code, ...);
264
265/*
266 * sys/socket.h
267 */
268#define hstrerror strerror
269
270#define SHUT_WR SD_SEND
271
272int mingw_socket(int domain, int type, int protocol);
273int mingw_connect(int sockfd, const struct sockaddr *sa, size_t sz);
274int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz);
275int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen);
276int mingw_shutdown(int sockfd, int how);
277int mingw_listen(int sockfd, int backlog);
278int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz);
279int mingw_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
280 struct timeval *timeout);
281int mingw_getpeername(int fd, struct sockaddr *sa, socklen_t *sz);
282int mingw_gethostname(char *host, int namelen);
283int mingw_getaddrinfo(const char *node, const char *service,
284 const struct addrinfo *hints, struct addrinfo **res);
285struct hostent *mingw_gethostbyaddr(const void *addr, socklen_t len, int type);
286
287#define socket mingw_socket
288#define connect mingw_connect
289#define listen mingw_listen
290#define bind mingw_bind
291#define setsockopt mingw_setsockopt
292#define shutdown mingw_shutdown
293#define accept mingw_accept
294#define select mingw_select
295#define getpeername mingw_getpeername
296#define gethostname mingw_gethostname
297#define getaddrinfo mingw_getaddrinfo
298#define gethostbyaddr mingw_gethostbyaddr
299
300/*
301 * sys/time.h
302 */
303#ifndef _TIMESPEC_DEFINED
304#define _TIMESPEC_DEFINED
305struct timespec {
306 time_t tv_sec;
307 long int tv_nsec;
308};
309#endif
310
311typedef int clockid_t;
312#define CLOCK_REALTIME 0
313
314time_t timegm(struct tm *tm);
315
316int nanosleep(const struct timespec *req, struct timespec *rem);
317int clock_gettime(clockid_t clockid, struct timespec *tp);
318int clock_settime(clockid_t clockid, const struct timespec *tp);
319
320/*
321 * sys/stat.h
322 */
323#define S_ISUID 04000
324#define S_ISGID 02000
325#define S_ISVTX 01000
326#ifndef S_IRWXU
327#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
328#endif
329#define S_IRWXG (S_IRWXU >> 3)
330#define S_IRWXO (S_IRWXG >> 3)
331
332#define S_IFSOCK 0140000
333#define S_IFLNK 0120000 /* Symbolic link */
334#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
335#define S_ISSOCK(x) 0
336
337#define S_IRGRP (S_IRUSR >> 3)
338#define S_IWGRP (S_IWUSR >> 3)
339#define S_IXGRP (S_IXUSR >> 3)
340#define S_IROTH (S_IRGRP >> 3)
341#define S_IWOTH (S_IWGRP >> 3)
342#define S_IXOTH (S_IXGRP >> 3)
343
344mode_t mingw_umask(mode_t mode);
345#define umask mingw_umask
346
347#define DEFAULT_UMASK 0002
348
349IMPL(fchmod,int,0,int fildes UNUSED_PARAM, mode_t mode UNUSED_PARAM);
350NOIMPL(fchown,int fd UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
351int mingw_mkdir(const char *path, int mode);
352int mingw_chdir(const char *path);
353int mingw_chmod(const char *path, int mode);
354
355#define mkdir mingw_mkdir
356#define chdir mingw_chdir
357#define chmod mingw_chmod
358
359#if ENABLE_LFS && !defined(__MINGW64_VERSION_MAJOR)
360# define off_t off64_t
361#endif
362
363typedef int nlink_t;
364typedef int blksize_t;
365typedef off_t blkcnt_t;
366#if ENABLE_FEATURE_EXTRA_FILE_DATA
367#define ino_t uint64_t
368#endif
369
370struct mingw_stat {
371 dev_t st_dev;
372 ino_t st_ino;
373 mode_t st_mode;
374 nlink_t st_nlink;
375 uid_t st_uid;
376 gid_t st_gid;
377 dev_t st_rdev;
378 off_t st_size;
379 struct timespec st_atim;
380 struct timespec st_mtim;
381 struct timespec st_ctim;
382 blksize_t st_blksize;
383 blkcnt_t st_blocks;
384 DWORD st_attr;
385 DWORD st_tag;
386};
387#define st_atime st_atim.tv_sec
388#define st_mtime st_mtim.tv_sec
389#define st_ctime st_ctim.tv_sec
390
391int count_subdirs(const char *pathname);
392int mingw_lstat(const char *file_name, struct mingw_stat *buf);
393int mingw_stat(const char *file_name, struct mingw_stat *buf);
394int mingw_fstat(int fd, struct mingw_stat *buf);
395#undef lstat
396#undef stat
397#undef fstat
398#define lstat mingw_lstat
399#define stat mingw_stat
400#define fstat mingw_fstat
401
402#define UTIME_NOW ((1l << 30) - 1l)
403#define UTIME_OMIT ((1l << 30) - 2l)
404
405int utimensat(int fd, const char *path, const struct timespec times[2],
406 int flags);
407int futimens(int fd, const struct timespec times[2]);
408
409/*
410 * sys/sysinfo.h
411 */
412struct sysinfo {
413 long uptime; /* Seconds since boot */
414 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
415 unsigned long totalram; /* Total usable main memory size */
416 unsigned long freeram; /* Available memory size */
417 unsigned long sharedram; /* Amount of shared memory */
418 unsigned long bufferram; /* Memory used by buffers */
419 unsigned long totalswap; /* Total swap space size */
420 unsigned long freeswap; /* Swap space still available */
421 unsigned short procs; /* Number of current processes */
422 unsigned long totalhigh; /* Total high memory size */
423 unsigned long freehigh; /* Available high memory size */
424 unsigned int mem_unit; /* Memory unit size in bytes */
425};
426
427int sysinfo(struct sysinfo *info);
428
429/*
430 * sys/sysmacros.h
431 */
432#define makedev(a,b) 0*(a)*(b) /* avoid unused warning */
433#define minor(x) 0
434#define major(x) 0
435
436/*
437 * sys/wait.h
438 */
439#define WNOHANG 1
440#define WUNTRACED 2
441pid_t waitpid(pid_t pid, int *status, int options);
442pid_t mingw_wait3(pid_t pid, int *status, int options, struct rusage *rusage);
443
444/*
445 * time.h
446 */
447struct tm *gmtime_r(const time_t *timep, struct tm *result);
448struct tm *localtime_r(const time_t *timep, struct tm *result);
449char *strptime(const char *s, const char *format, struct tm *tm);
450char *mingw_strptime(const char *s, const char *format, struct tm *tm, long *gmt);
451size_t mingw_strftime(char *buf, size_t max, const char *format, const struct tm *tm);
452
453#define strftime mingw_strftime
454
455/*
456 * times.h
457 */
458#define clock_t long
459
460struct tms {
461 clock_t tms_utime; /* user CPU time */
462 clock_t tms_stime; /* system CPU time */
463 clock_t tms_cutime; /* user CPU time of children */
464 clock_t tms_cstime; /* system CPU time of children */
465};
466
467clock_t times(struct tms *buf);
468
469/*
470 * unistd.h
471 */
472#define PIPE_BUF 8192
473
474#define _SC_CLK_TCK 2
475
476#define TICKS_PER_SECOND 100
477#define MS_PER_TICK 10
478#define HNSEC_PER_TICK 100000
479
480IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM);
481IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
482NOIMPL(chroot,const char *root UNUSED_PARAM);
483NOIMPL(fchdir,int fd UNUSED_PARAM);
484int mingw_dup2 (int fd, int fdto);
485char *mingw_getcwd(char *pointer, int len);
486off_t mingw_lseek(int fd, off_t offset, int whence);
487
488
489int getuid(void);
490#define getgid getuid
491#define geteuid getuid
492#define getegid getuid
493int getgroups(int n, gid_t *groups);
494pid_t getppid(void);
495NOIMPL(getsid,pid_t pid UNUSED_PARAM);
496int getlogin_r(char *buf, size_t len);
497int fcntl(int fd, int cmd, ...);
498int fsync(int fd);
499int kill(pid_t pid, int sig);
500int link(const char *oldpath, const char *newpath);
501NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM);
502/* order of devices must match that in get_dev_type */
503enum {DEV_NULL, DEV_ZERO, DEV_URANDOM, NOT_DEVICE = -1};
504int get_dev_type(const char *filename);
505void update_special_fd(int dev, int fd);
506int mingw_open (const char *filename, int oflags, ...);
507
508/* functions which add O_SPECIAL to open(2) to allow access to devices */
509int mingw_xopen(const char *filename, int oflags);
510ssize_t mingw_open_read_close(const char *fn, void *buf, size_t size) FAST_FUNC;
511
512#ifndef IO_REPARSE_TAG_APPEXECLINK
513# define IO_REPARSE_TAG_APPEXECLINK 0x8000001b
514#endif
515
516ssize_t mingw_read(int fd, void *buf, size_t count);
517int mingw_close(int fd);
518int pipe(int filedes[2]);
519NOIMPL(setgid,gid_t gid UNUSED_PARAM);
520NOIMPL(setegid,gid_t gid UNUSED_PARAM);
521NOIMPL(setsid,void);
522NOIMPL(setuid,uid_t gid UNUSED_PARAM);
523NOIMPL(seteuid,uid_t gid UNUSED_PARAM);
524unsigned int sleep(unsigned int seconds);
525int symlink(const char *target, const char *linkpath);
526int create_junction(const char *oldpath, const char *newpath);
527long sysconf(int name);
528IMPL(getpagesize,int,4096,void);
529NOIMPL(ttyname_r,int fd UNUSED_PARAM, char *buf UNUSED_PARAM, int sz UNUSED_PARAM);
530int mingw_unlink(const char *pathname);
531int mingw_access(const char *name, int mode);
532int mingw_rmdir(const char *name);
533void mingw_sync(void);
534int mingw_isatty(int fd);
535
536#define dup2 mingw_dup2
537#define getcwd mingw_getcwd
538#define lchown chown
539#define open mingw_open
540#define close mingw_close
541#define unlink mingw_unlink
542#define rmdir mingw_rmdir
543#define sync mingw_sync
544#undef lseek
545#define lseek mingw_lseek
546
547#undef access
548#define access mingw_access
549#define isatty mingw_isatty
550
551/*
552 * utime.h
553 */
554int utimes(const char *file_name, const struct timeval times[2]);
555
556/*
557 * Functions with different prototypes in BusyBox and WIN32
558 */
559#define itoa bb_itoa
560#define strrev bb_strrev
561
562/*
563 * MinGW specific
564 */
565#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
566#define is_unc_path(x) (strlen(x) > 4 && is_dir_sep(x[0]) && \
567 is_dir_sep(x[1]) && !is_dir_sep(x[2]))
568
569typedef struct {
570 char *path;
571 char *name;
572 char *opts;
573 char buf[100];
574} interp_t;
575
576int FAST_FUNC parse_interpreter(const char *cmd, interp_t *interp);
577char ** FAST_FUNC grow_argv(char **argv, int n);
578pid_t FAST_FUNC mingw_spawn(char **argv);
579intptr_t FAST_FUNC mingw_spawn_detach(char **argv);
580intptr_t FAST_FUNC mingw_spawn_proc(const char **argv);
581int mingw_execv(const char *cmd, char *const *argv);
582int httpd_execv_detach(const char *cmd, char *const *argv);
583int mingw_execvp(const char *cmd, char *const *argv);
584int mingw_execve(const char *cmd, char *const *argv, char *const *envp);
585#define spawn mingw_spawn
586#define execvp mingw_execvp
587#define execve mingw_execve
588#define execv mingw_execv
589#define HTTPD_DETACH (8)
590
591#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
592
593BOOL WINAPI kill_child_ctrl_handler(DWORD dwCtrlType);
594int FAST_FUNC is_valid_signal(int number);
595int exit_code_to_wait_status(DWORD win_exit_code);
596int exit_code_to_posix(DWORD win_exit_code);
597
598#define find_mount_point(n, s) find_mount_point(n)
599
600char *is_prefixed_with_case(const char *string, const char *key) FAST_FUNC;
601char *is_suffixed_with_case(const char *string, const char *key) FAST_FUNC;
602
603#define VT_OUTPUT 1
604#define VT_INPUT 2
605
606/*
607 * helpers
608 */
609
610const char *get_busybox_exec_path(void);
611void init_winsock(void);
612
613int has_bat_suffix(const char *p);
614int has_exe_suffix(const char *p);
615int has_exe_suffix_or_dot(const char *name);
616char *alloc_ext_space(const char *path);
617int add_win32_extension(char *p);
618char *file_is_win32_exe(const char *name);
619
620#if ENABLE_UNICODE_SUPPORT
621/*
622 * windows wchar_t is 16 bit, while linux (and busybox expectation) is 32.
623 * so when (busybox) unicode.h is included, wchar_t is 32 bit.
624 * Without unicode.h, MINGW_BB_WCHAR_T is busybox wide char (32),
625 * and wchar_t is Windows wide char (16).
626 */
627#define MINGW_BB_WCHAR_T uint32_t /* keep in sync with unicode.h */
628
629MINGW_BB_WCHAR_T *bs_to_slash_u(MINGW_BB_WCHAR_T *p) FAST_FUNC;
630#endif
631
632char *bs_to_slash(char *p) FAST_FUNC;
633void slash_to_bs(char *p) FAST_FUNC;
634void strip_dot_space(char *p) FAST_FUNC;
635size_t remove_cr(char *p, size_t len) FAST_FUNC;
636
637int err_win_to_posix(void);
638
639ULONGLONG CompatGetTickCount64(void);
640#define GetTickCount64 CompatGetTickCount64
641
642ssize_t get_random_bytes(void *buf, ssize_t count);
643int enumerate_links(const char *file, char *name);
644
645int unc_root_len(const char *dir) FAST_FUNC;
646int root_len(const char *path) FAST_FUNC;
647const char *get_system_drive(void) FAST_FUNC;
648int chdir_system_drive(void);
649char *xabsolute_path(char *path) FAST_FUNC;
650char *get_drive_cwd(const char *path, char *buffer, int size) FAST_FUNC;
651void fix_path_case(char *path) FAST_FUNC;
652void make_sparse(int fd, off_t start, off_t end) FAST_FUNC;
653int terminal_mode(int reset) FAST_FUNC;
654int unix_path(const char *path) FAST_FUNC;
655int has_path(const char *file) FAST_FUNC;
656int is_relative_path(const char *path) FAST_FUNC;
657char *get_last_slash(const char *path) FAST_FUNC;
658const char *applet_to_exe(const char *name) FAST_FUNC;
659char *get_user_name(void);
660char *quote_arg(const char *arg) FAST_FUNC;
661char *find_first_executable(const char *name) FAST_FUNC;
662char *xappendword(const char *str, const char *word) FAST_FUNC;
663int windows_env(void);
664void change_critical_error_dialogs(const char *newval) FAST_FUNC;
665char *exe_relative_path(const char *tail) FAST_FUNC;
666enum {
667 ELEVATED_PRIVILEGE = 1,
668 ADMIN_ENABLED = 2
669};
670int elevation_state(void);
671void set_interp(int i) FAST_FUNC;
diff --git a/include/platform.h b/include/platform.h
index ea0512f36..5795a0cf3 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -7,6 +7,20 @@
7#ifndef BB_PLATFORM_H 7#ifndef BB_PLATFORM_H
8#define BB_PLATFORM_H 1 8#define BB_PLATFORM_H 1
9 9
10#if ENABLE_PLATFORM_MINGW32
11# if !defined(__MINGW32__) /* HOSTCC is called */
12# undef ENABLE_PLATFORM_MINGW32
13# else
14# undef __USE_MINGW_ANSI_STDIO
15# define __USE_MINGW_ANSI_STDIO 0
16# undef _WIN32_WINNT
17# define _WIN32_WINNT 0x502
18# endif
19#else
20# if defined(__MINGW32__)
21# error "You must select target platform MS Windows, or it won't build"
22# endif
23#endif
10 24
11/* Convenience macros to test the version of gcc. */ 25/* Convenience macros to test the version of gcc. */
12#undef __GNUC_PREREQ 26#undef __GNUC_PREREQ
@@ -135,7 +149,7 @@
135 149
136/* Make all declarations hidden (-fvisibility flag only affects definitions) */ 150/* Make all declarations hidden (-fvisibility flag only affects definitions) */
137/* (don't include system headers after this until corresponding pop!) */ 151/* (don't include system headers after this until corresponding pop!) */
138#if __GNUC_PREREQ(4,1) && !defined(__CYGWIN__) 152#if __GNUC_PREREQ(4,1) && !defined(__CYGWIN__) && !ENABLE_PLATFORM_MINGW32
139# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN _Pragma("GCC visibility push(hidden)") 153# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN _Pragma("GCC visibility push(hidden)")
140# define POP_SAVED_FUNCTION_VISIBILITY _Pragma("GCC visibility pop") 154# define POP_SAVED_FUNCTION_VISIBILITY _Pragma("GCC visibility pop")
141#else 155#else
@@ -164,6 +178,13 @@
164# define bswap_64 __bswap64 178# define bswap_64 __bswap64
165# define bswap_32 __bswap32 179# define bswap_32 __bswap32
166# define bswap_16 __bswap16 180# define bswap_16 __bswap16
181#elif ENABLE_PLATFORM_MINGW32
182# define __BIG_ENDIAN 0
183# define __LITTLE_ENDIAN 1
184# define __BYTE_ORDER __LITTLE_ENDIAN
185# define bswap_16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0xFF) << 8))
186# define bswap_32(x) ((bswap_16(((x) & 0xFFFF0000L) >> 16)) | (bswap_16((x) & 0xFFFFL) << 16))
187# define bswap_64(x) ((bswap_32(((x) & 0xFFFFFFFF00000000LL) >> 32)) | (bswap_32((x) & 0xFFFFFFFFLL) << 32))
167#else 188#else
168# include <byteswap.h> 189# include <byteswap.h>
169# include <endian.h> 190# include <endian.h>
@@ -443,6 +464,26 @@ typedef unsigned smalluint;
443# endif 464# endif
444#endif 465#endif
445 466
467#if ENABLE_PLATFORM_MINGW32
468# undef HAVE_FDATASYNC
469# undef HAVE_DPRINTF
470# undef HAVE_GETLINE
471# undef HAVE_MEMRCHR
472# undef HAVE_MKDTEMP
473# undef HAVE_SETBIT
474# undef HAVE_STPCPY
475# undef HAVE_STPNCPY
476# undef HAVE_STRCASESTR
477# undef HAVE_STRCHRNUL
478# undef HAVE_STRSEP
479#if !defined(__MINGW64_VERSION_MAJOR)
480# undef HAVE_VASPRINTF
481#endif
482# undef HAVE_UNLOCKED_STDIO
483# undef HAVE_UNLOCKED_LINE_OPS
484# undef HAVE_PRINTF_PERCENTM
485#endif
486
446#if defined(__WATCOMC__) 487#if defined(__WATCOMC__)
447# undef HAVE_DPRINTF 488# undef HAVE_DPRINTF
448# undef HAVE_GETLINE 489# undef HAVE_GETLINE
@@ -563,6 +604,7 @@ extern int dprintf(int fd, const char *format, ...);
563#endif 604#endif
564 605
565#ifndef HAVE_MEMRCHR 606#ifndef HAVE_MEMRCHR
607#include <stddef.h>
566extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC; 608extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC;
567#endif 609#endif
568 610
@@ -626,6 +668,7 @@ extern int usleep(unsigned) FAST_FUNC;
626#endif 668#endif
627 669
628#ifndef HAVE_VASPRINTF 670#ifndef HAVE_VASPRINTF
671# include <stdarg.h>
629extern int vasprintf(char **string_ptr, const char *format, va_list p) FAST_FUNC; 672extern int vasprintf(char **string_ptr, const char *format, va_list p) FAST_FUNC;
630#endif 673#endif
631 674
diff --git a/include/unicode.h b/include/unicode.h
index 0317a2151..cdf35acb7 100644
--- a/include/unicode.h
+++ b/include/unicode.h
@@ -33,7 +33,11 @@ enum {
33 33
34# if CONFIG_LAST_SUPPORTED_WCHAR < 126 || CONFIG_LAST_SUPPORTED_WCHAR >= 0x30000 34# if CONFIG_LAST_SUPPORTED_WCHAR < 126 || CONFIG_LAST_SUPPORTED_WCHAR >= 0x30000
35# undef CONFIG_LAST_SUPPORTED_WCHAR 35# undef CONFIG_LAST_SUPPORTED_WCHAR
36# if ENABLE_PLATFORM_MINGW32
37# define CONFIG_LAST_SUPPORTED_WCHAR 0x10ffff /* full unicode range */
38# else
36# define CONFIG_LAST_SUPPORTED_WCHAR 0x2ffff 39# define CONFIG_LAST_SUPPORTED_WCHAR 0x2ffff
40# endif
37# endif 41# endif
38 42
39# if CONFIG_LAST_SUPPORTED_WCHAR < 0x300 43# if CONFIG_LAST_SUPPORTED_WCHAR < 0x300
@@ -87,6 +91,21 @@ void reinit_unicode(const char *LANG) FAST_FUNC;
87# undef MB_CUR_MAX 91# undef MB_CUR_MAX
88# define MB_CUR_MAX 6 92# define MB_CUR_MAX 6
89 93
94#if ENABLE_PLATFORM_MINGW32
95 #undef wint_t
96 #undef mbstate_t
97 #undef mbstowcs
98 #undef wcstombs
99 #undef wcrtomb
100 #undef iswspace
101 #undef iswalnum
102 #undef iswpunct
103 #undef wcwidth
104
105 #undef wchar_t
106 #define wchar_t uint32_t /* keep in sync with MINGW_BB_WCHAR_T */
107#endif
108
90/* Prevent name collisions */ 109/* Prevent name collisions */
91# define wint_t bb_wint_t 110# define wint_t bb_wint_t
92# define mbstate_t bb_mbstate_t 111# define mbstate_t bb_mbstate_t