Browse Source

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.
Iain Patterson 8 years ago
parent
commit
c1bc67d138
7 changed files with 80 additions and 17 deletions
  1. 15 0
      gui.cpp
  2. 14 3
      io.cpp
  3. 11 0
      io.h
  4. 11 10
      nssm.rc
  5. 18 3
      registry.cpp
  6. 2 1
      resource.h
  7. 9 0
      service.h

+ 15 - 0
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);

+ 14 - 3
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)) {

+ 11 - 0
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 *);

+ 11 - 10
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

+ 18 - 3
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) {

+ 2 - 1
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

+ 9 - 0
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;