summaryrefslogtreecommitdiff
path: root/deps/uv/src/win/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uv/src/win/fs.c')
-rw-r--r--deps/uv/src/win/fs.c108
1 files changed, 98 insertions, 10 deletions
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 3ab486080c..8502b07202 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -1195,9 +1195,10 @@ void fs__mkdir(uv_fs_t* req) {
}
}
+typedef int (*uv__fs_mktemp_func)(uv_fs_t* req);
/* OpenBSD original: lib/libc/stdio/mktemp.c */
-void fs__mkdtemp(uv_fs_t* req) {
+void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
static const WCHAR *tempchars =
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static const size_t num_chars = 62;
@@ -1227,13 +1228,11 @@ void fs__mkdtemp(uv_fs_t* req) {
v /= num_chars;
}
- if (_wmkdir(req->file.pathw) == 0) {
- len = strlen(req->path);
- wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
- SET_REQ_RESULT(req, 0);
- break;
- } else if (errno != EEXIST) {
- SET_REQ_RESULT(req, -1);
+ if (func(req)) {
+ if (req->result >= 0) {
+ len = strlen(req->path);
+ wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
+ }
break;
}
} while (--tries);
@@ -1244,6 +1243,77 @@ void fs__mkdtemp(uv_fs_t* req) {
}
+static int fs__mkdtemp_func(uv_fs_t* req) {
+ if (_wmkdir(req->file.pathw) == 0) {
+ SET_REQ_RESULT(req, 0);
+ return 1;
+ } else if (errno != EEXIST) {
+ SET_REQ_RESULT(req, -1);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void fs__mkdtemp(uv_fs_t* req) {
+ fs__mktemp(req, fs__mkdtemp_func);
+}
+
+
+static int fs__mkstemp_func(uv_fs_t* req) {
+ HANDLE file;
+ int fd;
+
+ file = CreateFileW(req->file.pathw,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (file == INVALID_HANDLE_VALUE) {
+ DWORD error;
+ error = GetLastError();
+
+ /* If the file exists, the main fs__mktemp() function
+ will retry. If it's another error, we want to stop. */
+ if (error != ERROR_FILE_EXISTS) {
+ SET_REQ_WIN32_ERROR(req, error);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ fd = _open_osfhandle((intptr_t) file, 0);
+ 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);
+ CloseHandle(file);
+ return 1;
+ }
+
+ SET_REQ_RESULT(req, fd);
+
+ return 1;
+}
+
+
+void fs__mkstemp(uv_fs_t* req) {
+ fs__mktemp(req, fs__mkstemp_func);
+}
+
+
void fs__scandir(uv_fs_t* req) {
static const size_t dirents_initial_size = 32;
@@ -2609,6 +2679,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(RMDIR, rmdir)
XX(MKDIR, mkdir)
XX(MKDTEMP, mkdtemp)
+ XX(MKSTEMP, mkstemp)
XX(RENAME, rename)
XX(SCANDIR, scandir)
XX(READDIR, readdir)
@@ -2785,8 +2856,10 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
}
-int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
- uv_fs_cb cb) {
+int uv_fs_mkdtemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
int err;
INIT(UV_FS_MKDTEMP);
@@ -2798,6 +2871,21 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
}
+int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
+ int err;
+
+ INIT(UV_FS_MKSTEMP);
+ err = fs__capture_path(req, tpl, NULL, TRUE);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ POST;
+}
+
+
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;