diff options
author | Ron Yorston <rmy@pobox.com> | 2018-02-22 11:40:53 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-02-22 11:40:53 +0000 |
commit | 4e6d0dc9476e5cf43ff0bc5e66a54d812ddb4225 (patch) | |
tree | 03dfcab70ff58cae77db6a7ad75dfac3203765c7 | |
parent | 1efab55196bea6d93aa26ca2fb1d3d358f16452f (diff) | |
download | busybox-w32-4e6d0dc9476e5cf43ff0bc5e66a54d812ddb4225.tar.gz busybox-w32-4e6d0dc9476e5cf43ff0bc5e66a54d812ddb4225.tar.bz2 busybox-w32-4e6d0dc9476e5cf43ff0bc5e66a54d812ddb4225.zip |
win32: handle /dev/zero and /dev/urandom in open and read functions
Currently /dev/zero is handled as a special case in dd. Add hacks
to the open and read functions in mingw.c to handle the zero and
urandom devices.
- Opening /dev/zero or /dev/urandom actually opens the special
Windows file 'nul' which behaves like /dev/null. This allows
manipulation of the file descriptor with things like seek and
close
- When /dev/zero or /dev/urandom is opened the resulting file
descriptor is stored and used to override the behaviour of read.
- No attempt is made to track duplicated file descriptors, so using
these devices for redirections in the shell isn't going to work
and won't be permitted. (Could be, but won't.)
- Limited control of the special file descriptors is provided by
allowing the internal variables to be changed.
- The numbers from /dev/urandom aren't very random.
-rw-r--r-- | include/mingw.h | 5 | ||||
-rw-r--r-- | win32/mingw.c | 61 | ||||
-rw-r--r-- | win32/winansi.c | 2 |
3 files changed, 65 insertions, 3 deletions
diff --git a/include/mingw.h b/include/mingw.h index a59ce6fc4..46be4dc23 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -395,6 +395,10 @@ int kill(pid_t pid, int sig); | |||
395 | int link(const char *oldpath, const char *newpath); | 395 | int link(const char *oldpath, const char *newpath); |
396 | NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM); | 396 | NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM); |
397 | int mingw_open (const char *filename, int oflags, ...); | 397 | int mingw_open (const char *filename, int oflags, ...); |
398 | void mingw_read_zero(int fd); | ||
399 | void mingw_read_random(int fd); | ||
400 | ssize_t mingw_read(int fd, void *buf, size_t count); | ||
401 | int mingw_close(int fd); | ||
398 | int pipe(int filedes[2]); | 402 | int pipe(int filedes[2]); |
399 | NOIMPL(readlink,const char *path UNUSED_PARAM, char *buf UNUSED_PARAM, size_t bufsiz UNUSED_PARAM); | 403 | NOIMPL(readlink,const char *path UNUSED_PARAM, char *buf UNUSED_PARAM, size_t bufsiz UNUSED_PARAM); |
400 | NOIMPL(setgid,gid_t gid UNUSED_PARAM); | 404 | NOIMPL(setgid,gid_t gid UNUSED_PARAM); |
@@ -418,6 +422,7 @@ int mingw_isatty(int fd); | |||
418 | #define getcwd mingw_getcwd | 422 | #define getcwd mingw_getcwd |
419 | #define lchown chown | 423 | #define lchown chown |
420 | #define open mingw_open | 424 | #define open mingw_open |
425 | #define close mingw_close | ||
421 | #define unlink mingw_unlink | 426 | #define unlink mingw_unlink |
422 | #define rmdir mingw_rmdir | 427 | #define rmdir mingw_rmdir |
423 | #undef lseek | 428 | #undef lseek |
diff --git a/win32/mingw.c b/win32/mingw.c index a55fb4f40..595042d85 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -138,12 +138,28 @@ int err_win_to_posix(DWORD winerr) | |||
138 | return error; | 138 | return error; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int zero_fd = -1; | ||
142 | static int rand_fd = -1; | ||
143 | |||
144 | void mingw_read_zero(int fd) | ||
145 | { | ||
146 | zero_fd = fd; | ||
147 | } | ||
148 | |||
149 | void mingw_read_random(int fd) | ||
150 | { | ||
151 | rand_fd = fd; | ||
152 | } | ||
153 | |||
141 | #undef open | 154 | #undef open |
142 | int mingw_open (const char *filename, int oflags, ...) | 155 | int mingw_open (const char *filename, int oflags, ...) |
143 | { | 156 | { |
144 | va_list args; | 157 | va_list args; |
145 | unsigned mode; | 158 | unsigned mode; |
146 | int fd; | 159 | int fd; |
160 | int devnull = 0; | ||
161 | int devzero = 0; | ||
162 | int devrand = 0; | ||
147 | 163 | ||
148 | va_start(args, oflags); | 164 | va_start(args, oflags); |
149 | mode = va_arg(args, int); | 165 | mode = va_arg(args, int); |
@@ -152,14 +168,29 @@ int mingw_open (const char *filename, int oflags, ...) | |||
152 | if (oflags & O_NONBLOCK) { | 168 | if (oflags & O_NONBLOCK) { |
153 | oflags &= ~O_NONBLOCK; | 169 | oflags &= ~O_NONBLOCK; |
154 | } | 170 | } |
155 | if (filename && !strcmp(filename, "/dev/null")) | 171 | if (filename && !strncmp(filename, "/dev/", 5)) { |
156 | filename = "nul"; | 172 | if (!strcmp(filename+5, "null")) |
173 | devnull = 1; | ||
174 | else if (!strcmp(filename+5, "zero")) | ||
175 | devzero = 1; | ||
176 | else if (!strcmp(filename+5, "urandom")) | ||
177 | devrand = 1; | ||
178 | |||
179 | if (devnull || devzero || devrand ) | ||
180 | filename = "nul"; | ||
181 | } | ||
157 | fd = open(filename, oflags, mode); | 182 | fd = open(filename, oflags, mode); |
158 | if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) { | 183 | if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) { |
159 | DWORD attrs = GetFileAttributes(filename); | 184 | DWORD attrs = GetFileAttributes(filename); |
160 | if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) | 185 | if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) |
161 | errno = EISDIR; | 186 | errno = EISDIR; |
162 | } | 187 | } |
188 | if (fd >= 0 ) { | ||
189 | if (devzero) | ||
190 | zero_fd = fd; | ||
191 | else if (devrand) | ||
192 | rand_fd = fd; | ||
193 | } | ||
163 | return fd; | 194 | return fd; |
164 | } | 195 | } |
165 | 196 | ||
@@ -171,6 +202,32 @@ FILE *mingw_fopen (const char *filename, const char *otype) | |||
171 | return fopen(filename, otype); | 202 | return fopen(filename, otype); |
172 | } | 203 | } |
173 | 204 | ||
205 | #undef read | ||
206 | ssize_t mingw_read(int fd, void *buf, size_t count) | ||
207 | { | ||
208 | if (fd == zero_fd) { | ||
209 | memset(buf, 0, count); | ||
210 | return count; | ||
211 | } | ||
212 | else if (fd == rand_fd) { | ||
213 | memset(buf, 0x5A, count); | ||
214 | return count; | ||
215 | } | ||
216 | return read(fd, buf, count); | ||
217 | } | ||
218 | |||
219 | #undef close | ||
220 | int mingw_close(int fd) | ||
221 | { | ||
222 | if (fd == zero_fd) { | ||
223 | zero_fd = -1; | ||
224 | } | ||
225 | if (fd == rand_fd) { | ||
226 | rand_fd = -1; | ||
227 | } | ||
228 | return close(fd); | ||
229 | } | ||
230 | |||
174 | #undef dup2 | 231 | #undef dup2 |
175 | int mingw_dup2 (int fd, int fdto) | 232 | int mingw_dup2 (int fd, int fdto) |
176 | { | 233 | { |
diff --git a/win32/winansi.c b/win32/winansi.c index 8fffc5a00..b357fc642 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -695,7 +695,7 @@ int winansi_read(int fd, void *buf, size_t count) | |||
695 | { | 695 | { |
696 | int rv; | 696 | int rv; |
697 | 697 | ||
698 | rv = read(fd, buf, count); | 698 | rv = mingw_read(fd, buf, count); |
699 | if (!isatty(fd)) | 699 | if (!isatty(fd)) |
700 | return rv; | 700 | return rv; |
701 | 701 | ||