Skip to content

Commit

Permalink
windows/fs: handle _open_osfhandle() failure correctly
Browse files Browse the repository at this point in the history
Until now we assumed that _open_osfhandle() would set _doserrno on
failure. This assumption was very wrong in one obvious case, namely when
the CRT file descriptor table would fill up. In that case errno is set
to EMFILE, but GetLastError() returns zero - which makes sense because
it's not a win32 error but rather a CRT problem.
  • Loading branch information
piscisaureus committed Sep 5, 2013
1 parent 489fb4c commit 20e774c
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/win/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ void fs__open(uv_fs_t* req) {
DWORD disposition;
DWORD attributes = 0;
HANDLE file;
int result, current_umask;
int fd, current_umask;
int flags = req->file_flags;

/* Obtain the active umask. umask() never fails and returns the previous */
Expand Down Expand Up @@ -502,8 +502,23 @@ void fs__open(uv_fs_t* req) {
}
return;
}
result = _open_osfhandle((intptr_t) file, flags);
SET_REQ_RESULT(req, result);

fd = _open_osfhandle((intptr_t) file, flags);
if (fd < 0) {
/* The only known failure mode for _open_osfhandle() is EMFILE, in which
* case GetLastError() will return zero. However we'll try to handle other
* errors as well, should they ever occur.
*/
if (errno == EMFILE)
SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
else if (GetLastError() != ERROR_SUCCESS)
SET_REQ_WIN32_ERROR(req, GetLastError());
else
SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
return;
}

SET_REQ_RESULT(req, fd);
return;

einval:
Expand Down

0 comments on commit 20e774c

Please sign in to comment.