return (r);
}
+/*
+ * This fcntl is limited implemention.
+ */
+int
+la_fcntl(int fd, int cmd, int val)
+{
+ HANDLE handle;
+
+ handle = (HANDLE)_get_osfhandle(fd);
+ if (GetFileType(handle) == FILE_TYPE_PIPE) {
+ if (cmd == F_SETFL && val == 0) {
+ DWORD mode = PIPE_WAIT;
+ if (SetNamedPipeHandleState(
+ handle, &mode, NULL, NULL) != 0)
+ return (0);
+ }
+ }
+ errno = EINVAL;
+ return (-1);
+}
+
__int64
la_lseek(int fd, __int64 offset, int whence)
{
ssize_t
la_read(int fd, void *buf, size_t nbytes)
{
+ HANDLE handle;
DWORD bytes_read, lasterr;
int r;
errno = EBADF;
return (-1);
}
- r = ReadFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
+ handle = (HANDLE)_get_osfhandle(fd);
+ if (GetFileType(handle) == FILE_TYPE_PIPE) {
+ DWORD sta;
+ if (GetNamedPipeHandleState(
+ handle, &sta, NULL, NULL, NULL, NULL, 0) != 0 &&
+ (sta & PIPE_NOWAIT) == 0) {
+ DWORD avail = -1;
+ int cnt = 3;
+
+ while (PeekNamedPipe(
+ handle, NULL, 0, NULL, &avail, NULL) != 0 &&
+ avail == 0 && --cnt)
+ Sleep(100);
+ if (avail == 0)
+ return (0);
+ }
+ }
+ r = ReadFile(handle, buf, (uint32_t)nbytes,
&bytes_read, NULL);
if (r == 0) {
lasterr = GetLastError();
+ if (lasterr == ERROR_NO_DATA) {
+ errno = EAGAIN;
+ return (-1);
+ }
if (lasterr == ERROR_BROKEN_PIPE)
return (0);
if (lasterr == ERROR_ACCESS_DENIED)
return (r);
}
+/*
+ * This waitpid is limited implemention.
+ */
+pid_t
+la_waitpid(pid_t wpid, int *status, int option)
+{
+ HANDLE child;
+ DWORD cs, ret;
+
+ (void)option;/* UNUSED */
+ child = OpenProcess(PROCESS_ALL_ACCESS, FALSE, wpid);
+ if (child == NULL)
+ return (-1);
+ ret = WaitForSingleObject(child, INFINITE);
+ if (ret == WAIT_FAILED) {
+ CloseHandle(child);
+ return (-1);
+ }
+ if (GetExitCodeProcess(child, &cs) == 0) {
+ CloseHandle(child);
+ return (-1);
+ }
+ if (cs == STILL_ACTIVE)
+ *status = 0x100;
+ else
+ *status = (int)(cs & 0xff);
+ CloseHandle(child);
+ return (wpid);
+}
+
ssize_t
la_write(int fd, const void *buf, size_t nbytes)
{
#define chdir la_chdir
#define chmod la_chmod
#define close _close
+#define fcntl la_fcntl
#define fileno _fileno
#define fstat la_fstat
#define getcwd _getcwd
#define tzset _tzset
#define umask _umask
#define unlink la_unlink
+#define waitpid la_waitpid
#define write la_write
#define O_RDONLY _O_RDONLY
#define __timeval _timeval64i32
#endif
+typedef int pid_t;
+
#define SYSTEM_PATH_CHAR '\\'
/* Message digest define */
/* Replacement POSIX function */
extern int la_chdir(const char *path);
extern int la_chmod(const char *path, mode_t mode);
+extern int la_fcntl(int fd, int cmd, int val);
extern int la_fstat(int fd, struct stat *st);
extern __int64 la_lseek(int fd, __int64 offset, int whence);
extern int la_mkdir(const char *path, mode_t mode);
extern int la_rmdir(const char *path);
extern int la_stat(const char *path, struct stat *st);
extern int la_unlink(const char *path);
+extern pid_t la_waitpid(pid_t wpid, int *status, int option);
extern ssize_t la_write(int fd, const void *buf, size_t nbytes);
#define _stat64i32(path, st) la_stat(path, st)
--- /dev/null
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#ifdef _WIN32
+
+#include "filter_fork.h"
+
+pid_t
+__archive_create_child(const char *path, int *child_stdin, int *child_stdout)
+{
+ HANDLE childStdout[2], childStdin[2], childStdinWr, childStdoutRd;
+ SECURITY_ATTRIBUTES secAtts;
+ STARTUPINFO staInfo;
+ PROCESS_INFORMATION childInfo;
+ char cmd[MAX_PATH];
+ DWORD mode;
+
+ secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
+ secAtts.bInheritHandle = TRUE;
+ secAtts.lpSecurityDescriptor = NULL;
+ if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
+ goto fail;
+ if (DuplicateHandle(GetCurrentProcess(), childStdout[0],
+ GetCurrentProcess(), &childStdoutRd, 0, FALSE,
+ DUPLICATE_SAME_ACCESS) == 0) {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ goto fail;
+ }
+ CloseHandle(childStdout[0]);
+
+ if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0) {
+ CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[1]);
+ goto fail;
+ }
+
+ if (DuplicateHandle(GetCurrentProcess(), childStdin[1],
+ GetCurrentProcess(), &childStdinWr, 0, FALSE,
+ DUPLICATE_SAME_ACCESS) == 0) {
+ CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdin[1]);
+ goto fail;
+ }
+ CloseHandle(childStdin[1]);
+
+ memset(&staInfo, 0, sizeof(staInfo));
+ staInfo.cb = sizeof(staInfo);
+ staInfo.hStdOutput = childStdout[1];
+ staInfo.hStdInput = childStdin[0];
+ staInfo.wShowWindow = SW_HIDE;
+ staInfo.dwFlags = STARTF_USEFILLATTRIBUTE | STARTF_USECOUNTCHARS |
+ STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ strncpy(cmd, path, sizeof(cmd)-1);
+ cmd[sizeof(cmd)-1] = '\0';
+ if (CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL,
+ &staInfo, &childInfo) == 0) {
+ CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdinWr);
+ goto fail;
+ }
+ WaitForInputIdle(childInfo.hProcess, INFINITE);
+ CloseHandle(childInfo.hProcess);
+ CloseHandle(childInfo.hThread);
+
+ mode = PIPE_NOWAIT;
+ SetNamedPipeHandleState(childStdoutRd, &mode, NULL, NULL);
+ *child_stdout = _open_osfhandle((intptr_t)childStdoutRd, _O_RDONLY);
+ *child_stdin = _open_osfhandle((intptr_t)childStdinWr, _O_WRONLY);
+
+ return (childInfo.dwProcessId);
+
+fail:
+ return (-1);
+}
+
+void
+__archive_check_child(int in, int out)
+{
+ Sleep(100);
+}
+
+#endif /* _WIN32 */