Allow configuring output file truncation.
authorIain Patterson <me@iain.cx>
Fri, 22 Nov 2013 15:22:21 +0000 (15:22 +0000)
committerIain Patterson <me@iain.cx>
Fri, 22 Nov 2013 15:22:21 +0000 (15:22 +0000)
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
io.cpp
io.h
nssm.rc
registry.cpp
resource.h
service.h

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