aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-02-22 11:40:53 +0000
committerRon Yorston <rmy@pobox.com>2018-02-22 11:40:53 +0000
commit4e6d0dc9476e5cf43ff0bc5e66a54d812ddb4225 (patch)
tree03dfcab70ff58cae77db6a7ad75dfac3203765c7
parent1efab55196bea6d93aa26ca2fb1d3d358f16452f (diff)
downloadbusybox-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.h5
-rw-r--r--win32/mingw.c61
-rw-r--r--win32/winansi.c2
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);
395int link(const char *oldpath, const char *newpath); 395int link(const char *oldpath, const char *newpath);
396NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM); 396NOIMPL(mknod,const char *name UNUSED_PARAM, mode_t mode UNUSED_PARAM, dev_t device UNUSED_PARAM);
397int mingw_open (const char *filename, int oflags, ...); 397int mingw_open (const char *filename, int oflags, ...);
398void mingw_read_zero(int fd);
399void mingw_read_random(int fd);
400ssize_t mingw_read(int fd, void *buf, size_t count);
401int mingw_close(int fd);
398int pipe(int filedes[2]); 402int pipe(int filedes[2]);
399NOIMPL(readlink,const char *path UNUSED_PARAM, char *buf UNUSED_PARAM, size_t bufsiz UNUSED_PARAM); 403NOIMPL(readlink,const char *path UNUSED_PARAM, char *buf UNUSED_PARAM, size_t bufsiz UNUSED_PARAM);
400NOIMPL(setgid,gid_t gid UNUSED_PARAM); 404NOIMPL(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
141static int zero_fd = -1;
142static int rand_fd = -1;
143
144void mingw_read_zero(int fd)
145{
146 zero_fd = fd;
147}
148
149void mingw_read_random(int fd)
150{
151 rand_fd = fd;
152}
153
141#undef open 154#undef open
142int mingw_open (const char *filename, int oflags, ...) 155int 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
206ssize_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
220int 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
175int mingw_dup2 (int fd, int fdto) 232int 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