1/*- 2 * Copyright (c) 2009 Michihiro NAKAJIMA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "archive_platform.h" 27 28#if defined(_WIN32) && !defined(__CYGWIN__) 29 30#include "filter_fork.h" 31 32pid_t 33__archive_create_child(const char *path, int *child_stdin, int *child_stdout) 34{ 35 HANDLE childStdout[2], childStdin[2], childStdinWr, childStdoutRd; 36 SECURITY_ATTRIBUTES secAtts; 37 STARTUPINFO staInfo; 38 PROCESS_INFORMATION childInfo; 39 char cmd[MAX_PATH]; 40 DWORD mode; 41 42 secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); 43 secAtts.bInheritHandle = TRUE; 44 secAtts.lpSecurityDescriptor = NULL; 45 if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0) 46 goto fail; 47 if (DuplicateHandle(GetCurrentProcess(), childStdout[0], 48 GetCurrentProcess(), &childStdoutRd, 0, FALSE, 49 DUPLICATE_SAME_ACCESS) == 0) { 50 CloseHandle(childStdout[0]); 51 CloseHandle(childStdout[1]); 52 goto fail; 53 } 54 CloseHandle(childStdout[0]); 55 56 if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0) { 57 CloseHandle(childStdoutRd); 58 CloseHandle(childStdout[1]); 59 goto fail; 60 } 61 62 if (DuplicateHandle(GetCurrentProcess(), childStdin[1], 63 GetCurrentProcess(), &childStdinWr, 0, FALSE, 64 DUPLICATE_SAME_ACCESS) == 0) { 65 CloseHandle(childStdoutRd); 66 CloseHandle(childStdout[1]); 67 CloseHandle(childStdin[0]); 68 CloseHandle(childStdin[1]); 69 goto fail; 70 } 71 CloseHandle(childStdin[1]); 72 73 memset(&staInfo, 0, sizeof(staInfo)); 74 staInfo.cb = sizeof(staInfo); 75 staInfo.hStdOutput = childStdout[1]; 76 staInfo.hStdInput = childStdin[0]; 77 staInfo.wShowWindow = SW_HIDE; 78 staInfo.dwFlags = STARTF_USEFILLATTRIBUTE | STARTF_USECOUNTCHARS | 79 STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 80 strncpy(cmd, path, sizeof(cmd)-1); 81 cmd[sizeof(cmd)-1] = '\0'; 82 if (CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, 83 &staInfo, &childInfo) == 0) { 84 CloseHandle(childStdoutRd); 85 CloseHandle(childStdout[1]); 86 CloseHandle(childStdin[0]); 87 CloseHandle(childStdinWr); 88 goto fail; 89 } 90 WaitForInputIdle(childInfo.hProcess, INFINITE); 91 CloseHandle(childInfo.hProcess); 92 CloseHandle(childInfo.hThread); 93 94 mode = PIPE_NOWAIT; 95 SetNamedPipeHandleState(childStdoutRd, &mode, NULL, NULL); 96 *child_stdout = _open_osfhandle((intptr_t)childStdoutRd, _O_RDONLY); 97 *child_stdin = _open_osfhandle((intptr_t)childStdinWr, _O_WRONLY); 98 99 return (childInfo.dwProcessId); 100 101fail: 102 return (-1); 103} 104 105void 106__archive_check_child(int in, int out) 107{ 108 (void)in; /* UNSED */ 109 (void)out; /* UNSED */ 110 Sleep(100); 111} 112 113#endif /* _WIN32 && !__CYGWIN__ */ 114