diff --git a/smartmontools/ChangeLog b/smartmontools/ChangeLog index 214614814b7d268e9163ed547839fe81ec6c8365..ab753db4c4a61bbdc8b09245e8f506a94a0d3fc1 100644 --- a/smartmontools/ChangeLog +++ b/smartmontools/ChangeLog @@ -1,5 +1,17 @@ $Id$ +2018-10-17 Christian Franke <franke@computer.org> + + os_win32/popen_win32.cpp, os_win32/popen.h: New popen()/pclose() + for Windows. Unlike MSVCRT _popen(), it does not open a new console. + os_win32.cpp: Remove run_cmd(), use popen() instead. + os_win32/daemon_win32.cpp, os_win32/daemon_win32.h: Remove + daemon_spawn(). + smartd.cpp: Remove _WIN32 specific usage of daemon_spawn(), + use generic code with popen() also on Windows. + Makefile.am, os_win32/vc14/smart*.vcxproj*: Add new files. + + 2018-10-17 Rick Chen <juihsiang.chen@gmail.com> scsiprint.cpp: Add SCSI information to JSON output as below: diff --git a/smartmontools/Makefile.am b/smartmontools/Makefile.am index f2faf5c0aa5ffc5db9225921f15e53945e6e33f6..f63a90212ea372ed5fc57e3f56d84c8866f0dc6f 100644 --- a/smartmontools/Makefile.am +++ b/smartmontools/Makefile.am @@ -121,6 +121,10 @@ EXTRA_smartctl_SOURCES = \ if OS_WIN32_MINGW +smartctl_SOURCES += \ + os_win32/popen_win32.cpp \ + os_win32/popen.h + smartctl_LDADD += smartctl_res.o smartctl_DEPENDENCIES += smartctl_res.o @@ -192,6 +196,8 @@ if OS_WIN32_MINGW smartd_SOURCES += \ os_win32/daemon_win32.cpp \ os_win32/daemon_win32.h \ + os_win32/popen_win32.cpp \ + os_win32/popen.h \ os_win32/syslog_win32.cpp \ os_win32/syslog.h diff --git a/smartmontools/os_win32.cpp b/smartmontools/os_win32.cpp index 8f22359c096cfda3b4ce15db3413bdcc1893510b..00d5ce3ad4199af7219e8fdb9e4c02432b97637b 100644 --- a/smartmontools/os_win32.cpp +++ b/smartmontools/os_win32.cpp @@ -28,6 +28,7 @@ #include "dev_areca.h" #include "os_win32/wmiquery.h" +#include "os_win32/popen.h" // TODO: Move from smartctl.h to other include file extern unsigned char failuretest_permissive; @@ -2555,63 +2556,6 @@ static int get_clipboard(char * data, int datasize) } -// Run a command, write stdout to dataout -// TODO: Combine with daemon_win32.cpp:daemon_spawn() - -static int run_cmd(const char * cmd, char * dataout, int outsize) -{ - // Create stdout pipe - SECURITY_ATTRIBUTES sa = {sizeof(sa), 0, TRUE}; - HANDLE pipe_out_w, h; - if (!CreatePipe(&h, &pipe_out_w, &sa/*inherit*/, outsize)) - return -1; - HANDLE self = GetCurrentProcess(); - HANDLE pipe_out_r; - if (!DuplicateHandle(self, h, self, &pipe_out_r, - GENERIC_READ, FALSE/*!inherit*/, DUPLICATE_CLOSE_SOURCE)) { - CloseHandle(pipe_out_w); - return -1; - } - HANDLE pipe_err_w; - if (!DuplicateHandle(self, pipe_out_w, self, &pipe_err_w, - 0, TRUE/*inherit*/, DUPLICATE_SAME_ACCESS)) { - CloseHandle(pipe_out_r); CloseHandle(pipe_out_w); - return -1; - } - - // Create process - STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); - si.hStdInput = INVALID_HANDLE_VALUE; - si.hStdOutput = pipe_out_w; si.hStdError = pipe_err_w; - si.dwFlags = STARTF_USESTDHANDLES; - PROCESS_INFORMATION pi; - if (!CreateProcess( - NULL, const_cast<char *>(cmd), - NULL, NULL, TRUE/*inherit*/, - CREATE_NO_WINDOW/*do not create a new console window*/, - NULL, NULL, &si, &pi)) { - CloseHandle(pipe_err_w); CloseHandle(pipe_out_r); CloseHandle(pipe_out_w); - return -1; - } - CloseHandle(pi.hThread); - CloseHandle(pipe_err_w); CloseHandle(pipe_out_w); - - // Copy stdout to output buffer - int i = 0; - while (i < outsize) { - DWORD num_read; - if (!ReadFile(pipe_out_r, dataout+i, outsize-i, &num_read, NULL) || num_read == 0) - break; - i += num_read; - } - CloseHandle(pipe_out_r); - // Wait for process - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - return i; -} - - static const char * findstr(const char * str, const char * sub) { const char * s = strstr(str, sub); @@ -2638,7 +2582,11 @@ bool win_tw_cli_device::open() snprintf(cmd, sizeof(cmd), "tw_cli /%s show all", name+n1); if (ata_debugmode > 1) pout("%s: Run: \"%s\"\n", name, cmd); - size = run_cmd(cmd, buffer, sizeof(buffer)); + FILE * f = popen(cmd, "rb"); + if (f) { + size = fread(buffer, 1, sizeof(buffer), f); + pclose(f); + } } else { return set_err(EINVAL); diff --git a/smartmontools/os_win32/daemon_win32.cpp b/smartmontools/os_win32/daemon_win32.cpp index 94cc5b05c5d092d1325116ca30cf22d6be4ae3fe..7cab81fbd62a455fca83829ec1b2a0f12a61b463 100644 --- a/smartmontools/os_win32/daemon_win32.cpp +++ b/smartmontools/os_win32/daemon_win32.cpp @@ -3,7 +3,7 @@ * * Home page of code is: http://www.smartmontools.org * - * Copyright (C) 2004-14 Christian Franke + * Copyright (C) 2004-18 Christian Franke * * SPDX-License-Identifier: GPL-2.0-or-later */ @@ -457,120 +457,6 @@ int daemon_detach(const char * ident) } -///////////////////////////////////////////////////////////////////////////// - -// Spawn a command and redirect <inpbuf >outbuf -// return command's exitcode or -1 on error - -int daemon_spawn(const char * cmd, - const char * inpbuf, int inpsize, - char * outbuf, int outsize ) -{ - HANDLE self = GetCurrentProcess(); - - // Create stdin pipe with inheritable read side - SECURITY_ATTRIBUTES sa; - memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - HANDLE pipe_inp_r, pipe_inp_w, h; - if (!CreatePipe(&pipe_inp_r, &h, &sa/*inherit*/, inpsize*2+13)) - return -1; - if (!DuplicateHandle(self, h, self, &pipe_inp_w, - 0, FALSE/*!inherit*/, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) { - CloseHandle(pipe_inp_r); - return -1; - } - - // Create stdout pipe with inheritable write side - memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - HANDLE pipe_out_w; - if (!CreatePipe(&h, &pipe_out_w, &sa/*inherit*/, outsize)) { - CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w); - return -1; - } - - HANDLE pipe_out_r; - if (!DuplicateHandle(self, h, self, &pipe_out_r, - GENERIC_READ, FALSE/*!inherit*/, DUPLICATE_CLOSE_SOURCE)) { - CloseHandle(pipe_out_w); CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w); - return -1; - } - - // Create stderr handle as dup of stdout write side - HANDLE pipe_err_w; - if (!DuplicateHandle(self, pipe_out_w, self, &pipe_err_w, - 0, TRUE/*inherit*/, DUPLICATE_SAME_ACCESS)) { - CloseHandle(pipe_out_r); CloseHandle(pipe_out_w); - CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w); - return -1; - } - - // Create process with pipes as stdio - STARTUPINFO si; - memset(&si, 0, sizeof(si)); si.cb = sizeof(si); - si.hStdInput = pipe_inp_r; - si.hStdOutput = pipe_out_w; - si.hStdError = pipe_err_w; - si.dwFlags = STARTF_USESTDHANDLES; - PROCESS_INFORMATION pi; - if (!CreateProcessA( - NULL, (char*)cmd, - NULL, NULL, TRUE/*inherit*/, - CREATE_NO_WINDOW, // DETACHED_PROCESS does not work - NULL, NULL, &si, &pi)) { - CloseHandle(pipe_err_w); - CloseHandle(pipe_out_r); CloseHandle(pipe_out_w); - CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w); - return -1; - } - CloseHandle(pi.hThread); - // Close inherited handles - CloseHandle(pipe_inp_r); - CloseHandle(pipe_out_w); - CloseHandle(pipe_err_w); - - // Copy inpbuf to stdin - // convert \n => \r\n - DWORD num_io; - int i; - for (i = 0; i < inpsize; ) { - int len = 0; - while (i+len < inpsize && inpbuf[i+len] != '\n') - len++; - if (len > 0) - WriteFile(pipe_inp_w, inpbuf+i, len, &num_io, NULL); - i += len; - if (i < inpsize) { - WriteFile(pipe_inp_w, "\r\n", 2, &num_io, NULL); - i++; - } - } - CloseHandle(pipe_inp_w); - - // Copy stdout to output buffer until full, rest to /dev/null - // convert \r\n => \n - for (i = 0; ; ) { - char buf[256]; - if (!ReadFile(pipe_out_r, buf, sizeof(buf), &num_io, NULL) || num_io == 0) - break; - for (int j = 0; i < outsize-1 && j < (int)num_io; j++) { - if (buf[j] != '\r') - outbuf[i++] = buf[j]; - } - } - outbuf[i] = 0; - CloseHandle(pipe_out_r); - - // Wait for process exitcode - DWORD exitcode = 42; - WaitForSingleObject(pi.hProcess, INFINITE); - GetExitCodeProcess(pi.hProcess, &exitcode); - CloseHandle(pi.hProcess); - return exitcode; -} - - ///////////////////////////////////////////////////////////////////////////// // Initd Functions diff --git a/smartmontools/os_win32/daemon_win32.h b/smartmontools/os_win32/daemon_win32.h index 7cbc42ccc1e5429edb9c8038c05537f02feb6f4e..a41b1fdb8d7fd27016caa21a41d4d3db6ab8ef29 100644 --- a/smartmontools/os_win32/daemon_win32.h +++ b/smartmontools/os_win32/daemon_win32.h @@ -3,7 +3,7 @@ * * Home page of code is: http://www.smartmontools.org * - * Copyright (C) 2004-12 Christian Franke + * Copyright (C) 2004-18 Christian Franke * * SPDX-License-Identifier: GPL-2.0-or-later */ @@ -52,9 +52,4 @@ int daemon_enable_console(const char * title); // Detach from console int daemon_detach(const char * ident); -// Spawn a process and redirect stdio -int daemon_spawn(const char * cmd, - const char * inpbuf, int inpsize, - char * outbuf, int outsize ); - #endif // DAEMON_WIN32_H diff --git a/smartmontools/os_win32/popen.h b/smartmontools/os_win32/popen.h new file mode 100644 index 0000000000000000000000000000000000000000..a0c0c91b895239d93f421787e1c0f81f45033b33 --- /dev/null +++ b/smartmontools/os_win32/popen.h @@ -0,0 +1,55 @@ +/* + * os_win32/popen.h + * + * Home page of code is: https://www.smartmontools.org + * + * Copyright (C) 2018 Christian Franke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef POPEN_H +#define POPEN_H + +#define POPEN_H_CVSID "$Id$" + +#include <stdio.h> + +// MinGW <stdio.h> defines these to _popen/_pclose +#undef popen +#undef pclose + +#ifdef __cplusplus +extern "C" { +#endif + +// popen(3) reimplementation for Windows +// +// The _popen() from MSVCRT is not useful as it always opens a new +// console window if parent process has none. +// +// Differences to popen(3): +// - Only modes "r[bt]" are supported +// - stdin and stderr from parent are not inherited to child process +// but redirected to null device +// - Only one child process can be run at a time + +FILE * popen(const char * command, const char * mode); + +int pclose(FILE * f); + +#ifdef __cplusplus +} +#endif + +// wait(3) macros from <sys/wait.h> +#ifndef WIFEXITED +#define WIFEXITED(status) (((status) & 0xff) == 0x00) +#define WIFSIGNALED(status) (((status) & 0xff) != 0x00) +#define WIFSTOPPED(status) (0) +#define WEXITSTATUS(status) ((status) >> 8) +#define WTERMSIG(status) ((status) & 0xff) +#define WSTOPSIG(status) (0) +#endif // WIFEXITED + +#endif // POPEN_H diff --git a/smartmontools/os_win32/popen_win32.cpp b/smartmontools/os_win32/popen_win32.cpp new file mode 100644 index 0000000000000000000000000000000000000000..717fa7d9345da7926214ceeadfe4c3b488c47103 --- /dev/null +++ b/smartmontools/os_win32/popen_win32.cpp @@ -0,0 +1,176 @@ +/* + * os_win32/popen_win32.cpp + * + * Home page of code is: https://www.smartmontools.org + * + * Copyright (C) 2018 Christian Franke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "popen.h" + +const char * popen_win32_cpp_cvsid = "$Id$" + POPEN_H_CVSID; + +#include <errno.h> +#include <fcntl.h> +#include <io.h> // _open_osfhandle() +#include <signal.h> // SIGSEGV +#include <stdlib.h> +#include <string.h> + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +static FILE * s_popen_file; +static HANDLE s_popen_process; + +extern "C" +FILE * popen(const char * command, const char * mode) +{ + // Fail if previous run is still in progress + if (s_popen_file) { + errno = EEXIST; + return (FILE *)0; + } + + // mode "w" is not implemented + if (!(mode[0] == 'r' && (!mode[1] || !mode[2]))) { + errno = EINVAL; + return (FILE *)0; + } + + // Set flags for text or binary mode + // Note: _open_osfhandle() ignores _fmode and defaults to O_BINARY + int oflags; const char * fomode; + switch (mode[1]) { + case 0: + case 't': + oflags = O_RDONLY|O_TEXT; + fomode = "rt"; + break; + case 'b': + oflags = O_RDONLY|O_BINARY; + fomode = "rb"; + break; + default: + errno = EINVAL; + return (FILE *)0; + } + + // Create stdout pipe with inheritable write end + HANDLE pipe_out_r, pipe_out_w; + if (!CreatePipe(&pipe_out_r, &pipe_out_w, (SECURITY_ATTRIBUTES *)0, 1024)) { + errno = EMFILE; + return (FILE *)0; + } + if (!SetHandleInformation(pipe_out_w, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + CloseHandle(pipe_out_r); CloseHandle(pipe_out_w); + errno = EMFILE; + return (FILE *)0; + } + + // Connect pipe read end to new FD + int fd = _open_osfhandle((intptr_t)pipe_out_r, oflags); + if (fd < 0) { + CloseHandle(pipe_out_r); CloseHandle(pipe_out_w); + return (FILE *)0; + } + + // Connect FD to new FILE + FILE * f = fdopen(fd, fomode); + if (!f) { + int err = errno; + close(fd); // CloseHandle(pipe_out_r) + CloseHandle(pipe_out_w); + errno = err; + return (FILE *)0; + } + + // Build command line "cmd /c COMMAND" + int cmdlen = strlen(command); + char * shellcmd = (char *)malloc(7 + cmdlen + 1); + if (!shellcmd) { + fclose(f); // CloseHandle(pipe_out_r) + CloseHandle(pipe_out_w); + errno = ENOMEM; + return (FILE *)0; + } + memcpy(shellcmd, "cmd /c ", 7); + memcpy(shellcmd + 7, command, cmdlen + 1); + + // Redirect stdin stderr to null device + // Don't inherit parent's stdin, script may hang if parent has no console. + SECURITY_ATTRIBUTES sa_inherit = { sizeof(sa_inherit), (SECURITY_DESCRIPTOR *)0, TRUE }; + HANDLE null_in = CreateFile("nul", GENERIC_READ , 0, &sa_inherit, OPEN_EXISTING, 0, (HANDLE)0); + HANDLE null_err = CreateFile("nul", GENERIC_WRITE, 0, &sa_inherit, OPEN_EXISTING, 0, (HANDLE)0); + + // Set stdio handles + STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); + si.hStdInput = null_in; + si.hStdOutput = pipe_out_w; + si.hStdError = null_err; + si.dwFlags = STARTF_USESTDHANDLES; + + // Create process + PROCESS_INFORMATION pi; + BOOL ok = CreateProcessA( + getenv("COMSPEC"), // "C:\WINDOWS\system32\cmd.exe" or nullptr + shellcmd, // "cmd /c COMMAND" ("cmd" searched in PATH if COMSPEC not set) + (SECURITY_ATTRIBUTES *)0, (SECURITY_ATTRIBUTES *)0, + TRUE, // inherit + CREATE_NO_WINDOW, // DETACHED_PROCESS would open new console(s) + (void *)0, (char *)0, &si, &pi + ); + free(shellcmd); + + // Close inherited handles + CloseHandle(null_err); + CloseHandle(null_in); + CloseHandle(pipe_out_w); + + if (!ok) { + fclose(f); // CloseHandle(pipe_out_r) + errno = ENOENT; + return (FILE *)0; + } + + // Store process and FILE for pclose() + CloseHandle(pi.hThread); + s_popen_process = pi.hProcess; + s_popen_file = f; + + return f; +} + +extern "C" +int pclose(FILE * f) +{ + if (f != s_popen_file) { + errno = EBADF; + return -1; + } + + fclose(f); + s_popen_file = 0; + + // Wait for process exitcode + DWORD exitcode = 42; + bool ok = ( WaitForSingleObject(s_popen_process, INFINITE) == WAIT_OBJECT_0 + && GetExitCodeProcess(s_popen_process, &exitcode)); + + CloseHandle(s_popen_process); + s_popen_process = 0; + + if (!ok) { + errno = ECHILD; + return -1; + } + + // Modify exitcode for wait(3) macros + if (exitcode >> 23) + return ((exitcode << 9) >> 1) | SIGSEGV; + else + return exitcode << 8; +} diff --git a/smartmontools/os_win32/vc14/smartctl.vcxproj b/smartmontools/os_win32/vc14/smartctl.vcxproj index 33a532478bb27bdf34f9841ec6b96e3580477c00..d42cacd015325fdf4620d8c9ee04e23a7379f26c 100644 --- a/smartmontools/os_win32/vc14/smartctl.vcxproj +++ b/smartmontools/os_win32/vc14/smartctl.vcxproj @@ -166,6 +166,7 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\popen_win32.cpp" /> <ClCompile Include="..\syslog_win32.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> @@ -290,6 +291,7 @@ <ClInclude Include="..\..\json.h" /> <ClInclude Include="..\..\nvmecmds.h" /> <ClInclude Include="..\..\nvmeprint.h" /> + <ClInclude Include="..\popen.h" /> <ClInclude Include="config.h" /> <ClInclude Include="svnversion.h" /> <CustomBuildStep Include="..\daemon_win32.h"> diff --git a/smartmontools/os_win32/vc14/smartctl.vcxproj.filters b/smartmontools/os_win32/vc14/smartctl.vcxproj.filters index 72e6f9fada82d24ccb52069f9d89ee622a4617e9..a2405bf15de3b551bb9299cd20a6574d36c804b9 100644 --- a/smartmontools/os_win32/vc14/smartctl.vcxproj.filters +++ b/smartmontools/os_win32/vc14/smartctl.vcxproj.filters @@ -69,6 +69,9 @@ <ClCompile Include="..\..\nvmeprint.cpp" /> <ClCompile Include="..\..\dev_intelliprop.cpp" /> <ClCompile Include="..\..\json.cpp" /> + <ClCompile Include="..\popen_win32.cpp"> + <Filter>os_win32</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\wmiquery.h"> @@ -115,6 +118,9 @@ <ClInclude Include="..\..\getopt\bits\getopt_ext.h"> <Filter>getopt</Filter> </ClInclude> + <ClInclude Include="..\popen.h"> + <Filter>os_win32</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="..\installer.nsi"> diff --git a/smartmontools/os_win32/vc14/smartd.vcxproj b/smartmontools/os_win32/vc14/smartd.vcxproj index ca4cf688ab0198c5e9a93320fb5e86a8d6cc24a3..2b02af72ba3803886297e52ff43b4fd02c29593a 100644 --- a/smartmontools/os_win32/vc14/smartd.vcxproj +++ b/smartmontools/os_win32/vc14/smartd.vcxproj @@ -170,6 +170,7 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\daemon_win32.cpp" /> + <ClCompile Include="..\popen_win32.cpp" /> <ClCompile Include="..\syslog_win32.cpp" /> <ClCompile Include="..\wmiquery.cpp" /> <ClCompile Include="..\..\regex\regcomp.c"> @@ -309,6 +310,7 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\daemon_win32.h" /> + <ClInclude Include="..\popen.h" /> <ClInclude Include="..\syslog.h" /> <ClInclude Include="..\wmiquery.h" /> <ClInclude Include="..\..\regex\regex.h" /> diff --git a/smartmontools/os_win32/vc14/smartd.vcxproj.filters b/smartmontools/os_win32/vc14/smartd.vcxproj.filters index 84e604f2ac1d32b69ba690eec1a6fe9eccf8601a..ce761a736c14216b0b36f51241b2cc79cc210652 100644 --- a/smartmontools/os_win32/vc14/smartd.vcxproj.filters +++ b/smartmontools/os_win32/vc14/smartd.vcxproj.filters @@ -68,6 +68,9 @@ <ClCompile Include="..\..\nvmecmds.cpp" /> <ClCompile Include="..\..\nvmeprint.cpp" /> <ClCompile Include="..\..\dev_intelliprop.cpp" /> + <ClCompile Include="..\popen_win32.cpp"> + <Filter>os_win32</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\daemon_win32.h"> @@ -116,6 +119,9 @@ <ClInclude Include="..\..\getopt\bits\getopt_ext.h"> <Filter>getopt</Filter> </ClInclude> + <ClInclude Include="..\popen.h"> + <Filter>os_win32</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="..\installer.nsi"> diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp index 416dc43bc9e9ba70861730d9006c543cb37ad913..26757a8d1cee3c8d3d650c7d350fd72ff616d4f1 100644 --- a/smartmontools/smartd.cpp +++ b/smartmontools/smartd.cpp @@ -42,6 +42,7 @@ #endif #ifdef _WIN32 +#include "os_win32/popen.h" // popen/pclose() #ifdef _MSC_VER #pragma warning(disable:4761) // "conversion supplied" typedef unsigned short mode_t; @@ -73,7 +74,7 @@ typedef int pid_t; #ifdef _WIN32 // fork()/signal()/initd simulation for native Windows -#include "daemon_win32.h" // daemon_main/detach/signal() +#include "os_win32/daemon_win32.h" // daemon_main/detach/signal() #define strsignal daemon_strsignal #define sleep daemon_sleep // SIGQUIT does not exist, CONTROL-Break signals SIGBREAK. @@ -1192,7 +1193,6 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co const char * newadd = (!address.empty()? address.c_str() : "<nomailer>"); const char * newwarn = (which? "Warning via" : "Test of"); -#ifndef _WIN32 char command[2048]; snprintf(command, sizeof(command), "%s 2>&1", warning_script.c_str()); @@ -1265,29 +1265,6 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co } } - -#else // _WIN32 - { - char command[2048]; - snprintf(command, sizeof(command), "cmd /c \"%s\"", warning_script.c_str()); - - char stdoutbuf[800]; // < buffer in syslog_win32::vsyslog() - int rc; - // run command - PrintOut(LOG_INFO,"%s %s to %s ...\n", - (which?"Sending warning via":"Executing test of"), executable, newadd); - rc = daemon_spawn(command, "", 0, stdoutbuf, sizeof(stdoutbuf)); - if (rc >= 0 && stdoutbuf[0]) - PrintOut(LOG_CRIT,"%s %s to %s produced unexpected output (%d bytes) to STDOUT/STDERR:\n%s\n", - newwarn, executable, newadd, (int)strlen(stdoutbuf), stdoutbuf); - if (rc != 0) - PrintOut(LOG_CRIT,"%s %s to %s: failed, exit status %d\n", - newwarn, executable, newadd, rc); - else - PrintOut(LOG_INFO,"%s %s to %s: successful\n", newwarn, executable, newadd); - } - -#endif // _WIN32 // increment mail sent counter mail->logged++;