From c1bc67d13894b1b9456fb85abdabc4dbb5d71bcc Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Fri, 22 Nov 2013 15:22:21 +0000 Subject: [PATCH] Allow configuring output file truncation. A new checkbox in the GUI allows specifying that stdout and stderr should be truncated rather than appended. The registry must still be used to set different disposition for each or to control the disposition of stdin. --- gui.cpp | 15 +++++++++++++++ io.cpp | 17 ++++++++++++++--- io.h | 11 +++++++++++ nssm.rc | 21 +++++++++++---------- registry.cpp | 21 ++++++++++++++++++--- resource.h | 3 ++- service.h | 9 +++++++++ 7 files changed, 80 insertions(+), 17 deletions(-) diff --git a/gui.cpp b/gui.cpp index f9a553d..7cc5bc4 100644 --- a/gui.cpp +++ b/gui.cpp @@ -134,6 +134,21 @@ int install(HWND window) { check_io("stdin", service->stdin_path, sizeof(service->stdin_path), IDC_STDIN); check_io("stdout", service->stdout_path, sizeof(service->stdout_path), IDC_STDOUT); check_io("stderr", service->stderr_path, sizeof(service->stderr_path), IDC_STDERR); + /* I/O defaults. */ + service->stdin_sharing = NSSM_STDIN_SHARING; + service->stdin_disposition = NSSM_STDIN_DISPOSITION; + service->stdin_flags = NSSM_STDIN_FLAGS; + service->stdout_sharing = NSSM_STDOUT_SHARING; + service->stdout_disposition = NSSM_STDOUT_DISPOSITION; + service->stdout_flags = NSSM_STDOUT_FLAGS; + service->stderr_sharing = NSSM_STDERR_SHARING; + service->stderr_disposition = NSSM_STDERR_DISPOSITION; + service->stderr_flags = NSSM_STDERR_FLAGS; + /* Override stdout and/or stderr. */ + if (SendDlgItemMessage(tablist[NSSM_TAB_IO], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) { + if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS; + if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS; + } /* Get environment. */ unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0); diff --git a/io.cpp b/io.cpp index 1c0a9ff..0ab92c3 100644 --- a/io.cpp +++ b/io.cpp @@ -50,6 +50,17 @@ int get_createfile_parameters(HKEY key, char *prefix, char *path, unsigned long return 0; } +int set_createfile_parameter(HKEY key, char *prefix, char *suffix, unsigned long number) { + char value[NSSM_STDIO_LENGTH]; + + if (_snprintf_s(value, sizeof(value), _TRUNCATE, "%s%s", prefix, suffix) < 0) { + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, suffix, "set_createfile_parameter()", 0); + return 1; + } + + return set_number(key, value, number); +} + HANDLE append_to_file(char *path, unsigned long sharing, SECURITY_ATTRIBUTES *attributes, unsigned long disposition, unsigned long flags) { HANDLE ret; @@ -82,7 +93,7 @@ int get_output_handles(HKEY key, STARTUPINFO *si) { attributes.bInheritHandle = true; /* stdin */ - if (get_createfile_parameters(key, NSSM_REG_STDIN, path, &sharing, FILE_SHARE_WRITE, &disposition, OPEN_EXISTING, &flags, FILE_ATTRIBUTE_NORMAL)) return 1; + if (get_createfile_parameters(key, NSSM_REG_STDIN, path, &sharing, NSSM_STDIN_SHARING, &disposition, NSSM_STDIN_DISPOSITION, &flags, NSSM_STDIN_FLAGS)) return 1; if (path[0]) { si->hStdInput = CreateFile(path, FILE_READ_DATA, sharing, &attributes, disposition, flags, 0); if (! si->hStdInput) { @@ -93,7 +104,7 @@ int get_output_handles(HKEY key, STARTUPINFO *si) { } /* stdout */ - if (get_createfile_parameters(key, NSSM_REG_STDOUT, path, &sharing, FILE_SHARE_READ | FILE_SHARE_WRITE, &disposition, OPEN_ALWAYS, &flags, FILE_ATTRIBUTE_NORMAL)) return 3; + if (get_createfile_parameters(key, NSSM_REG_STDOUT, path, &sharing, NSSM_STDOUT_SHARING, &disposition, NSSM_STDOUT_DISPOSITION, &flags, NSSM_STDOUT_FLAGS)) return 3; if (path[0]) { /* Remember path for comparison with stderr. */ if (_snprintf_s(stdout_path, sizeof(stdout_path), _TRUNCATE, "%s", path) < 0) { @@ -108,7 +119,7 @@ int get_output_handles(HKEY key, STARTUPINFO *si) { else ZeroMemory(stdout_path, sizeof(stdout_path)); /* stderr */ - if (get_createfile_parameters(key, NSSM_REG_STDERR, path, &sharing, FILE_SHARE_READ | FILE_SHARE_WRITE, &disposition, OPEN_ALWAYS, &flags, FILE_ATTRIBUTE_NORMAL)) return 6; + if (get_createfile_parameters(key, NSSM_REG_STDERR, path, &sharing, NSSM_STDERR_SHARING, &disposition, NSSM_STDERR_DISPOSITION, &flags, NSSM_STDERR_FLAGS)) return 6; if (path[0]) { /* Same as stdin? */ if (str_equiv(path, stdout_path)) { diff --git a/io.h b/io.h index f8fb256..1abaf1b 100644 --- a/io.h +++ b/io.h @@ -1,7 +1,18 @@ #ifndef IO_H #define IO_H +#define NSSM_STDIN_SHARING FILE_SHARE_WRITE +#define NSSM_STDIN_DISPOSITION OPEN_EXISTING +#define NSSM_STDIN_FLAGS FILE_ATTRIBUTE_NORMAL +#define NSSM_STDOUT_SHARING (FILE_SHARE_READ | FILE_SHARE_WRITE) +#define NSSM_STDOUT_DISPOSITION OPEN_ALWAYS +#define NSSM_STDOUT_FLAGS FILE_ATTRIBUTE_NORMAL +#define NSSM_STDERR_SHARING (FILE_SHARE_READ | FILE_SHARE_WRITE) +#define NSSM_STDERR_DISPOSITION OPEN_ALWAYS +#define NSSM_STDERR_FLAGS FILE_ATTRIBUTE_NORMAL + int get_createfile_parameters(HKEY, char *, char *, unsigned long *, unsigned long, unsigned long *, unsigned long, unsigned long *, unsigned long); +int set_createfile_parameter(HKEY, char *, char *, unsigned long); HANDLE append_to_file(char *, unsigned long, SECURITY_ATTRIBUTES *, unsigned long, unsigned long); int get_output_handles(HKEY, STARTUPINFO *); void close_output_handles(STARTUPINFO *); diff --git a/nssm.rc b/nssm.rc index f825826..9596674 100644 --- a/nssm.rc +++ b/nssm.rc @@ -87,11 +87,11 @@ BEGIN END LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_APPLICATION DIALOG 9, 20, 261, 73 +IDD_APPLICATION DIALOG 9, 20, 261, 75 STYLE DS_SHELLFONT | WS_VISIBLE | WS_CHILD | DS_CONTROL FONT 8, "MS Sans Serif" { - GROUPBOX "Application", IDC_STATIC, 7, 7, 251, 58 + GROUPBOX "Application", IDC_STATIC, 7, 7, 251, 68 LTEXT "Path:", IDC_STATIC, 13, 18, 53, 8, SS_LEFT EDITTEXT IDC_PATH, 70, 16, 167, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES DEFPUSHBUTTON "...", IDC_BROWSE, 239, 15, 15, 14 @@ -126,7 +126,7 @@ FONT 8, "MS Sans Serif" } LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDD_APPEXIT DIALOG 9, 20, 261, 73 +IDD_APPEXIT DIALOG 9, 20, 261, 75 STYLE DS_SHELLFONT | WS_VISIBLE | WS_CHILD | DS_CONTROL FONT 8, "MS Sans Serif" { @@ -134,17 +134,17 @@ FONT 8, "MS Sans Serif" LTEXT "Delay restart if application runs for less than", IDC_STATIC, 13, 18, 137, 8, SS_LEFT EDITTEXT IDC_THROTTLE, 152, 16, 29, 12, ES_AUTOHSCROLL | ES_NUMBER LTEXT "ms", IDC_STATIC, 186, 18, 10, 8, SS_LEFT - GROUPBOX "Restart", IDC_STATIC, 7, 33, 251, 35 + GROUPBOX "Restart", IDC_STATIC, 7, 33, 251, 42 LTEXT "Action to take when application exits other\nthan in response to a controlled service\nshutdown:", IDC_STATIC, 14, 42, 134, 24, SS_LEFT COMBOBOX IDC_APPEXIT, 153, 47, 100, 120, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_TABSTOP } LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDD_IO DIALOG 9, 20, 261, 73 +IDD_IO DIALOG 9, 20, 261, 75 STYLE DS_SHELLFONT | WS_VISIBLE | WS_CHILD | DS_CONTROL FONT 8, "MS Sans Serif" { - GROUPBOX "I/O redirection", IDC_STATIC, 7, 7, 251, 58 + GROUPBOX "I/O redirection", IDC_STATIC, 7, 7, 251, 68 LTEXT "Input (stdin):", IDC_STATIC, 13, 18, 53, 8, SS_LEFT EDITTEXT IDC_STDIN, 70, 16, 167, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES DEFPUSHBUTTON "...", IDC_BROWSE_STDIN, 239, 15, 15, 14 @@ -154,6 +154,7 @@ FONT 8, "MS Sans Serif" LTEXT "Error (stderr):", IDC_STATIC, 13, 50, 53, 8, SS_LEFT EDITTEXT IDC_STDERR, 70, 48, 167, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES DEFPUSHBUTTON "...", IDC_BROWSE_STDERR, 239, 47, 15, 14 + AUTOCHECKBOX "Replace files", IDC_TRUNCATE, 13, 60, 74, 8 } LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL @@ -263,11 +264,11 @@ BEGIN END LANGUAGE LANG_FRENCH, SUBLANG_FRENCH -IDD_APPLICATION DIALOG 9, 20, 261, 73 +IDD_APPLICATION DIALOG 9, 20, 261, 75 STYLE DS_SHELLFONT | WS_VISIBLE | WS_CHILD | DS_CONTROL FONT 8, "MS Sans Serif" { - GROUPBOX "Application", IDC_STATIC, 7, 7, 251, 58 + GROUPBOX "Application", IDC_STATIC, 7, 7, 251, 68 LTEXT "Chemin:", IDC_STATIC, 13, 18, 53, 8, SS_LEFT EDITTEXT IDC_PATH, 80, 16, 157, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES DEFPUSHBUTTON "...", IDC_BROWSE, 239, 15, 15, 14 @@ -388,11 +389,11 @@ BEGIN END LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN -IDD_APPLICATION DIALOG 9, 20, 261, 73 +IDD_APPLICATION DIALOG 9, 20, 261, 75 STYLE DS_SHELLFONT | WS_VISIBLE | WS_CHILD | DS_CONTROL FONT 8, "MS Sans Serif" { - GROUPBOX "Applicazione", IDC_STATIC, 7, 7, 251, 58 + GROUPBOX "Applicazione", IDC_STATIC, 7, 7, 251, 68 LTEXT "Path:", IDC_STATIC, 13, 18, 53, 8, SS_LEFT EDITTEXT IDC_PATH, 70, 16, 167, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES DEFPUSHBUTTON "...", IDC_BROWSE, 239, 16, 15, 14 diff --git a/registry.cpp b/registry.cpp index 458127c..c63821d 100644 --- a/registry.cpp +++ b/registry.cpp @@ -68,9 +68,24 @@ int create_parameters(nssm_service_t *service) { if (service->kill_console_delay != NSSM_KILL_CONSOLE_GRACE_PERIOD) set_number(key, NSSM_REG_KILL_CONSOLE_GRACE_PERIOD, service->kill_console_delay); if (service->kill_window_delay != NSSM_KILL_WINDOW_GRACE_PERIOD) set_number(key, NSSM_REG_KILL_WINDOW_GRACE_PERIOD, service->kill_window_delay); if (service->kill_threads_delay != NSSM_KILL_THREADS_GRACE_PERIOD) set_number(key, NSSM_REG_KILL_THREADS_GRACE_PERIOD, service->kill_threads_delay); - if (service->stdin_path[0]) set_expand_string(key, NSSM_REG_STDIN, service->stdin_path); - if (service->stdout_path[0]) set_expand_string(key, NSSM_REG_STDOUT, service->stdout_path); - if (service->stderr_path[0]) set_expand_string(key, NSSM_REG_STDERR, service->stderr_path); + if (service->stdin_path[0]) { + set_expand_string(key, NSSM_REG_STDIN, service->stdin_path); + if (service->stdin_sharing != NSSM_STDIN_SHARING) set_createfile_parameter(key, NSSM_REG_STDIN, NSSM_REG_STDIO_SHARING, service->stdin_sharing); + if (service->stdin_disposition != NSSM_STDIN_DISPOSITION) set_createfile_parameter(key, NSSM_REG_STDIN, NSSM_REG_STDIO_DISPOSITION, service->stdin_disposition); + if (service->stdin_flags != NSSM_STDIN_FLAGS) set_createfile_parameter(key, NSSM_REG_STDIN, NSSM_REG_STDIO_FLAGS, service->stdin_flags); + } + if (service->stdout_path[0]) { + set_expand_string(key, NSSM_REG_STDOUT, service->stdout_path); + if (service->stdout_sharing != NSSM_STDOUT_SHARING) set_createfile_parameter(key, NSSM_REG_STDOUT, NSSM_REG_STDIO_SHARING, service->stdout_sharing); + if (service->stdout_disposition != NSSM_STDOUT_DISPOSITION) set_createfile_parameter(key, NSSM_REG_STDOUT, NSSM_REG_STDIO_DISPOSITION, service->stdout_disposition); + if (service->stdout_flags != NSSM_STDOUT_FLAGS) set_createfile_parameter(key, NSSM_REG_STDOUT, NSSM_REG_STDIO_FLAGS, service->stdout_flags); + } + if (service->stderr_path[0]) { + set_expand_string(key, NSSM_REG_STDERR, service->stderr_path); + if (service->stderr_sharing != NSSM_STDERR_SHARING) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_SHARING, service->stderr_sharing); + if (service->stderr_disposition != NSSM_STDERR_DISPOSITION) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_DISPOSITION, service->stderr_disposition); + if (service->stderr_flags != NSSM_STDERR_FLAGS) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_FLAGS, service->stderr_flags); + } /* Environment */ if (service->env) { diff --git a/resource.h b/resource.h index 63fb69e..d6f2792 100644 --- a/resource.h +++ b/resource.h @@ -37,6 +37,7 @@ #define IDC_BROWSE_DIR 1024 #define IDC_ENVIRONMENT 1025 #define IDC_ENVIRONMENT_REPLACE 1026 +#define IDC_TRUNCATE 1027 // Next default values for new objects // @@ -44,7 +45,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1027 +#define _APS_NEXT_CONTROL_VALUE 1028 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/service.h b/service.h index 5c56ed5..9c596f1 100644 --- a/service.h +++ b/service.h @@ -26,8 +26,17 @@ typedef struct { char *env_extra; unsigned long env_extralen; char stdin_path[MAX_PATH]; + unsigned long stdin_sharing; + unsigned long stdin_disposition; + unsigned long stdin_flags; char stdout_path[MAX_PATH]; + unsigned long stdout_sharing; + unsigned long stdout_disposition; + unsigned long stdout_flags; char stderr_path[MAX_PATH]; + unsigned long stderr_sharing; + unsigned long stderr_disposition; + unsigned long stderr_flags; unsigned long default_exit_action; unsigned long throttle_delay; unsigned long stop_method; -- 2.20.1