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.h272
-rw-r--r--include/mingw.h674
-rw-r--r--include/platform.h45
-rw-r--r--include/unicode.h19
6 files changed, 987 insertions, 38 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..4cacdacba 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",
@@ -263,6 +281,12 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
263# endif 281# endif
264#endif 282#endif
265 283
284#if ENABLE_FEATURE_TLS_SCHANNEL
285# define SECURITY_WIN32
286# include <windows.h>
287# include <security.h>
288#endif
289
266/* Tested to work correctly with all int types (IIRC :]) */ 290/* Tested to work correctly with all int types (IIRC :]) */
267#define MAXINT(T) (T)( \ 291#define MAXINT(T) (T)( \
268 ((T)-1) > 0 \ 292 ((T)-1) > 0 \
@@ -276,6 +300,20 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
276 : ((T)1 << (sizeof(T)*8-1)) \ 300 : ((T)1 << (sizeof(T)*8-1)) \
277 ) 301 )
278 302
303// UCRT supports both "ll" and "I64", but gcc warns on "I64" with UCRT mingw
304#if ENABLE_PLATFORM_MINGW32 && !defined(_UCRT) && \
305 (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)
306#define LL_FMT "I64"
307#else
308#define LL_FMT "ll"
309#endif
310
311#if ENABLE_PLATFORM_MINGW32 && defined(_WIN64)
312#define PID_FMT LL_FMT
313#else
314#define PID_FMT
315#endif
316
279/* Large file support */ 317/* Large file support */
280/* Note that CONFIG_LFS=y forces bbox to be built with all common ops 318/* Note that CONFIG_LFS=y forces bbox to be built with all common ops
281 * (stat, lseek etc) mapped to "largefile" variants by libc. 319 * (stat, lseek etc) mapped to "largefile" variants by libc.
@@ -301,7 +339,7 @@ typedef unsigned long long uoff_t;
301# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX) 339# define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX)
302# define BB_STRTOOFF bb_strtoull 340# define BB_STRTOOFF bb_strtoull
303# define STRTOOFF strtoull 341# define STRTOOFF strtoull
304# define OFF_FMT "ll" 342# define OFF_FMT LL_FMT
305# endif 343# endif
306#else 344#else
307/* CONFIG_LFS is off */ 345/* CONFIG_LFS is off */
@@ -570,13 +608,20 @@ char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
570const char *bb_basename(const char *name) FAST_FUNC; 608const char *bb_basename(const char *name) FAST_FUNC;
571/* NB: can violate const-ness (similarly to strchr) */ 609/* NB: can violate const-ness (similarly to strchr) */
572char *last_char_is(const char *s, int c) FAST_FUNC; 610char *last_char_is(const char *s, int c) FAST_FUNC;
611char *last_char_is_dir_sep(const char *s) FAST_FUNC;
573const char* endofname(const char *name) FAST_FUNC; 612const char* endofname(const char *name) FAST_FUNC;
574char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; 613char *is_prefixed_with(const char *string, const char *key) FAST_FUNC;
575char *is_suffixed_with(const char *string, const char *key) FAST_FUNC; 614char *is_suffixed_with(const char *string, const char *key) FAST_FUNC;
576 615
616#if !ENABLE_PLATFORM_MINGW32
577int ndelay_on(int fd) FAST_FUNC; 617int ndelay_on(int fd) FAST_FUNC;
578int ndelay_off(int fd) FAST_FUNC; 618int ndelay_off(int fd) FAST_FUNC;
579void close_on_exec_on(int fd) FAST_FUNC; 619void close_on_exec_on(int fd) FAST_FUNC;
620#else
621static inline int ndelay_on(int fd UNUSED_PARAM) { return 0; }
622static inline int ndelay_off(int fd UNUSED_PARAM) { return 0; }
623static inline void close_on_exec_on(int fd UNUSED_PARAM) { return; }
624#endif
580void xdup2(int, int) FAST_FUNC; 625void xdup2(int, int) FAST_FUNC;
581void xmove_fd(int, int) FAST_FUNC; 626void xmove_fd(int, int) FAST_FUNC;
582 627
@@ -610,20 +655,37 @@ enum {
610 * Dance around with long long to guard against that... 655 * Dance around with long long to guard against that...
611 */ 656 */
612 BB_FATAL_SIGS = (int)(0 657 BB_FATAL_SIGS = (int)(0
658#ifdef SIGHUP
613 + (1LL << SIGHUP) 659 + (1LL << SIGHUP)
660#endif
614 + (1LL << SIGINT) 661 + (1LL << SIGINT)
615 + (1LL << SIGTERM) 662 + (1LL << SIGTERM)
616 + (1LL << SIGPIPE) // Write to pipe with no readers 663 + (1LL << SIGPIPE) // Write to pipe with no readers
664#ifdef SIGQUIT
617 + (1LL << SIGQUIT) // Quit from keyboard 665 + (1LL << SIGQUIT) // Quit from keyboard
666#endif
618 + (1LL << SIGABRT) // Abort signal from abort(3) 667 + (1LL << SIGABRT) // Abort signal from abort(3)
668#ifdef SIGALRM
619 + (1LL << SIGALRM) // Timer signal from alarm(2) 669 + (1LL << SIGALRM) // Timer signal from alarm(2)
670#endif
671#ifdef SIGVTALRM
620 + (1LL << SIGVTALRM) // Virtual alarm clock 672 + (1LL << SIGVTALRM) // Virtual alarm clock
673#endif
674#ifdef SIGXCPU
621 + (1LL << SIGXCPU) // CPU time limit exceeded 675 + (1LL << SIGXCPU) // CPU time limit exceeded
676#endif
677#ifdef SIGXFSZ
622 + (1LL << SIGXFSZ) // File size limit exceeded 678 + (1LL << SIGXFSZ) // File size limit exceeded
679#endif
680#ifdef SIGUSR1
623 + (1LL << SIGUSR1) // Yes kids, these are also fatal! 681 + (1LL << SIGUSR1) // Yes kids, these are also fatal!
682#endif
683#ifdef SIGUSR1
624 + (1LL << SIGUSR2) 684 + (1LL << SIGUSR2)
685#endif
625 + 0), 686 + 0),
626}; 687};
688#if !ENABLE_PLATFORM_MINGW32
627void bb_signals(int sigs, void (*f)(int)) FAST_FUNC; 689void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
628/* Unlike signal() and bb_signals, sets handler with sigaction() 690/* Unlike signal() and bb_signals, sets handler with sigaction()
629 * and in a way that while signal handler is run, no other signals 691 * and in a way that while signal handler is run, no other signals
@@ -643,6 +705,10 @@ int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
643int sigprocmask_allsigs(int how) FAST_FUNC; 705int sigprocmask_allsigs(int how) FAST_FUNC;
644/* Return old set in the same set: */ 706/* Return old set in the same set: */
645int sigprocmask2(int how, sigset_t *set) FAST_FUNC; 707int sigprocmask2(int how, sigset_t *set) FAST_FUNC;
708#else
709#define bb_signals(s, f)
710#define kill_myself_with_sig(s)
711#endif
646/* Standard handler which just records signo */ 712/* Standard handler which just records signo */
647extern smallint bb_got_signal; 713extern smallint bb_got_signal;
648void record_signo(int signo); /* not FAST_FUNC! */ 714void record_signo(int signo); /* not FAST_FUNC! */
@@ -726,7 +792,7 @@ void xsettimeofday(const struct timeval *tv) FAST_FUNC;
726int xsocket(int domain, int type, int protocol) FAST_FUNC; 792int xsocket(int domain, int type, int protocol) FAST_FUNC;
727void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC; 793void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
728void xlisten(int s, int backlog) FAST_FUNC; 794void xlisten(int s, int backlog) FAST_FUNC;
729void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC; 795void 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, 796ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
731 socklen_t tolen) FAST_FUNC; 797 socklen_t tolen) FAST_FUNC;
732 798
@@ -839,7 +905,36 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC;
839// Also mount.c and inetd.c are using gethostbyname(), 905// Also mount.c and inetd.c are using gethostbyname(),
840// + inet_common.c has additional IPv4-only stuff 906// + inet_common.c has additional IPv4-only stuff
841 907
908#if defined CONFIG_FEATURE_TLS_SCHANNEL
909typedef struct tls_state {
910 int ofd;
911 int ifd;
912
913 // handles
914 CredHandle cred_handle;
915 CtxtHandle ctx_handle;
842 916
917 // buffers
918 char in_buffer[16384 + 256]; // input buffer (to read from server)
919 unsigned long in_buffer_size; // amount of data currently in input buffer
920
921 char *out_buffer; // output buffer (for decrypted data), this is essentially the same as input buffer as data is decrypted in place
922 unsigned long out_buffer_size; // amount of data currently in output buffer
923 unsigned long out_buffer_used; // amount of extra data currently in output buffer
924
925 // data
926 char *hostname;
927 SecPkgContext_StreamSizes stream_sizes;
928
929 // booleans
930
931 // context initialized
932 int initialized;
933
934 // closed by remote peer
935 int closed;
936} tls_state_t;
937#else
843struct tls_aes { 938struct tls_aes {
844 uint32_t key[60]; 939 uint32_t key[60];
845 unsigned rounds; 940 unsigned rounds;
@@ -896,12 +991,14 @@ typedef struct tls_state {
896 struct tls_aes aes_decrypt; 991 struct tls_aes aes_decrypt;
897 uint8_t H[16]; //used by AES_GCM 992 uint8_t H[16]; //used by AES_GCM
898} tls_state_t; 993} tls_state_t;
994#endif
899 995
900static inline tls_state_t *new_tls_state(void) 996static inline tls_state_t *new_tls_state(void)
901{ 997{
902 tls_state_t *tls = xzalloc(sizeof(*tls)); 998 tls_state_t *tls = xzalloc(sizeof(*tls));
903 return tls; 999 return tls;
904} 1000}
1001
905void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; 1002void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC;
906#define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0) 1003#define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0)
907void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC; 1004void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC;
@@ -933,7 +1030,7 @@ int bb_putchar(int ch) FAST_FUNC;
933/* Note: does not use stdio, writes to fd 2 directly */ 1030/* Note: does not use stdio, writes to fd 2 directly */
934int bb_putchar_stderr(char ch) FAST_FUNC; 1031int bb_putchar_stderr(char ch) FAST_FUNC;
935int fputs_stdout(const char *s) FAST_FUNC; 1032int fputs_stdout(const char *s) FAST_FUNC;
936char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; 1033char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) RETURNS_MALLOC;
937char *auto_string(char *str) FAST_FUNC; 1034char *auto_string(char *str) FAST_FUNC;
938// gcc-4.1.1 still isn't good enough at optimizing it 1035// gcc-4.1.1 still isn't good enough at optimizing it
939// (+200 bytes compared to macro) 1036// (+200 bytes compared to macro)
@@ -1011,13 +1108,13 @@ unsigned bb_clk_tck(void) FAST_FUNC;
1011 1108
1012#if SEAMLESS_COMPRESSION 1109#if SEAMLESS_COMPRESSION
1013/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ 1110/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
1014int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; 1111int setup_unzip_on_fd(int fd, int die_if_not_compressed) FAST_FUNC;
1015/* Autodetects .gz etc */ 1112/* Autodetects .gz etc */
1016extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; 1113extern int open_zipped(const char *fname, int die_if_not_compressed) FAST_FUNC;
1017extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; 1114extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
1018#else 1115#else
1019# define setup_unzip_on_fd(...) (0) 1116# define setup_unzip_on_fd(...) (0)
1020# define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); 1117# define open_zipped(fname, die_if_not_compressed) open((fname), O_RDONLY);
1021# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) 1118# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p))
1022#endif 1119#endif
1023/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ 1120/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */
@@ -1208,12 +1305,20 @@ gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC;
1208struct cached_groupinfo { 1305struct cached_groupinfo {
1209 uid_t euid; 1306 uid_t euid;
1210 gid_t egid; 1307 gid_t egid;
1308#if !ENABLE_PLATFORM_MINGW32
1309 // If these are ever restored on Windows it will be necessary to alter
1310 // globals_misc_size()/globals_misc_copy() in ash.
1211 int ngroups; 1311 int ngroups;
1212 gid_t *supplementary_array; 1312 gid_t *supplementary_array;
1313#endif
1213}; 1314};
1214uid_t FAST_FUNC get_cached_euid(uid_t *euid); 1315uid_t FAST_FUNC get_cached_euid(uid_t *euid);
1215gid_t FAST_FUNC get_cached_egid(gid_t *egid); 1316gid_t FAST_FUNC get_cached_egid(gid_t *egid);
1317#if !ENABLE_PLATFORM_MINGW32
1216int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid); 1318int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid);
1319#else
1320# define is_in_supplementary_groups(g, i) (FALSE)
1321#endif
1217 1322
1218#if ENABLE_FEATURE_UTMP 1323#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); 1324void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
@@ -1249,6 +1354,7 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1249 1354
1250/* xvfork() can't be a _function_, return after vfork in child mangles stack 1355/* xvfork() can't be a _function_, return after vfork in child mangles stack
1251 * in the parent. It must be a macro. */ 1356 * in the parent. It must be a macro. */
1357#if !ENABLE_PLATFORM_MINGW32
1252#define xvfork() \ 1358#define xvfork() \
1253({ \ 1359({ \
1254 pid_t bb__xvfork_pid = vfork(); \ 1360 pid_t bb__xvfork_pid = vfork(); \
@@ -1256,6 +1362,9 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
1256 bb_simple_perror_msg_and_die("vfork"); \ 1362 bb_simple_perror_msg_and_die("vfork"); \
1257 bb__xvfork_pid; \ 1363 bb__xvfork_pid; \
1258}) 1364})
1365#else
1366#define xvfork() vfork()
1367#endif
1259#if BB_MMU 1368#if BB_MMU
1260pid_t xfork(void) FAST_FUNC; 1369pid_t xfork(void) FAST_FUNC;
1261#endif 1370#endif
@@ -1290,6 +1399,15 @@ void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN F
1290#ifndef BUILD_INDIVIDUAL 1399#ifndef BUILD_INDIVIDUAL
1291int find_applet_by_name(const char *name) FAST_FUNC; 1400int 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; 1401void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC;
1402# if ENABLE_PLATFORM_MINGW32
1403# if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE
1404int prefer_applet(const char *name, const char *path) FAST_FUNC;
1405int find_applet_by_name_for_sh(const char *name, const char *path) FAST_FUNC;
1406# endif
1407# else
1408# define prefer_applet(n, p) (1)
1409# define find_applet_by_name_for_sh(n, p) find_applet_by_name(n)
1410# endif
1293#endif 1411#endif
1294void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; 1412void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC;
1295#if defined(__linux__) 1413#if defined(__linux__)
@@ -1370,12 +1488,12 @@ char* single_argv(char **argv) FAST_FUNC;
1370char **skip_dash_dash(char **argv) FAST_FUNC; 1488char **skip_dash_dash(char **argv) FAST_FUNC;
1371extern const char *const bb_argv_dash[]; /* { "-", NULL } */ 1489extern const char *const bb_argv_dash[]; /* { "-", NULL } */
1372extern uint32_t option_mask32; 1490extern uint32_t option_mask32;
1373uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; 1491uint32_t getopt32(char **argv, const char *applet_opts, ...);
1374# define No_argument "\0" 1492# define No_argument "\0"
1375# define Required_argument "\001" 1493# define Required_argument "\001"
1376# define Optional_argument "\002" 1494# define Optional_argument "\002"
1377#if ENABLE_LONG_OPTS 1495#if ENABLE_LONG_OPTS
1378uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...) FAST_FUNC; 1496uint32_t getopt32long(char **argv, const char *optstring, const char *longopts, ...);
1379#else 1497#else
1380#define getopt32long(argv,optstring,longopts,...) \ 1498#define getopt32long(argv,optstring,longopts,...) \
1381 getopt32(argv,optstring,##__VA_ARGS__) 1499 getopt32(argv,optstring,##__VA_ARGS__)
@@ -1450,17 +1568,17 @@ extern uint8_t xfunc_error_retval;
1450extern void (*die_func)(void); 1568extern void (*die_func)(void);
1451void xfunc_die(void) NORETURN FAST_FUNC; 1569void xfunc_die(void) NORETURN FAST_FUNC;
1452void bb_show_usage(void) NORETURN FAST_FUNC; 1570void bb_show_usage(void) NORETURN FAST_FUNC;
1453void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1571void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1454void bb_simple_error_msg(const char *s) FAST_FUNC; 1572void 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; 1573void 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; 1574void 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; 1575void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1458void bb_simple_perror_msg(const char *s) FAST_FUNC; 1576void 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; 1577void 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; 1578void 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; 1579void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1462void bb_simple_herror_msg(const char *s) FAST_FUNC; 1580void 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; 1581void 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; 1582void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1465void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; 1583void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1466void bb_perror_nomsg(void) FAST_FUNC; 1584void bb_perror_nomsg(void) FAST_FUNC;
@@ -1476,7 +1594,7 @@ void bb_logenv_override(void) FAST_FUNC;
1476typedef smalluint exitcode_t; 1594typedef smalluint exitcode_t;
1477 1595
1478#if ENABLE_FEATURE_SYSLOG_INFO 1596#if ENABLE_FEATURE_SYSLOG_INFO
1479void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1597void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
1480void bb_simple_info_msg(const char *s) FAST_FUNC; 1598void bb_simple_info_msg(const char *s) FAST_FUNC;
1481void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC; 1599void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC;
1482#else 1600#else
@@ -1853,8 +1971,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; 1971int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC;
1854 1972
1855/* NB: "unsigned request" is crucial! "int request" will break some arches! */ 1973/* 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; 1974int 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; 1975int 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 1976#if ENABLE_IOCTL_HEX2STR_ERROR
1859int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC; 1977int 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; 1978int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
@@ -1867,9 +1985,15 @@ int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
1867#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp) 1985#define xioctl(fd,request,argp) bb_xioctl(fd,request,argp)
1868#endif 1986#endif
1869 1987
1988#if !ENABLE_PLATFORM_MINGW32 || ENABLE_FEATURE_EXTRA_FILE_DATA
1870char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC; 1989char *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; 1990void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
1872void reset_ino_dev_hashtable(void) FAST_FUNC; 1991void reset_ino_dev_hashtable(void) FAST_FUNC;
1992#else
1993#define add_to_ino_dev_hashtable(s, n) (void)0
1994#define is_in_ino_dev_hashtable(s) NULL
1995#define reset_ino_dev_hashtable()
1996#endif
1873#ifdef __GLIBC__ 1997#ifdef __GLIBC__
1874/* At least glibc has horrendously large inline for this, so wrap it */ 1998/* At least glibc has horrendously large inline for this, so wrap it */
1875unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC; 1999unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
@@ -1947,10 +2071,17 @@ enum {
1947 * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout 2071 * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout
1948 */ 2072 */
1949int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC; 2073int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
2074#if ENABLE_PLATFORM_MINGW32
2075int64_t windows_read_key(int fd, char *buffer, int timeout) FAST_FUNC;
2076#endif
1950/* This version loops on EINTR: */ 2077/* This version loops on EINTR: */
1951int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC; 2078int64_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; 2079void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
1953 2080
2081int check_got_signal_and_poll(struct pollfd pfd[1], int timeout) FAST_FUNC;
2082#if ENABLE_PLATFORM_MINGW32
2083# define check_got_signal_and_poll(p, t) poll(p, 1, t)
2084#endif
1954 2085
1955#if ENABLE_FEATURE_EDITING 2086#if ENABLE_FEATURE_EDITING
1956/* It's NOT just ENABLEd or disabled. It's a number: */ 2087/* It's NOT just ENABLEd or disabled. It's a number: */
@@ -1960,8 +2091,14 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1960# else 2091# else
1961# define MAX_HISTORY 0 2092# define MAX_HISTORY 0
1962# endif 2093# endif
2094# if defined CONFIG_FEATURE_EDITING_HISTORY_DEFAULT && CONFIG_FEATURE_EDITING_HISTORY_DEFAULT > 0
2095# define DEFAULT_HISTORY (CONFIG_FEATURE_EDITING_HISTORY_DEFAULT + 0)
2096# else
2097# define DEFAULT_HISTORY 0
2098# endif
1963typedef const char *get_exe_name_t(int i) FAST_FUNC; 2099typedef const char *get_exe_name_t(int i) FAST_FUNC;
1964typedef const char *sh_get_var_t(const char *name) FAST_FUNC; 2100typedef const char *sh_get_var_t(const char *name) FAST_FUNC;
2101typedef int sh_accept_glob_t(const char *name) FAST_FUNC;
1965typedef struct line_input_t { 2102typedef struct line_input_t {
1966 int flags; 2103 int flags;
1967 int timeout; 2104 int timeout;
@@ -1975,6 +2112,9 @@ typedef struct line_input_t {
1975# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH 2112# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
1976 /* function to fetch additional application-specific names to match */ 2113 /* function to fetch additional application-specific names to match */
1977 get_exe_name_t *get_exe_name; 2114 get_exe_name_t *get_exe_name;
2115# if ENABLE_ASH_GLOB_OPTIONS
2116 sh_accept_glob_t *sh_accept_glob;
2117# endif
1978# endif 2118# endif
1979# endif 2119# endif
1980# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ 2120# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \
@@ -1988,7 +2128,7 @@ typedef struct line_input_t {
1988# if MAX_HISTORY 2128# if MAX_HISTORY
1989 int cnt_history; 2129 int cnt_history;
1990 int cur_history; 2130 int cur_history;
1991 int max_history; /* must never be <= 0 */ 2131 int max_history; /* must never be < 0 */
1992# if ENABLE_FEATURE_EDITING_SAVEHISTORY 2132# if ENABLE_FEATURE_EDITING_SAVEHISTORY
1993 /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT: 2133 /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT:
1994 * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are 2134 * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are
@@ -2009,6 +2149,9 @@ enum {
2009 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI, 2149 VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI,
2010 WITH_PATH_LOOKUP = 0x10, 2150 WITH_PATH_LOOKUP = 0x10,
2011 LI_INTERRUPTIBLE = 0x20, 2151 LI_INTERRUPTIBLE = 0x20,
2152#if ENABLE_PLATFORM_MINGW32
2153 IGNORE_CTRL_C = 0x40,
2154#endif
2012 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION | LI_INTERRUPTIBLE, 2155 FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION | LI_INTERRUPTIBLE,
2013}; 2156};
2014line_input_t *new_line_input_t(int flags) FAST_FUNC; 2157line_input_t *new_line_input_t(int flags) FAST_FUNC;
@@ -2038,6 +2181,10 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
2038 2181
2039unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz); 2182unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz);
2040 2183
2184#if ENABLE_PLATFORM_MINGW32
2185# undef COMM_LEN
2186# define COMM_LEN 32
2187#endif
2041#ifndef COMM_LEN 2188#ifndef COMM_LEN
2042# ifdef TASK_COMM_LEN 2189# ifdef TASK_COMM_LEN
2043enum { COMM_LEN = TASK_COMM_LEN }; 2190enum { COMM_LEN = TASK_COMM_LEN };
@@ -2075,7 +2222,13 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
2075 void (*cb)(struct smaprec *, void *), void *data); 2222 void (*cb)(struct smaprec *, void *), void *data);
2076 2223
2077typedef struct procps_status_t { 2224typedef struct procps_status_t {
2225#if !ENABLE_PLATFORM_MINGW32
2078 DIR *dir; 2226 DIR *dir;
2227#else
2228 HANDLE snapshot;
2229 DWORD *pids;
2230 int npids;
2231#endif
2079 IF_FEATURE_SHOW_THREADS(DIR *task_dir;) 2232 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
2080 uint8_t shift_pages_to_bytes; 2233 uint8_t shift_pages_to_bytes;
2081 uint8_t shift_pages_to_kb; 2234 uint8_t shift_pages_to_kb;
@@ -2182,6 +2335,36 @@ char *decode_base64(char *dst, const char **pp_src) FAST_FUNC;
2182char *decode_base32(char *dst, const char **pp_src) FAST_FUNC; 2335char *decode_base32(char *dst, const char **pp_src) FAST_FUNC;
2183void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC; 2336void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC;
2184 2337
2338#if defined CONFIG_FEATURE_USE_CNG_API
2339struct bcrypt_hash_ctx_t {
2340 void *handle;
2341 void *hash_obj;
2342 unsigned int output_size;
2343};
2344typedef struct bcrypt_hash_ctx_t md5_ctx_t;
2345typedef struct bcrypt_hash_ctx_t sha1_ctx_t;
2346typedef struct bcrypt_hash_ctx_t sha256_ctx_t;
2347typedef struct bcrypt_hash_ctx_t sha512_ctx_t;
2348typedef struct sha3_ctx_t {
2349 uint64_t state[25];
2350 unsigned bytes_queued;
2351 unsigned input_block_bytes;
2352} sha3_ctx_t;
2353void md5_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2354void sha1_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2355void sha256_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2356void sha512_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC;
2357void generic_hash(struct bcrypt_hash_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
2358unsigned generic_end(struct bcrypt_hash_ctx_t *ctx, void *resbuf) FAST_FUNC;
2359# define md5_hash generic_hash
2360# define sha1_hash generic_hash
2361# define sha256_hash generic_hash
2362# define sha512_hash generic_hash
2363# define md5_end generic_end
2364# define sha1_end generic_end
2365# define sha256_end generic_end
2366# define sha512_end generic_end
2367#else
2185typedef struct md5_ctx_t { 2368typedef struct md5_ctx_t {
2186 uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ 2369 uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
2187 void (*process_block)(struct md5_ctx_t*) FAST_FUNC; 2370 void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
@@ -2212,13 +2395,20 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
2212void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 2395void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
2213void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 2396void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
2214unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; 2397unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
2398#endif
2215void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; 2399void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
2216void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 2400void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
2217unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; 2401unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
2218/* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ 2402/* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */
2403#if defined CONFIG_FEATURE_USE_CNG_API
2404typedef struct bcrypt_hash_ctx_t md5sha_ctx_t;
2405#define md5sha_hash generic_hash
2406#define sha_end generic_end
2407#else
2219typedef struct md5_ctx_t md5sha_ctx_t; 2408typedef struct md5_ctx_t md5sha_ctx_t;
2220#define md5sha_hash md5_hash 2409#define md5sha_hash md5_hash
2221#define sha_end sha1_end 2410#define sha_end sha1_end
2411#endif
2222enum { 2412enum {
2223 MD5_OUTSIZE = 16, 2413 MD5_OUTSIZE = 16,
2224 SHA1_OUTSIZE = 20, 2414 SHA1_OUTSIZE = 20,
@@ -2309,11 +2499,18 @@ extern const char bb_path_wtmp_file[] ALIGN1;
2309#define bb_path_motd_file "/etc/motd" 2499#define bb_path_motd_file "/etc/motd"
2310 2500
2311#define bb_dev_null "/dev/null" 2501#define bb_dev_null "/dev/null"
2502#if ENABLE_PLATFORM_MINGW32
2503#define bb_busybox_exec_path get_busybox_exec_path()
2504extern char bb_comm[];
2505extern char bb_command_line[];
2506#else
2312extern const char bb_busybox_exec_path[] ALIGN1; 2507extern const char bb_busybox_exec_path[] ALIGN1;
2508#endif
2313/* allow default system PATH to be extended via CFLAGS */ 2509/* allow default system PATH to be extended via CFLAGS */
2314#ifndef BB_ADDITIONAL_PATH 2510#ifndef BB_ADDITIONAL_PATH
2315#define BB_ADDITIONAL_PATH "" 2511#define BB_ADDITIONAL_PATH ""
2316#endif 2512#endif
2513#if !ENABLE_PLATFORM_MINGW32
2317#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH 2514#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 */ 2515extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2319#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH")) 2516#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
@@ -2321,6 +2518,23 @@ extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2321 * but I want to save a few bytes here: 2518 * but I want to save a few bytes here:
2322 */ 2519 */
2323#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) 2520#define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin"))
2521#define PATH_SEP ':'
2522#define PATH_SEP_STR ":"
2523#else
2524#define BB_PATH_ROOT_PATH "PATH=C:/Windows/System32;C:/Windows" BB_ADDITIONAL_PATH
2525extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2526#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
2527#define bb_default_path (bb_PATH_root_path + sizeof("PATH"))
2528#define PATH_SEP ';'
2529#define PATH_SEP_STR ";"
2530extern const char bbvar[] ALIGN1;
2531#define bbafter(p) (p + sizeof(#p))
2532#define BB_OVERRIDE_APPLETS bbvar
2533#define BB_SKIP_ANSI_EMULATION bbafter(BB_OVERRIDE_APPLETS)
2534#define BB_TERMINAL_MODE bbafter(BB_SKIP_ANSI_EMULATION)
2535#define BB_SYSTEMROOT bbafter(BB_TERMINAL_MODE)
2536#define BB_CRITICAL_ERROR_DIALOGS bbafter(BB_SYSTEMROOT)
2537#endif
2324 2538
2325extern const int const_int_0; 2539extern const int const_int_0;
2326//extern const int const_int_1; 2540//extern const int const_int_1;
@@ -2337,26 +2551,10 @@ extern struct globals *BB_GLOBAL_CONST ptr_to_globals;
2337#define barrier() asm volatile ("":::"memory") 2551#define barrier() asm volatile ("":::"memory")
2338 2552
2339#if defined(__clang_major__) && __clang_major__ >= 9 2553#if defined(__clang_major__) && __clang_major__ >= 9
2340/* Clang/llvm drops assignment to "constant" storage. Silently. 2554/* {ASSIGN,XZALLOC}_CONST_PTR() are out-of-line functions
2341 * Needs serious convincing to not eliminate the store. 2555 * to prevent clang from reading pointer before it is assigned.
2342 */
2343static ALWAYS_INLINE void* not_const_pp(const void *p)
2344{
2345 void *pp;
2346 asm volatile (
2347 "# forget that p points to const"
2348 : /*outputs*/ "=r" (pp)
2349 : /*inputs*/ "0" (p)
2350 );
2351 return pp;
2352}
2353# define ASSIGN_CONST_PTR(pptr, v) do { \
2354 *(void**)not_const_pp(pptr) = (void*)(v); \
2355 barrier(); \
2356} while (0)
2357/* XZALLOC_CONST_PTR() is an out-of-line function to prevent
2358 * clang from reading pointer before it is assigned.
2359 */ 2556 */
2557void ASSIGN_CONST_PTR(const void *pptr, void *v) FAST_FUNC;
2360void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC; 2558void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC;
2361#else 2559#else
2362# define ASSIGN_CONST_PTR(pptr, v) do { \ 2560# define ASSIGN_CONST_PTR(pptr, v) do { \
diff --git a/include/mingw.h b/include/mingw.h
new file mode 100644
index 000000000..276e40659
--- /dev/null
+++ b/include/mingw.h
@@ -0,0 +1,674 @@
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#define TIOCSWINSZ 0x5414
263
264int ioctl(int fd, int code, ...);
265
266/*
267 * sys/socket.h
268 */
269#define hstrerror strerror
270
271#define SHUT_WR SD_SEND
272
273int mingw_socket(int domain, int type, int protocol);
274int mingw_connect(int sockfd, const struct sockaddr *sa, size_t sz);
275int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz);
276int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen);
277int mingw_shutdown(int sockfd, int how);
278int mingw_listen(int sockfd, int backlog);
279int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz);
280int mingw_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
281 struct timeval *timeout);
282int mingw_getpeername(int fd, struct sockaddr *sa, socklen_t *sz);
283int mingw_gethostname(char *host, int namelen);
284int mingw_getaddrinfo(const char *node, const char *service,
285 const struct addrinfo *hints, struct addrinfo **res);
286struct hostent *mingw_gethostbyaddr(const void *addr, socklen_t len, int type);
287
288#define socket mingw_socket
289#define connect mingw_connect
290#define listen mingw_listen
291#define bind mingw_bind
292#define setsockopt mingw_setsockopt
293#define shutdown mingw_shutdown
294#define accept mingw_accept
295#define select mingw_select
296#define getpeername mingw_getpeername
297#define gethostname mingw_gethostname
298#define getaddrinfo mingw_getaddrinfo
299#define gethostbyaddr mingw_gethostbyaddr
300
301/*
302 * sys/time.h
303 */
304#ifndef _TIMESPEC_DEFINED
305#define _TIMESPEC_DEFINED
306struct timespec {
307 time_t tv_sec;
308 long int tv_nsec;
309};
310#endif
311
312typedef int clockid_t;
313#define CLOCK_REALTIME 0
314
315time_t timegm(struct tm *tm);
316
317int nanosleep(const struct timespec *req, struct timespec *rem);
318int clock_gettime(clockid_t clockid, struct timespec *tp);
319int clock_settime(clockid_t clockid, const struct timespec *tp);
320
321/*
322 * sys/stat.h
323 */
324#define S_ISUID 04000
325#define S_ISGID 02000
326#define S_ISVTX 01000
327#ifndef S_IRWXU
328#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
329#endif
330#define S_IRWXG (S_IRWXU >> 3)
331#define S_IRWXO (S_IRWXG >> 3)
332
333#define S_IFSOCK 0140000
334#define S_IFLNK 0120000 /* Symbolic link */
335#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
336#define S_ISSOCK(x) 0
337
338#define S_IRGRP (S_IRUSR >> 3)
339#define S_IWGRP (S_IWUSR >> 3)
340#define S_IXGRP (S_IXUSR >> 3)
341#define S_IROTH (S_IRGRP >> 3)
342#define S_IWOTH (S_IWGRP >> 3)
343#define S_IXOTH (S_IXGRP >> 3)
344
345mode_t mingw_umask(mode_t mode);
346#define umask mingw_umask
347
348#define DEFAULT_UMASK 0002
349
350IMPL(fchmod,int,0,int fildes UNUSED_PARAM, mode_t mode UNUSED_PARAM);
351NOIMPL(fchown,int fd UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
352int mingw_mkdir(const char *path, int mode);
353int mingw_chdir(const char *path);
354int mingw_chmod(const char *path, int mode);
355
356#define mkdir mingw_mkdir
357#define chdir mingw_chdir
358#define chmod mingw_chmod
359
360#if ENABLE_LFS && !defined(__MINGW64_VERSION_MAJOR)
361# define off_t off64_t
362#endif
363
364typedef int nlink_t;
365typedef int blksize_t;
366typedef off_t blkcnt_t;
367#if ENABLE_FEATURE_EXTRA_FILE_DATA
368#define ino_t uint64_t
369#endif
370
371struct mingw_stat {
372 dev_t st_dev;
373 ino_t st_ino;
374 mode_t st_mode;
375 nlink_t st_nlink;
376 uid_t st_uid;
377 gid_t st_gid;
378 dev_t st_rdev;
379 off_t st_size;
380 struct timespec st_atim;
381 struct timespec st_mtim;
382 struct timespec st_ctim;
383 blksize_t st_blksize;
384 blkcnt_t st_blocks;
385 DWORD st_attr;
386 DWORD st_tag;
387};
388#define st_atime st_atim.tv_sec
389#define st_mtime st_mtim.tv_sec
390#define st_ctime st_ctim.tv_sec
391
392int count_subdirs(const char *pathname);
393int mingw_lstat(const char *file_name, struct mingw_stat *buf);
394int mingw_stat(const char *file_name, struct mingw_stat *buf);
395int mingw_fstat(int fd, struct mingw_stat *buf);
396#undef lstat
397#undef stat
398#undef fstat
399#define lstat mingw_lstat
400#define stat mingw_stat
401#define fstat mingw_fstat
402
403#define UTIME_NOW ((1l << 30) - 1l)
404#define UTIME_OMIT ((1l << 30) - 2l)
405
406int utimensat(int fd, const char *path, const struct timespec times[2],
407 int flags);
408int futimens(int fd, const struct timespec times[2]);
409
410/*
411 * sys/sysinfo.h
412 */
413struct sysinfo {
414 long uptime; /* Seconds since boot */
415 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
416 unsigned long totalram; /* Total usable main memory size */
417 unsigned long freeram; /* Available memory size */
418 unsigned long sharedram; /* Amount of shared memory */
419 unsigned long bufferram; /* Memory used by buffers */
420 unsigned long totalswap; /* Total swap space size */
421 unsigned long freeswap; /* Swap space still available */
422 unsigned short procs; /* Number of current processes */
423 unsigned long totalhigh; /* Total high memory size */
424 unsigned long freehigh; /* Available high memory size */
425 unsigned int mem_unit; /* Memory unit size in bytes */
426};
427
428int sysinfo(struct sysinfo *info);
429
430/*
431 * sys/sysmacros.h
432 */
433#define makedev(a,b) 0*(a)*(b) /* avoid unused warning */
434#define minor(x) 0
435#define major(x) 0
436
437/*
438 * sys/wait.h
439 */
440#define WNOHANG 1
441#define WUNTRACED 2
442pid_t waitpid(pid_t pid, int *status, int options);
443pid_t mingw_wait3(pid_t pid, int *status, int options, struct rusage *rusage);
444
445/*
446 * time.h
447 */
448struct tm *gmtime_r(const time_t *timep, struct tm *result);
449struct tm *localtime_r(const time_t *timep, struct tm *result);
450char *strptime(const char *s, const char *format, struct tm *tm);
451char *mingw_strptime(const char *s, const char *format, struct tm *tm, long *gmt);
452size_t mingw_strftime(char *buf, size_t max, const char *format, const struct tm *tm);
453
454#define strftime mingw_strftime
455
456/*
457 * times.h
458 */
459#define clock_t long
460
461struct tms {
462 clock_t tms_utime; /* user CPU time */
463 clock_t tms_stime; /* system CPU time */
464 clock_t tms_cutime; /* user CPU time of children */
465 clock_t tms_cstime; /* system CPU time of children */
466};
467
468clock_t times(struct tms *buf);
469
470/*
471 * unistd.h
472 */
473#define PIPE_BUF 8192
474
475#define _SC_CLK_TCK 2
476
477#define TICKS_PER_SECOND 100
478#define MS_PER_TICK 10
479#define HNSEC_PER_TICK 100000
480
481IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM);
482IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
483NOIMPL(chroot,const char *root UNUSED_PARAM);
484NOIMPL(fchdir,int fd UNUSED_PARAM);
485int mingw_dup2 (int fd, int fdto);
486char *mingw_getcwd(char *pointer, int len);
487off_t mingw_lseek(int fd, off_t offset, int whence);
488
489
490int getuid(void);
491#define getgid getuid
492#define geteuid getuid
493#define getegid getuid
494int getgroups(int n, gid_t *groups);
495pid_t getppid(void);
496NOIMPL(getsid,pid_t pid UNUSED_PARAM);
497int getlogin_r(char *buf, size_t len);
498int fcntl(int fd, int cmd, ...);
499int fsync(int fd);
500int kill(pid_t pid, int sig);
501int link(const char *oldpath, const char *newpath);
502NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM);
503/* order of devices must match that in get_dev_type */
504enum {DEV_NULL, DEV_ZERO, DEV_URANDOM, NOT_DEVICE = -1};
505int get_dev_type(const char *filename);
506void update_special_fd(int dev, int fd);
507int mingw_open (const char *filename, int oflags, ...);
508
509/* functions which add O_SPECIAL to open(2) to allow access to devices */
510int mingw_xopen(const char *filename, int oflags);
511ssize_t mingw_open_read_close(const char *fn, void *buf, size_t size) FAST_FUNC;
512
513#ifndef IO_REPARSE_TAG_APPEXECLINK
514# define IO_REPARSE_TAG_APPEXECLINK 0x8000001b
515#endif
516
517ssize_t mingw_read(int fd, void *buf, size_t count);
518int mingw_close(int fd);
519int pipe(int filedes[2]);
520NOIMPL(setgid,gid_t gid UNUSED_PARAM);
521NOIMPL(setegid,gid_t gid UNUSED_PARAM);
522NOIMPL(setsid,void);
523NOIMPL(setuid,uid_t gid UNUSED_PARAM);
524NOIMPL(seteuid,uid_t gid UNUSED_PARAM);
525unsigned int sleep(unsigned int seconds);
526int symlink(const char *target, const char *linkpath);
527int create_junction(const char *oldpath, const char *newpath);
528long sysconf(int name);
529IMPL(getpagesize,int,4096,void);
530NOIMPL(ttyname_r,int fd UNUSED_PARAM, char *buf UNUSED_PARAM, int sz UNUSED_PARAM);
531int mingw_unlink(const char *pathname);
532int mingw_access(const char *name, int mode);
533int mingw_rmdir(const char *name);
534void mingw_sync(void);
535int mingw_isatty(int fd);
536
537#define dup2 mingw_dup2
538#define getcwd mingw_getcwd
539#define lchown chown
540#define open mingw_open
541#define close mingw_close
542#define unlink mingw_unlink
543#define rmdir mingw_rmdir
544#define sync mingw_sync
545#undef lseek
546#define lseek mingw_lseek
547
548#undef access
549#define access mingw_access
550#define isatty mingw_isatty
551
552/*
553 * utime.h
554 */
555int utimes(const char *file_name, const struct timeval times[2]);
556
557/*
558 * Functions with different prototypes in BusyBox and WIN32
559 */
560#define itoa bb_itoa
561#define strrev bb_strrev
562
563/*
564 * MinGW specific
565 */
566#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
567#define is_unc_path(x) (strlen(x) > 4 && is_dir_sep(x[0]) && \
568 is_dir_sep(x[1]) && !is_dir_sep(x[2]))
569
570typedef struct {
571 char *path;
572 char *name;
573 char *opts;
574 char buf[100];
575} interp_t;
576
577int FAST_FUNC parse_interpreter(const char *cmd, interp_t *interp);
578char ** FAST_FUNC grow_argv(char **argv, int n);
579pid_t FAST_FUNC mingw_spawn(char **argv);
580intptr_t FAST_FUNC mingw_spawn_detach(char **argv);
581intptr_t FAST_FUNC mingw_spawn_proc(const char **argv);
582int mingw_execv(const char *cmd, char *const *argv);
583int httpd_execv_detach(const char *cmd, char *const *argv);
584int mingw_execvp(const char *cmd, char *const *argv);
585int mingw_execve(const char *cmd, char *const *argv, char *const *envp);
586#define spawn mingw_spawn
587#define execvp mingw_execvp
588#define execve mingw_execve
589#define execv mingw_execv
590#define HTTPD_DETACH (8)
591
592#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
593
594BOOL WINAPI kill_child_ctrl_handler(DWORD dwCtrlType);
595int FAST_FUNC is_valid_signal(int number);
596int exit_code_to_wait_status(DWORD win_exit_code);
597int exit_code_to_posix(DWORD win_exit_code);
598
599#define find_mount_point(n, s) find_mount_point(n)
600
601char *is_prefixed_with_case(const char *string, const char *key) FAST_FUNC;
602char *is_suffixed_with_case(const char *string, const char *key) FAST_FUNC;
603
604#define VT_OUTPUT 1
605#define VT_INPUT 2
606
607/*
608 * helpers
609 */
610
611const char *get_busybox_exec_path(void);
612void init_winsock(void);
613
614int has_bat_suffix(const char *p);
615int has_exe_suffix(const char *p);
616int has_exe_suffix_or_dot(const char *name);
617char *alloc_ext_space(const char *path);
618int add_win32_extension(char *p);
619char *file_is_win32_exe(const char *name);
620
621#if ENABLE_UNICODE_SUPPORT
622/*
623 * windows wchar_t is 16 bit, while linux (and busybox expectation) is 32.
624 * so when (busybox) unicode.h is included, wchar_t is 32 bit.
625 * Without unicode.h, MINGW_BB_WCHAR_T is busybox wide char (32),
626 * and wchar_t is Windows wide char (16).
627 */
628#define MINGW_BB_WCHAR_T uint32_t /* keep in sync with unicode.h */
629
630MINGW_BB_WCHAR_T *bs_to_slash_u(MINGW_BB_WCHAR_T *p) FAST_FUNC;
631#endif
632
633char *bs_to_slash(char *p) FAST_FUNC;
634void slash_to_bs(char *p) FAST_FUNC;
635void strip_dot_space(char *p) FAST_FUNC;
636size_t remove_cr(char *p, size_t len) FAST_FUNC;
637
638int err_win_to_posix(void);
639
640ULONGLONG CompatGetTickCount64(void);
641#define GetTickCount64 CompatGetTickCount64
642
643ssize_t get_random_bytes(void *buf, ssize_t count);
644int enumerate_links(const char *file, char *name);
645
646int unc_root_len(const char *dir) FAST_FUNC;
647int root_len(const char *path) FAST_FUNC;
648const char *get_system_drive(void) FAST_FUNC;
649int chdir_system_drive(void);
650char *xabsolute_path(char *path) FAST_FUNC;
651char *get_drive_cwd(const char *path, char *buffer, int size) FAST_FUNC;
652void fix_path_case(char *path) FAST_FUNC;
653void make_sparse(int fd, off_t start, off_t end) FAST_FUNC;
654int terminal_mode(int reset) FAST_FUNC;
655int unix_path(const char *path) FAST_FUNC;
656int has_path(const char *file) FAST_FUNC;
657int is_relative_path(const char *path) FAST_FUNC;
658char *get_last_slash(const char *path) FAST_FUNC;
659const char *applet_to_exe(const char *name) FAST_FUNC;
660char *get_user_name(void);
661char *quote_arg(const char *arg) FAST_FUNC;
662char *find_first_executable(const char *name) FAST_FUNC;
663char *xappendword(const char *str, const char *word) FAST_FUNC;
664int windows_env(void);
665void change_critical_error_dialogs(const char *newval) FAST_FUNC;
666char *exe_relative_path(const char *tail) FAST_FUNC;
667enum {
668 ELEVATED_PRIVILEGE = 1,
669 ADMIN_ENABLED = 2
670};
671int elevation_state(void);
672void set_interp(int i) FAST_FUNC;
673int mingw_shell_execute(SHELLEXECUTEINFO *info);
674void mingw_die_if_error(NTSTATUS status, const char *function_name);
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