diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-04-23 03:00:34 +1000 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-04-23 04:44:31 +1000 |
commit | be6cd4da128c27f6f58d600c3ab1d09422eff968 (patch) | |
tree | c5f4ad6bfe5677154ae9b484dbf061355480a779 | |
parent | 97b3a0ad578463c8fa64e8b38d096cd91dde841e (diff) | |
download | busybox-w32-be6cd4da128c27f6f58d600c3ab1d09422eff968.tar.gz busybox-w32-be6cd4da128c27f6f58d600c3ab1d09422eff968.tar.bz2 busybox-w32-be6cd4da128c27f6f58d600c3ab1d09422eff968.zip |
mingw_spawnve(): transfer O_APPEND attribute to child processes
-rw-r--r-- | include/mingw.h | 9 | ||||
-rw-r--r-- | libbb/mingw.c | 60 |
2 files changed, 69 insertions, 0 deletions
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); | |||
141 | int mingw_open (const char *filename, int oflags, ...); | 141 | int mingw_open (const char *filename, int oflags, ...); |
142 | #define open mingw_open | 142 | #define open mingw_open |
143 | 143 | ||
144 | int mingw_close (int fd); | ||
145 | #define close mingw_close | ||
146 | |||
147 | int mingw_dup (int fd); | ||
148 | #define dup mingw_dup | ||
149 | |||
150 | int mingw_dup2 (int fd, int fdto); | ||
151 | #define dup2 mingw_dup2 | ||
152 | |||
144 | char *mingw_getcwd(char *pointer, int len); | 153 | char *mingw_getcwd(char *pointer, int len); |
145 | #define getcwd mingw_getcwd | 154 | #define getcwd mingw_getcwd |
146 | 155 | ||
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) | |||
117 | return error; | 117 | return error; |
118 | } | 118 | } |
119 | 119 | ||
120 | /* | ||
121 | * emulate msvcrt file handle table | ||
122 | */ | ||
123 | #define MAX_FD 256 | ||
124 | #define WX_APPEND 0x20 | ||
125 | #define WX_OPEN 0x01 | ||
126 | static int fd_table[MAX_FD]; | ||
127 | |||
120 | #undef open | 128 | #undef open |
121 | int mingw_open (const char *filename, int oflags, ...) | 129 | int mingw_open (const char *filename, int oflags, ...) |
122 | { | 130 | { |
@@ -134,9 +142,41 @@ int mingw_open (const char *filename, int oflags, ...) | |||
134 | if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) | 142 | if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) |
135 | errno = EISDIR; | 143 | errno = EISDIR; |
136 | } | 144 | } |
145 | if (fd >= 0) { | ||
146 | fd_table[fd] = WX_OPEN; | ||
147 | if (oflags & O_APPEND) | ||
148 | fd_table[fd] |= WX_APPEND; | ||
149 | } | ||
137 | return fd; | 150 | return fd; |
138 | } | 151 | } |
139 | 152 | ||
153 | #undef close | ||
154 | int mingw_close (int fd) | ||
155 | { | ||
156 | int ret = close(fd); | ||
157 | if (!ret) | ||
158 | fd_table[fd] = 0; | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | #undef dup | ||
163 | int mingw_dup (int fd) | ||
164 | { | ||
165 | int ret = dup(fd); | ||
166 | if (ret != -1) | ||
167 | fd_table[ret] = fd_table[fd]; | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | #undef dup2 | ||
172 | int mingw_dup2 (int fd, int fdto) | ||
173 | { | ||
174 | int ret = dup2(fd, fdto); | ||
175 | if (ret != -1) | ||
176 | fd_table[fdto] = fd_table[fd]; | ||
177 | return ret; | ||
178 | } | ||
179 | |||
140 | static inline time_t filetime_to_time_t(const FILETIME *ft) | 180 | static inline time_t filetime_to_time_t(const FILETIME *ft) |
141 | { | 181 | { |
142 | long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime; | 182 | 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, | |||
649 | struct strbuf envblk, args; | 689 | struct strbuf envblk, args; |
650 | unsigned flags; | 690 | unsigned flags; |
651 | BOOL ret; | 691 | BOOL ret; |
692 | int i, fd_end; | ||
652 | 693 | ||
653 | /* Determine whether or not we are associated to a console */ | 694 | /* Determine whether or not we are associated to a console */ |
654 | HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE, | 695 | HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE, |
@@ -682,6 +723,23 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, | |||
682 | si.hStdOutput = (HANDLE) _get_osfhandle(1); | 723 | si.hStdOutput = (HANDLE) _get_osfhandle(1); |
683 | si.hStdError = (HANDLE) _get_osfhandle(2); | 724 | si.hStdError = (HANDLE) _get_osfhandle(2); |
684 | 725 | ||
726 | for (i = fd_end = 0;i < MAX_FD;i++) | ||
727 | if (fd_table[i] & WX_APPEND && fd_end <= i) | ||
728 | fd_end = i+1; | ||
729 | if (fd_end > 0) { | ||
730 | char *attr; | ||
731 | HANDLE *handle; | ||
732 | si.cbReserved2 = sizeof(unsigned) + (sizeof(char)+sizeof(HANDLE))*fd_end; | ||
733 | si.lpReserved2 = xmalloc(si.cbReserved2); | ||
734 | *((unsigned*)si.lpReserved2) = fd_end; | ||
735 | attr = (char*)((unsigned*)si.lpReserved2+1); | ||
736 | handle = (HANDLE*)(attr+fd_end); | ||
737 | for (i = 0;i < fd_end;i++,handle++,attr++) { | ||
738 | *attr = fd_table[i]; | ||
739 | *handle = fd_table[i] & WX_OPEN ? (HANDLE)_get_osfhandle(i) : INVALID_HANDLE_VALUE; | ||
740 | } | ||
741 | } | ||
742 | |||
685 | /* concatenate argv, quoting args as we go */ | 743 | /* concatenate argv, quoting args as we go */ |
686 | strbuf_init(&args, 0); | 744 | strbuf_init(&args, 0); |
687 | if (prepend_cmd) { | 745 | if (prepend_cmd) { |
@@ -723,6 +781,8 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, | |||
723 | ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags, | 781 | ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags, |
724 | env ? envblk.buf : NULL, NULL, &si, &pi); | 782 | env ? envblk.buf : NULL, NULL, &si, &pi); |
725 | 783 | ||
784 | if (si.lpReserved2) | ||
785 | free(si.lpReserved2); | ||
726 | if (env) | 786 | if (env) |
727 | strbuf_release(&envblk); | 787 | strbuf_release(&envblk); |
728 | strbuf_release(&args); | 788 | strbuf_release(&args); |