From be6cd4da128c27f6f58d600c3ab1d09422eff968 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Thu, 23 Apr 2009 03:00:34 +1000 Subject: mingw_spawnve(): transfer O_APPEND attribute to child processes --- include/mingw.h | 9 +++++++++ libbb/mingw.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/include/mingw.h b/include/mingw.h index 762eb143a..eae6a7d3a 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -141,6 +141,15 @@ int link(const char *oldpath, const char *newpath); int mingw_open (const char *filename, int oflags, ...); #define open mingw_open +int mingw_close (int fd); +#define close mingw_close + +int mingw_dup (int fd); +#define dup mingw_dup + +int mingw_dup2 (int fd, int fdto); +#define dup2 mingw_dup2 + char *mingw_getcwd(char *pointer, int len); #define getcwd mingw_getcwd diff --git a/libbb/mingw.c b/libbb/mingw.c index 88d4f90e4..eb239bbd6 100644 --- a/libbb/mingw.c +++ b/libbb/mingw.c @@ -117,6 +117,14 @@ static int err_win_to_posix(DWORD winerr) return error; } +/* + * emulate msvcrt file handle table + */ +#define MAX_FD 256 +#define WX_APPEND 0x20 +#define WX_OPEN 0x01 +static int fd_table[MAX_FD]; + #undef open int mingw_open (const char *filename, int oflags, ...) { @@ -134,9 +142,41 @@ int mingw_open (const char *filename, int oflags, ...) if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) errno = EISDIR; } + if (fd >= 0) { + fd_table[fd] = WX_OPEN; + if (oflags & O_APPEND) + fd_table[fd] |= WX_APPEND; + } return fd; } +#undef close +int mingw_close (int fd) +{ + int ret = close(fd); + if (!ret) + fd_table[fd] = 0; + return ret; +} + +#undef dup +int mingw_dup (int fd) +{ + int ret = dup(fd); + if (ret != -1) + fd_table[ret] = fd_table[fd]; + return ret; +} + +#undef dup2 +int mingw_dup2 (int fd, int fdto) +{ + int ret = dup2(fd, fdto); + if (ret != -1) + fd_table[fdto] = fd_table[fd]; + return ret; +} + static inline time_t filetime_to_time_t(const FILETIME *ft) { long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime; @@ -649,6 +689,7 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, struct strbuf envblk, args; unsigned flags; BOOL ret; + int i, fd_end; /* Determine whether or not we are associated to a console */ HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE, @@ -682,6 +723,23 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, si.hStdOutput = (HANDLE) _get_osfhandle(1); si.hStdError = (HANDLE) _get_osfhandle(2); + for (i = fd_end = 0;i < MAX_FD;i++) + if (fd_table[i] & WX_APPEND && fd_end <= i) + fd_end = i+1; + if (fd_end > 0) { + char *attr; + HANDLE *handle; + si.cbReserved2 = sizeof(unsigned) + (sizeof(char)+sizeof(HANDLE))*fd_end; + si.lpReserved2 = xmalloc(si.cbReserved2); + *((unsigned*)si.lpReserved2) = fd_end; + attr = (char*)((unsigned*)si.lpReserved2+1); + handle = (HANDLE*)(attr+fd_end); + for (i = 0;i < fd_end;i++,handle++,attr++) { + *attr = fd_table[i]; + *handle = fd_table[i] & WX_OPEN ? (HANDLE)_get_osfhandle(i) : INVALID_HANDLE_VALUE; + } + } + /* concatenate argv, quoting args as we go */ strbuf_init(&args, 0); if (prepend_cmd) { @@ -723,6 +781,8 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags, env ? envblk.buf : NULL, NULL, &si, &pi); + if (si.lpReserved2) + free(si.lpReserved2); if (env) strbuf_release(&envblk); strbuf_release(&args); -- cgit v1.2.3-55-g6feb