summaryrefslogtreecommitdiff
path: root/src/couchdb/priv/spawnkillable/couchspawnkillable_win.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/couchdb/priv/spawnkillable/couchspawnkillable_win.c')
-rw-r--r--src/couchdb/priv/spawnkillable/couchspawnkillable_win.c145
1 files changed, 0 insertions, 145 deletions
diff --git a/src/couchdb/priv/spawnkillable/couchspawnkillable_win.c b/src/couchdb/priv/spawnkillable/couchspawnkillable_win.c
deleted file mode 100644
index 06782315..00000000
--- a/src/couchdb/priv/spawnkillable/couchspawnkillable_win.c
+++ /dev/null
@@ -1,145 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Do what 2 lines of shell script in couchspawnkillable does...
-// * Create a new suspended process with the same (duplicated) standard
-// handles as us.
-// * Write a line to stdout, consisting of the path to ourselves, plus
-// '--kill {pid}' where {pid} is the PID of the newly created process.
-// * Un-suspend the new process.
-// * Wait for the process to terminate.
-// * Terminate with the child's exit-code.
-
-// Later, couch will call us with --kill and the PID, so we dutifully
-// terminate the specified PID.
-
-#include <stdlib.h>
-#include "windows.h"
-
-char *get_child_cmdline(int argc, char **argv)
-{
- // make a new command-line, but skipping me.
- // XXX - todo - spaces etc in args???
- int i;
- char *p, *cmdline;
- int nchars = 0;
- int nthis = 1;
- for (i=1;i<argc;i++)
- nchars += strlen(argv[i])+1;
- cmdline = p = malloc(nchars+1);
- if (!cmdline)
- return NULL;
- for (i=1;i<argc;i++) {
- nthis = strlen(argv[i]);
- strncpy(p, argv[i], nthis);
- p[nthis] = ' ';
- p += nthis+1;
- }
- // Replace the last space we added above with a '\0'
- cmdline[nchars-1] = '\0';
- return cmdline;
-}
-
-// create the child process, returning 0, or the exit-code we will
-// terminate with.
-int create_child(int argc, char **argv, PROCESS_INFORMATION *pi)
-{
- char buf[1024];
- DWORD dwcreate;
- STARTUPINFO si;
- char *cmdline;
- if (argc < 2)
- return 1;
- cmdline = get_child_cmdline(argc, argv);
- if (!cmdline)
- return 2;
-
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(si);
- // depending on how *our* parent is started, we may or may not have
- // a valid stderr stream - so although we try and duplicate it, only
- // failing to duplicate stdin and stdout are considered fatal.
- if (!DuplicateHandle(GetCurrentProcess(),
- GetStdHandle(STD_INPUT_HANDLE),
- GetCurrentProcess(),
- &si.hStdInput,
- 0,
- TRUE, // inheritable
- DUPLICATE_SAME_ACCESS) ||
- !DuplicateHandle(GetCurrentProcess(),
- GetStdHandle(STD_OUTPUT_HANDLE),
- GetCurrentProcess(),
- &si.hStdOutput,
- 0,
- TRUE, // inheritable
- DUPLICATE_SAME_ACCESS)) {
- return 3;
- }
- DuplicateHandle(GetCurrentProcess(),
- GetStdHandle(STD_ERROR_HANDLE),
- GetCurrentProcess(),
- &si.hStdError,
- 0,
- TRUE, // inheritable
- DUPLICATE_SAME_ACCESS);
-
- si.dwFlags = STARTF_USESTDHANDLES;
- dwcreate = CREATE_SUSPENDED;
- if (!CreateProcess( NULL, cmdline,
- NULL,
- NULL,
- TRUE, // inherit handles
- dwcreate,
- NULL, // environ
- NULL, // cwd
- &si,
- pi))
- return 4;
- return 0;
-}
-
-// and here we go...
-int main(int argc, char **argv)
-{
- char out_buf[1024];
- int rc;
- DWORD cbwritten;
- DWORD exitcode;
- PROCESS_INFORMATION pi;
- if (argc==3 && strcmp(argv[1], "--kill")==0) {
- HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, atoi(argv[2]));
- if (!h)
- return 1;
- if (!TerminateProcess(h, 0))
- return 2;
- CloseHandle(h);
- return 0;
- }
- // spawn the new suspended process
- rc = create_child(argc, argv, &pi);
- if (rc)
- return rc;
- // Write the 'terminate' command, which includes this PID, back to couch.
- // *sob* - what about spaces etc?
- sprintf_s(out_buf, sizeof(out_buf), "%s --kill %d\n",
- argv[0], pi.dwProcessId);
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), out_buf, strlen(out_buf),
- &cbwritten, NULL);
- // Let the child process go...
- ResumeThread(pi.hThread);
- // Wait for the process to terminate so we can reflect the exit code
- // back to couch.
- WaitForSingleObject(pi.hProcess, INFINITE);
- if (!GetExitCodeProcess(pi.hProcess, &exitcode))
- return 6;
- return exitcode;
-}