return dup_handle(source_handle, dest_handle_ptr, source_description, dest_description, DUPLICATE_SAME_ACCESS);\r
}\r
\r
+/*\r
+ read_handle: read from application\r
+ pipe_handle: stdout of application\r
+ write_handle: to file\r
+*/\r
static HANDLE create_logging_thread(TCHAR *service_name, TCHAR *path, unsigned long sharing, unsigned long disposition, unsigned long flags, HANDLE *read_handle_ptr, HANDLE *pipe_handle_ptr, HANDLE *write_handle_ptr, unsigned long rotate_bytes_low, unsigned long rotate_bytes_high, unsigned long rotate_delay, unsigned long *tid_ptr, unsigned long *rotate_online, bool copy_and_truncate) {\r
*tid_ptr = 0;\r
\r
if (service->rotate_files) rotate_file(service->name, service->stdout_path, service->rotate_seconds, service->rotate_bytes_low, service->rotate_bytes_high, service->rotate_delay, service->stdout_copy_and_truncate);\r
HANDLE stdout_handle = write_to_file(service->stdout_path, service->stdout_sharing, 0, service->stdout_disposition, service->stdout_flags);\r
if (stdout_handle == INVALID_HANDLE_VALUE) return 4;\r
+ service->stdout_si = 0;\r
\r
- if (service->rotate_files && service->rotate_stdout_online) {\r
+ if (service->use_stdout_pipe) {\r
service->stdout_pipe = si->hStdOutput = 0;\r
- service->stdout_thread = create_logging_thread(service->name, service->stdout_path, service->stdout_sharing, service->stdout_disposition, service->stdout_flags, &service->stdout_pipe, &si->hStdOutput, &stdout_handle, service->rotate_bytes_low, service->rotate_bytes_high, service->rotate_delay, &service->stdout_tid, &service->rotate_stdout_online, service->stdout_copy_and_truncate);\r
+ service->stdout_thread = create_logging_thread(service->name, service->stdout_path, service->stdout_sharing, service->stdout_disposition, service->stdout_flags, &service->stdout_pipe, &service->stdout_si, &stdout_handle, service->rotate_bytes_low, service->rotate_bytes_high, service->rotate_delay, &service->stdout_tid, &service->rotate_stdout_online, service->stdout_copy_and_truncate);\r
if (! service->stdout_thread) {\r
CloseHandle(service->stdout_pipe);\r
- CloseHandle(si->hStdOutput);\r
+ CloseHandle(service->stdout_si);\r
}\r
}\r
else service->stdout_thread = 0;\r
\r
if (! service->stdout_thread) {\r
- if (dup_handle(stdout_handle, &si->hStdOutput, NSSM_REG_STDOUT, _T("stdout"), DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) return 4;\r
+ if (dup_handle(stdout_handle, &service->stdout_si, NSSM_REG_STDOUT, _T("stdout"), DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) return 4;\r
service->rotate_stdout_online = NSSM_ROTATE_OFFLINE;\r
}\r
+\r
+ if (dup_handle(service->stdout_si, &si->hStdOutput, _T("stdout_si"), _T("stdout"))) {\r
+ if (service->stdout_thread) {\r
+ CloseHandle(service->stdout_thread);\r
+ service->stdout_thread = 0;\r
+ }\r
+ }\r
}\r
\r
/* stderr */\r
service->rotate_stderr_online = NSSM_ROTATE_OFFLINE;\r
\r
/* Two handles to the same file will create a race. */\r
- if (dup_handle(si->hStdOutput, &si->hStdError, _T("stdout"), _T("stderr"))) return 6;\r
+ /* XXX: Here we assume that either both or neither handle must be a pipe. */\r
+ if (dup_handle(service->stdout_si, &service->stderr_si, _T("stdout"), _T("stderr"))) return 6;\r
}\r
else {\r
if (service->rotate_files) rotate_file(service->name, service->stderr_path, service->rotate_seconds, service->rotate_bytes_low, service->rotate_bytes_high, service->rotate_delay, service->stderr_copy_and_truncate);\r
HANDLE stderr_handle = write_to_file(service->stderr_path, service->stderr_sharing, 0, service->stderr_disposition, service->stderr_flags);\r
if (stderr_handle == INVALID_HANDLE_VALUE) return 7;\r
+ service->stderr_si = 0;\r
\r
- if (service->rotate_files && service->rotate_stderr_online) {\r
+ if (service->use_stderr_pipe) {\r
service->stderr_pipe = si->hStdError = 0;\r
- service->stderr_thread = create_logging_thread(service->name, service->stderr_path, service->stderr_sharing, service->stderr_disposition, service->stderr_flags, &service->stderr_pipe, &si->hStdError, &stderr_handle, service->rotate_bytes_low, service->rotate_bytes_high, service->rotate_delay, &service->stderr_tid, &service->rotate_stderr_online, service->stderr_copy_and_truncate);\r
+ service->stderr_thread = create_logging_thread(service->name, service->stderr_path, service->stderr_sharing, service->stderr_disposition, service->stderr_flags, &service->stderr_pipe, &service->stderr_si, &stderr_handle, service->rotate_bytes_low, service->rotate_bytes_high, service->rotate_delay, &service->stderr_tid, &service->rotate_stderr_online, service->stderr_copy_and_truncate);\r
if (! service->stderr_thread) {\r
CloseHandle(service->stderr_pipe);\r
- CloseHandle(si->hStdError);\r
+ CloseHandle(service->stderr_si);\r
}\r
}\r
else service->stderr_thread = 0;\r
\r
if (! service->stderr_thread) {\r
- if (dup_handle(stderr_handle, &si->hStdError, NSSM_REG_STDERR, _T("stderr"), DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) return 7;\r
+ if (dup_handle(stderr_handle, &service->stderr_si, NSSM_REG_STDERR, _T("stderr"), DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) return 7;\r
service->rotate_stderr_online = NSSM_ROTATE_OFFLINE;\r
}\r
}\r
+\r
+ if (dup_handle(service->stderr_si, &si->hStdError, _T("stderr_si"), _T("stderr"))) {\r
+ if (service->stderr_thread) {\r
+ CloseHandle(service->stderr_thread);\r
+ service->stderr_thread = 0;\r
+ }\r
+ }\r
}\r
\r
/*\r
}\r
if (! si->hStdError) {\r
if (dup_handle(GetStdHandle(STD_ERROR_HANDLE), &si->hStdError, _T("STD_ERROR_HANDLE"), _T("stderr"))) return 10;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/* Reuse output handles for a hook. */\r
+int use_output_handles(nssm_service_t *service, STARTUPINFO *si) {\r
+ si->dwFlags &= ~STARTF_USESTDHANDLES;\r
+\r
+ if (service->stdout_si) {\r
+ if (dup_handle(service->stdout_si, &si->hStdOutput, _T("stdout_pipe"), _T("hStdOutput"))) return 1;\r
+ si->dwFlags |= STARTF_USESTDHANDLES;\r
+ }\r
+\r
+ if (service->stderr_si) {\r
+ if (dup_handle(service->stderr_si, &si->hStdError, _T("stderr_pipe"), _T("hStdError"))) {\r
+ if (si->hStdOutput) {\r
+ si->dwFlags &= ~STARTF_USESTDHANDLES;\r
+ CloseHandle(si->hStdOutput);\r
+ }\r
+ return 2;\r
}\r
+ si->dwFlags |= STARTF_USESTDHANDLES;\r
}\r
\r
return 0;\r