diff options
-rw-r--r-- | configs/mingw32_defconfig | 4 | ||||
-rw-r--r-- | configs/mingw64_defconfig | 4 | ||||
-rw-r--r-- | configs/mingw64u_defconfig | 4 | ||||
-rw-r--r-- | include/mingw.h | 2 | ||||
-rw-r--r-- | networking/httpd.c | 117 | ||||
-rw-r--r-- | win32/process.c | 60 |
6 files changed, 176 insertions, 15 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index ee01330d1..0f674d45c 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.37.0.git | 3 | # Busybox version: 1.37.0.git |
4 | # Sat Dec 9 09:38:58 2023 | 4 | # Wed Dec 20 13:23:38 2023 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -916,7 +916,7 @@ CONFIG_FEATURE_HTTPD_RANGES=y | |||
916 | # CONFIG_FEATURE_HTTPD_SETUID is not set | 916 | # CONFIG_FEATURE_HTTPD_SETUID is not set |
917 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y | 917 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y |
918 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set | 918 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set |
919 | # CONFIG_FEATURE_HTTPD_CGI is not set | 919 | CONFIG_FEATURE_HTTPD_CGI=y |
920 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set | 920 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set |
921 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set | 921 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set |
922 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y | 922 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index 3fed1c99b..37f95f4c8 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.37.0.git | 3 | # Busybox version: 1.37.0.git |
4 | # Sat Dec 9 09:38:58 2023 | 4 | # Wed Dec 20 13:23:38 2023 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -916,7 +916,7 @@ CONFIG_FEATURE_HTTPD_RANGES=y | |||
916 | # CONFIG_FEATURE_HTTPD_SETUID is not set | 916 | # CONFIG_FEATURE_HTTPD_SETUID is not set |
917 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y | 917 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y |
918 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set | 918 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set |
919 | # CONFIG_FEATURE_HTTPD_CGI is not set | 919 | CONFIG_FEATURE_HTTPD_CGI=y |
920 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set | 920 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set |
921 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set | 921 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set |
922 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y | 922 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y |
diff --git a/configs/mingw64u_defconfig b/configs/mingw64u_defconfig index f3391a206..f26b17ec9 100644 --- a/configs/mingw64u_defconfig +++ b/configs/mingw64u_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.37.0.git | 3 | # Busybox version: 1.37.0.git |
4 | # Sat Dec 9 09:38:58 2023 | 4 | # Wed Dec 20 13:23:38 2023 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -916,7 +916,7 @@ CONFIG_FEATURE_HTTPD_RANGES=y | |||
916 | # CONFIG_FEATURE_HTTPD_SETUID is not set | 916 | # CONFIG_FEATURE_HTTPD_SETUID is not set |
917 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y | 917 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y |
918 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set | 918 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set |
919 | # CONFIG_FEATURE_HTTPD_CGI is not set | 919 | CONFIG_FEATURE_HTTPD_CGI=y |
920 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set | 920 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set |
921 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set | 921 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set |
922 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y | 922 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y |
diff --git a/include/mingw.h b/include/mingw.h index 46cbe03f8..88da85243 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -552,12 +552,14 @@ pid_t FAST_FUNC mingw_spawn(char **argv); | |||
552 | intptr_t FAST_FUNC mingw_spawn_detach(char **argv); | 552 | intptr_t FAST_FUNC mingw_spawn_detach(char **argv); |
553 | intptr_t FAST_FUNC mingw_spawn_proc(const char **argv); | 553 | intptr_t FAST_FUNC mingw_spawn_proc(const char **argv); |
554 | int mingw_execv(const char *cmd, char *const *argv); | 554 | int mingw_execv(const char *cmd, char *const *argv); |
555 | int httpd_execv_detach(const char *cmd, char *const *argv); | ||
555 | int mingw_execvp(const char *cmd, char *const *argv); | 556 | int mingw_execvp(const char *cmd, char *const *argv); |
556 | int mingw_execve(const char *cmd, char *const *argv, char *const *envp); | 557 | int mingw_execve(const char *cmd, char *const *argv, char *const *envp); |
557 | #define spawn mingw_spawn | 558 | #define spawn mingw_spawn |
558 | #define execvp mingw_execvp | 559 | #define execvp mingw_execvp |
559 | #define execve mingw_execve | 560 | #define execve mingw_execve |
560 | #define execv mingw_execv | 561 | #define execv mingw_execv |
562 | #define HTTPD_DETACH (8) | ||
561 | 563 | ||
562 | #define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':') | 564 | #define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':') |
563 | 565 | ||
diff --git a/networking/httpd.c b/networking/httpd.c index 0de56a47a..d049e3842 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -461,6 +461,13 @@ static const struct { | |||
461 | 461 | ||
462 | struct globals { | 462 | struct globals { |
463 | int verbose; /* must be int (used by getopt32) */ | 463 | int verbose; /* must be int (used by getopt32) */ |
464 | #if ENABLE_PLATFORM_MINGW32 | ||
465 | smallint foreground; | ||
466 | # if ENABLE_FEATURE_HTTPD_CGI | ||
467 | int server_argc; | ||
468 | char **server_argv; | ||
469 | # endif | ||
470 | #endif | ||
464 | smallint flg_deny_all; | 471 | smallint flg_deny_all; |
465 | #if ENABLE_FEATURE_HTTPD_GZIP | 472 | #if ENABLE_FEATURE_HTTPD_GZIP |
466 | /* client can handle gzip / we are going to send gzip */ | 473 | /* client can handle gzip / we are going to send gzip */ |
@@ -518,6 +525,11 @@ struct globals { | |||
518 | }; | 525 | }; |
519 | #define G (*ptr_to_globals) | 526 | #define G (*ptr_to_globals) |
520 | #define verbose (G.verbose ) | 527 | #define verbose (G.verbose ) |
528 | #if ENABLE_PLATFORM_MINGW32 | ||
529 | #define foreground (G.foreground ) | ||
530 | #define server_argc (G.server_argc ) | ||
531 | #define server_argv (G.server_argv ) | ||
532 | #endif | ||
521 | #define flg_deny_all (G.flg_deny_all ) | 533 | #define flg_deny_all (G.flg_deny_all ) |
522 | #if ENABLE_FEATURE_HTTPD_GZIP | 534 | #if ENABLE_FEATURE_HTTPD_GZIP |
523 | # define content_gzip (G.content_gzip ) | 535 | # define content_gzip (G.content_gzip ) |
@@ -1563,6 +1575,52 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1563 | #endif | 1575 | #endif |
1564 | 1576 | ||
1565 | #if ENABLE_FEATURE_HTTPD_CGI | 1577 | #if ENABLE_FEATURE_HTTPD_CGI |
1578 | # if ENABLE_PLATFORM_MINGW32 | ||
1579 | static void cgi_handler(char **argv) | ||
1580 | { | ||
1581 | struct fd_pair fromCgi; /* CGI -> httpd pipe */ | ||
1582 | struct fd_pair toCgi; /* httpd -> CGI pipe */ | ||
1583 | char *dir, *script; | ||
1584 | |||
1585 | xfunc_error_retval = 242; | ||
1586 | |||
1587 | if (sscanf(argv[0], "%d:%d:%d:%d", &toCgi.wr, &toCgi.rd, | ||
1588 | &fromCgi.wr, &fromCgi.rd) != 4) { | ||
1589 | exit(242); | ||
1590 | } | ||
1591 | |||
1592 | /* NB: close _first_, then move fds! */ | ||
1593 | close(toCgi.wr); | ||
1594 | close(fromCgi.rd); | ||
1595 | xmove_fd(toCgi.rd, 0); /* replace stdin with the pipe */ | ||
1596 | xmove_fd(fromCgi.wr, 1); /* replace stdout with the pipe */ | ||
1597 | |||
1598 | dir = argv[1]; | ||
1599 | script = argv[2]; | ||
1600 | |||
1601 | if (chdir_or_warn(dir) != 0) { | ||
1602 | goto error_execing_cgi; | ||
1603 | } | ||
1604 | |||
1605 | /* set argv[0] to name without path */ | ||
1606 | argv[0] = script; | ||
1607 | argv[1] = NULL; | ||
1608 | |||
1609 | /* _NOT_ execvp. We do not search PATH. argv[0] is a filename | ||
1610 | * without any dir components and will only match a file | ||
1611 | * in the current directory */ | ||
1612 | if (foreground) | ||
1613 | execv(argv[0], argv); | ||
1614 | else | ||
1615 | httpd_execv_detach(argv[0], argv); | ||
1616 | if (verbose) | ||
1617 | bb_perror_msg("can't execute '%s'", argv[0]); | ||
1618 | error_execing_cgi: | ||
1619 | /* send to stdout */ | ||
1620 | iobuf = xmalloc(IOBUF_SIZE); | ||
1621 | send_headers_and_exit(HTTP_NOT_FOUND); | ||
1622 | } | ||
1623 | # endif | ||
1566 | 1624 | ||
1567 | static void setenv1(const char *name, const char *value) | 1625 | static void setenv1(const char *name, const char *value) |
1568 | { | 1626 | { |
@@ -1596,6 +1654,10 @@ static void send_cgi_and_exit( | |||
1596 | struct fd_pair toCgi; /* httpd -> CGI pipe */ | 1654 | struct fd_pair toCgi; /* httpd -> CGI pipe */ |
1597 | char *script, *last_slash; | 1655 | char *script, *last_slash; |
1598 | int pid; | 1656 | int pid; |
1657 | #if ENABLE_PLATFORM_MINGW32 | ||
1658 | char **argv; | ||
1659 | int i; | ||
1660 | #endif | ||
1599 | 1661 | ||
1600 | /* Make a copy. NB: caller guarantees: | 1662 | /* Make a copy. NB: caller guarantees: |
1601 | * url[0] == '/', url[1] != '/' */ | 1663 | * url[0] == '/', url[1] != '/' */ |
@@ -1682,6 +1744,32 @@ static void send_cgi_and_exit( | |||
1682 | xpiped_pair(fromCgi); | 1744 | xpiped_pair(fromCgi); |
1683 | xpiped_pair(toCgi); | 1745 | xpiped_pair(toCgi); |
1684 | 1746 | ||
1747 | #if ENABLE_PLATFORM_MINGW32 | ||
1748 | /* Find script's dir */ | ||
1749 | script = last_slash; | ||
1750 | if (script != url) { /* paranoia */ | ||
1751 | *script = '\0'; | ||
1752 | } | ||
1753 | script++; | ||
1754 | |||
1755 | argv = xzalloc((server_argc + 9) * sizeof(char *)); | ||
1756 | argv[0] = (char *)bb_busybox_exec_path; | ||
1757 | argv[1] = (char *)"--busybox"; | ||
1758 | argv[2] = (char *)"-httpd" + 1; // skip '-' | ||
1759 | argv[3] = (char *)"-I"; | ||
1760 | argv[4] = (char *)"0"; | ||
1761 | for (i = 0; i < server_argc; ++i) | ||
1762 | argv[i + 5] = server_argv[i]; | ||
1763 | argv[server_argc + 5] = xasprintf("%d:%d:%d:%d", toCgi.wr, toCgi.rd, | ||
1764 | fromCgi.wr, fromCgi.rd); | ||
1765 | argv[server_argc + 6] = (char *)url + 1; // script directory | ||
1766 | argv[server_argc + 7] = (char *)script; // script name | ||
1767 | /* argv[server_argc + 8] = NULL; - xzalloc did it */ | ||
1768 | |||
1769 | pid = foreground ? mingw_spawn(argv) : mingw_spawn_detach(argv); | ||
1770 | if (pid == -1) | ||
1771 | log_and_exit(); | ||
1772 | #else | ||
1685 | pid = vfork(); | 1773 | pid = vfork(); |
1686 | if (pid < 0) { | 1774 | if (pid < 0) { |
1687 | /* TODO: log perror? */ | 1775 | /* TODO: log perror? */ |
@@ -1759,6 +1847,7 @@ static void send_cgi_and_exit( | |||
1759 | 1847 | ||
1760 | /* Restore variables possibly changed by child */ | 1848 | /* Restore variables possibly changed by child */ |
1761 | xfunc_error_retval = 0; | 1849 | xfunc_error_retval = 0; |
1850 | #endif | ||
1762 | 1851 | ||
1763 | /* Pump data */ | 1852 | /* Pump data */ |
1764 | close(fromCgi.wr); | 1853 | close(fromCgi.wr); |
@@ -2797,8 +2886,8 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) | |||
2797 | } | 2886 | } |
2798 | #endif | 2887 | #endif |
2799 | #else /* ENABLE_PLATFORM_MINGW32 */ | 2888 | #else /* ENABLE_PLATFORM_MINGW32 */ |
2800 | static void mini_httpd_win32(int fg, int sock, int argc, char **argv) NORETURN; | 2889 | static void mini_httpd_win32(int sock, int argc, char **argv) NORETURN; |
2801 | static void mini_httpd_win32(int fg, int sock, int argc, char **argv) | 2890 | static void mini_httpd_win32(int sock, int argc, char **argv) |
2802 | { | 2891 | { |
2803 | char *argv_copy[argc + 5]; | 2892 | char *argv_copy[argc + 5]; |
2804 | 2893 | ||
@@ -2820,7 +2909,8 @@ static void mini_httpd_win32(int fg, int sock, int argc, char **argv) | |||
2820 | setsockopt_keepalive(n); | 2909 | setsockopt_keepalive(n); |
2821 | 2910 | ||
2822 | argv_copy[4] = itoa(n); | 2911 | argv_copy[4] = itoa(n); |
2823 | if ((fg ? spawn(argv_copy) : mingw_spawn_detach(argv_copy)) == -1) | 2912 | if ((foreground ? |
2913 | spawn(argv_copy) : mingw_spawn_detach(argv_copy)) == -1) | ||
2824 | bb_perror_msg_and_die("can't execute 'httpd'"); | 2914 | bb_perror_msg_and_die("can't execute 'httpd'"); |
2825 | 2915 | ||
2826 | /* parent, or spawn failed */ | 2916 | /* parent, or spawn failed */ |
@@ -2936,7 +3026,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2936 | "\0" | 3026 | "\0" |
2937 | /* -v counts, -i implies -f */ | 3027 | /* -v counts, -i implies -f */ |
2938 | IF_NOT_PLATFORM_MINGW32("vv:if",) | 3028 | IF_NOT_PLATFORM_MINGW32("vv:if",) |
2939 | IF_PLATFORM_MINGW32("vv:If",) | 3029 | IF_PLATFORM_MINGW32("vv:",) |
2940 | &opt_c_configFile, &url_for_decode, &home_httpd | 3030 | &opt_c_configFile, &url_for_decode, &home_httpd |
2941 | IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) | 3031 | IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) |
2942 | IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) | 3032 | IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) |
@@ -2981,7 +3071,8 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2981 | } | 3071 | } |
2982 | #endif | 3072 | #endif |
2983 | #else /* ENABLE_PLATFORM_MINGW32 */ | 3073 | #else /* ENABLE_PLATFORM_MINGW32 */ |
2984 | if (!(opt & OPT_FOREGROUND) && argv[0][0] != '-') | 3074 | foreground = (opt & OPT_FOREGROUND) == OPT_FOREGROUND; |
3075 | if (!foreground && argv[0][0] != '-') | ||
2985 | mingw_daemonize(argv); | 3076 | mingw_daemonize(argv); |
2986 | #endif | 3077 | #endif |
2987 | 3078 | ||
@@ -3032,7 +3123,14 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
3032 | #endif | 3123 | #endif |
3033 | 3124 | ||
3034 | parse_conf(DEFAULT_PATH_HTTPD_CONF, FIRST_PARSE); | 3125 | parse_conf(DEFAULT_PATH_HTTPD_CONF, FIRST_PARSE); |
3035 | #if !ENABLE_PLATFORM_MINGW32 | 3126 | #if ENABLE_PLATFORM_MINGW32 |
3127 | # if ENABLE_FEATURE_HTTPD_CGI | ||
3128 | if ((opt & OPT_INETD) && fd == 0) { | ||
3129 | cgi_handler(argv + optind); | ||
3130 | return 0; | ||
3131 | } | ||
3132 | # endif | ||
3133 | #else | ||
3036 | if (!(opt & OPT_INETD)) | 3134 | if (!(opt & OPT_INETD)) |
3037 | signal(SIGHUP, sighup_handler); | 3135 | signal(SIGHUP, sighup_handler); |
3038 | #endif | 3136 | #endif |
@@ -3044,6 +3142,11 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
3044 | xdup2(0, 1); | 3142 | xdup2(0, 1); |
3045 | while (--fd > 2) | 3143 | while (--fd > 2) |
3046 | close(fd); | 3144 | close(fd); |
3145 | # if ENABLE_FEATURE_HTTPD_CGI | ||
3146 | /* Skip 'httpd -I N' and omit any non-option arguments */ | ||
3147 | server_argc = optind - 3; | ||
3148 | server_argv = argv + 3; | ||
3149 | # endif | ||
3047 | } | 3150 | } |
3048 | #endif | 3151 | #endif |
3049 | if (opt & OPT_INETD) | 3152 | if (opt & OPT_INETD) |
@@ -3057,7 +3160,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
3057 | mini_httpd_nommu(server_socket, argc, argv); /* never returns */ | 3160 | mini_httpd_nommu(server_socket, argc, argv); /* never returns */ |
3058 | #endif | 3161 | #endif |
3059 | #else /* ENABLE_PLATFORM_MINGW32 */ | 3162 | #else /* ENABLE_PLATFORM_MINGW32 */ |
3060 | mini_httpd_win32(opt & OPT_FOREGROUND, server_socket, argc, argv); | 3163 | mini_httpd_win32(server_socket, argc, argv); |
3061 | #endif | 3164 | #endif |
3062 | /* return 0; */ | 3165 | /* return 0; */ |
3063 | } | 3166 | } |
diff --git a/win32/process.c b/win32/process.c index b51f25d5c..35480e08d 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -248,6 +248,51 @@ grow_argv(char **argv, int n) | |||
248 | return new_argv; | 248 | return new_argv; |
249 | } | 249 | } |
250 | 250 | ||
251 | #if ENABLE_FEATURE_HTTPD_CGI | ||
252 | static int | ||
253 | create_detached_process(const char *prog, char *const *argv) | ||
254 | { | ||
255 | int argc, i; | ||
256 | char *command = NULL; | ||
257 | STARTUPINFO siStartInfo; | ||
258 | PROCESS_INFORMATION piProcInfo; | ||
259 | int success; | ||
260 | |||
261 | argc = string_array_len((char **)argv); | ||
262 | for (i = 0; i < argc; i++) | ||
263 | command = xappendword(command, quote_arg(argv[i])); | ||
264 | |||
265 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
266 | siStartInfo.cb = sizeof(STARTUPINFO); | ||
267 | siStartInfo.hStdInput = (HANDLE)_get_osfhandle(STDIN_FILENO); | ||
268 | siStartInfo.hStdOutput = (HANDLE)_get_osfhandle(STDOUT_FILENO); | ||
269 | siStartInfo.dwFlags = STARTF_USESTDHANDLES; | ||
270 | |||
271 | success = CreateProcess((LPCSTR)prog, | ||
272 | (LPSTR)command, /* command line */ | ||
273 | NULL, /* process security attributes */ | ||
274 | NULL, /* primary thread security attributes */ | ||
275 | TRUE, /* handles are inherited */ | ||
276 | DETACHED_PROCESS, /* creation flags */ | ||
277 | NULL, /* use parent's environment */ | ||
278 | NULL, /* use parent's current directory */ | ||
279 | &siStartInfo, /* STARTUPINFO pointer */ | ||
280 | &piProcInfo); /* receives PROCESS_INFORMATION */ | ||
281 | |||
282 | free(command); | ||
283 | |||
284 | if (!success) | ||
285 | return -1; | ||
286 | exit(0); | ||
287 | } | ||
288 | |||
289 | # define SPAWNVEQ(m, p, a, e) \ | ||
290 | ((m != HTTPD_DETACH) ? spawnveq(m, p, a, e) : \ | ||
291 | create_detached_process(p, a)) | ||
292 | #else | ||
293 | # define SPAWNVEQ(m, p, a, e) spawnveq(m, p, a, e) | ||
294 | #endif | ||
295 | |||
251 | static intptr_t | 296 | static intptr_t |
252 | mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, | 297 | mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, |
253 | char *const *envp, int level) | 298 | char *const *envp, int level) |
@@ -259,7 +304,7 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, | |||
259 | char *path = NULL; | 304 | char *path = NULL; |
260 | 305 | ||
261 | if (!parse_interpreter(prog, &interp)) | 306 | if (!parse_interpreter(prog, &interp)) |
262 | return spawnveq(mode, prog, argv, envp); | 307 | return SPAWNVEQ(mode, prog, argv, envp); |
263 | 308 | ||
264 | if (++level > 4) { | 309 | if (++level > 4) { |
265 | errno = ELOOP; | 310 | errno = ELOOP; |
@@ -275,7 +320,7 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, | |||
275 | if (unix_path(interp.path) && find_applet_by_name(interp.name) >= 0) { | 320 | if (unix_path(interp.path) && find_applet_by_name(interp.name) >= 0) { |
276 | /* the fake path indicates the index of the script */ | 321 | /* the fake path indicates the index of the script */ |
277 | new_argv[0] = path = xasprintf("%d:/%s", nopts+1, interp.name); | 322 | new_argv[0] = path = xasprintf("%d:/%s", nopts+1, interp.name); |
278 | ret = mingw_spawn_applet(mode, new_argv, envp); | 323 | ret = SPAWNVEQ(mode, bb_busybox_exec_path, new_argv, envp); |
279 | goto done; | 324 | goto done; |
280 | } | 325 | } |
281 | #endif | 326 | #endif |
@@ -428,6 +473,17 @@ mingw_execv(const char *cmd, char *const *argv) | |||
428 | return mingw_execve(cmd, argv, NULL); | 473 | return mingw_execve(cmd, argv, NULL); |
429 | } | 474 | } |
430 | 475 | ||
476 | #if ENABLE_FEATURE_HTTPD_CGI | ||
477 | int httpd_execv_detach(const char *script, char *const *argv) | ||
478 | { | ||
479 | intptr_t ret = mingw_spawn_interpreter(HTTPD_DETACH, script, | ||
480 | (char *const *)argv, NULL, 0); | ||
481 | if (ret != -1) | ||
482 | exit(0); | ||
483 | return ret; | ||
484 | } | ||
485 | #endif | ||
486 | |||
431 | static inline long long filetime_to_ticks(const FILETIME *ft) | 487 | static inline long long filetime_to_ticks(const FILETIME *ft) |
432 | { | 488 | { |
433 | return (((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime)/ | 489 | return (((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime)/ |