summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/libuv/src/win/fs-event.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/libuv/src/win/fs-event.c')
-rw-r--r--3rdparty/libuv/src/win/fs-event.c550
1 files changed, 0 insertions, 550 deletions
diff --git a/3rdparty/libuv/src/win/fs-event.c b/3rdparty/libuv/src/win/fs-event.c
deleted file mode 100644
index 77c935a2d8c..00000000000
--- a/3rdparty/libuv/src/win/fs-event.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "uv.h"
-#include "internal.h"
-#include "handle-inl.h"
-#include "req-inl.h"
-
-
-const unsigned int uv_directory_watcher_buffer_size = 4096;
-
-
-static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
- uv_fs_event_t* handle) {
- assert(handle->dir_handle != INVALID_HANDLE_VALUE);
- assert(!handle->req_pending);
-
- memset(&(handle->req.u.io.overlapped), 0,
- sizeof(handle->req.u.io.overlapped));
- if (!ReadDirectoryChangesW(handle->dir_handle,
- handle->buffer,
- uv_directory_watcher_buffer_size,
- (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_ATTRIBUTES |
- FILE_NOTIFY_CHANGE_SIZE |
- FILE_NOTIFY_CHANGE_LAST_WRITE |
- FILE_NOTIFY_CHANGE_LAST_ACCESS |
- FILE_NOTIFY_CHANGE_CREATION |
- FILE_NOTIFY_CHANGE_SECURITY,
- NULL,
- &handle->req.u.io.overlapped,
- NULL)) {
- /* Make this req pending reporting an error. */
- SET_REQ_ERROR(&handle->req, GetLastError());
- uv_insert_pending_req(loop, (uv_req_t*)&handle->req);
- }
-
- handle->req_pending = 1;
-}
-
-static void uv_relative_path(const WCHAR* filename,
- const WCHAR* dir,
- WCHAR** relpath) {
- size_t dirlen = wcslen(dir);
- if (dirlen > 0 && dir[dirlen - 1] == '\\')
- dirlen--;
- size_t filenamelen = wcslen(filename);
- size_t relpathlen = filenamelen - dirlen - 1;
- *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR));
- if (!*relpath)
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- wcsncpy(*relpath, filename + dirlen + 1, relpathlen);
- (*relpath)[relpathlen] = L'\0';
-}
-
-static int uv_split_path(const WCHAR* filename, WCHAR** dir,
- WCHAR** file) {
- int len = wcslen(filename);
- int i = len;
- while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
-
- if (i == 0) {
- if (dir) {
- *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
- if (!*dir) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
- uv__free(*dir);
- *dir = NULL;
- return -1;
- }
- }
-
- *file = wcsdup(filename);
- } else {
- if (dir) {
- *dir = (WCHAR*)uv__malloc((i + 2) * sizeof(WCHAR));
- if (!*dir) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
- wcsncpy(*dir, filename, i + 1);
- (*dir)[i + 1] = L'\0';
- }
-
- *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR));
- if (!*file) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
- wcsncpy(*file, filename + i + 1, len - i - 1);
- (*file)[len - i - 1] = L'\0';
- }
-
- return 0;
-}
-
-
-int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
- uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT);
- handle->dir_handle = INVALID_HANDLE_VALUE;
- handle->buffer = NULL;
- handle->req_pending = 0;
- handle->filew = NULL;
- handle->short_filew = NULL;
- handle->dirw = NULL;
-
- uv_req_init(loop, (uv_req_t*)&handle->req);
- handle->req.type = UV_FS_EVENT_REQ;
- handle->req.data = handle;
-
- return 0;
-}
-
-
-int uv_fs_event_start(uv_fs_event_t* handle,
- uv_fs_event_cb cb,
- const char* path,
- unsigned int flags) {
- int name_size, is_path_dir;
- DWORD attr, last_error;
- WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
- WCHAR short_path[MAX_PATH];
-
- if (uv__is_active(handle))
- return UV_EINVAL;
-
- handle->cb = cb;
- handle->path = uv__strdup(path);
- if (!handle->path) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- uv__handle_start(handle);
-
- /* Convert name to UTF16. */
-
- name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) *
- sizeof(WCHAR);
- pathw = (WCHAR*)uv__malloc(name_size);
- if (!pathw) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- if (!MultiByteToWideChar(CP_UTF8,
- 0,
- path,
- -1,
- pathw,
- name_size / sizeof(WCHAR))) {
- return uv_translate_sys_error(GetLastError());
- }
-
- /* Determine whether path is a file or a directory. */
- attr = GetFileAttributesW(pathw);
- if (attr == INVALID_FILE_ATTRIBUTES) {
- last_error = GetLastError();
- goto error;
- }
-
- is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
-
- if (is_path_dir) {
- /* path is a directory, so that's the directory that we will watch. */
- handle->dirw = pathw;
- dir_to_watch = pathw;
- } else {
- /*
- * path is a file. So we split path into dir & file parts, and
- * watch the dir directory.
- */
-
- /* Convert to short path. */
- if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
- last_error = GetLastError();
- goto error;
- }
-
- if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
- last_error = GetLastError();
- goto error;
- }
-
- if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
- last_error = GetLastError();
- goto error;
- }
-
- dir_to_watch = dir;
- uv__free(pathw);
- pathw = NULL;
- }
-
- handle->dir_handle = CreateFileW(dir_to_watch,
- FILE_LIST_DIRECTORY,
- FILE_SHARE_READ | FILE_SHARE_DELETE |
- FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS |
- FILE_FLAG_OVERLAPPED,
- NULL);
-
- if (dir) {
- uv__free(dir);
- dir = NULL;
- }
-
- if (handle->dir_handle == INVALID_HANDLE_VALUE) {
- last_error = GetLastError();
- goto error;
- }
-
- if (CreateIoCompletionPort(handle->dir_handle,
- handle->loop->iocp,
- (ULONG_PTR)handle,
- 0) == NULL) {
- last_error = GetLastError();
- goto error;
- }
-
- if (!handle->buffer) {
- handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size);
- }
- if (!handle->buffer) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- memset(&(handle->req.u.io.overlapped), 0,
- sizeof(handle->req.u.io.overlapped));
-
- if (!ReadDirectoryChangesW(handle->dir_handle,
- handle->buffer,
- uv_directory_watcher_buffer_size,
- (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_ATTRIBUTES |
- FILE_NOTIFY_CHANGE_SIZE |
- FILE_NOTIFY_CHANGE_LAST_WRITE |
- FILE_NOTIFY_CHANGE_LAST_ACCESS |
- FILE_NOTIFY_CHANGE_CREATION |
- FILE_NOTIFY_CHANGE_SECURITY,
- NULL,
- &handle->req.u.io.overlapped,
- NULL)) {
- last_error = GetLastError();
- goto error;
- }
-
- handle->req_pending = 1;
- return 0;
-
-error:
- if (handle->path) {
- uv__free(handle->path);
- handle->path = NULL;
- }
-
- if (handle->filew) {
- uv__free(handle->filew);
- handle->filew = NULL;
- }
-
- if (handle->short_filew) {
- uv__free(handle->short_filew);
- handle->short_filew = NULL;
- }
-
- uv__free(pathw);
-
- if (handle->dir_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(handle->dir_handle);
- handle->dir_handle = INVALID_HANDLE_VALUE;
- }
-
- if (handle->buffer) {
- uv__free(handle->buffer);
- handle->buffer = NULL;
- }
-
- return uv_translate_sys_error(last_error);
-}
-
-
-int uv_fs_event_stop(uv_fs_event_t* handle) {
- if (!uv__is_active(handle))
- return 0;
-
- if (handle->dir_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(handle->dir_handle);
- handle->dir_handle = INVALID_HANDLE_VALUE;
- }
-
- uv__handle_stop(handle);
-
- if (handle->filew) {
- uv__free(handle->filew);
- handle->filew = NULL;
- }
-
- if (handle->short_filew) {
- uv__free(handle->short_filew);
- handle->short_filew = NULL;
- }
-
- if (handle->path) {
- uv__free(handle->path);
- handle->path = NULL;
- }
-
- if (handle->dirw) {
- uv__free(handle->dirw);
- handle->dirw = NULL;
- }
-
- return 0;
-}
-
-
-void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
- uv_fs_event_t* handle) {
- FILE_NOTIFY_INFORMATION* file_info;
- int err, sizew, size;
- char* filename = NULL;
- WCHAR* filenamew, *long_filenamew = NULL;
- DWORD offset = 0;
-
- assert(req->type == UV_FS_EVENT_REQ);
- assert(handle->req_pending);
- handle->req_pending = 0;
-
- /* Don't report any callbacks if:
- * - We're closing, just push the handle onto the endgame queue
- * - We are not active, just ignore the callback
- */
- if (!uv__is_active(handle)) {
- if (handle->flags & UV__HANDLE_CLOSING) {
- uv_want_endgame(loop, (uv_handle_t*) handle);
- }
- return;
- }
-
- file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
-
- if (REQ_SUCCESS(req)) {
- if (req->u.io.overlapped.InternalHigh > 0) {
- do {
- file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
- assert(!filename);
- assert(!long_filenamew);
-
- /*
- * Fire the event only if we were asked to watch a directory,
- * or if the filename filter matches.
- */
- if (handle->dirw ||
- _wcsnicmp(handle->filew, file_info->FileName,
- file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
- _wcsnicmp(handle->short_filew, file_info->FileName,
- file_info->FileNameLength / sizeof(WCHAR)) == 0) {
-
- if (handle->dirw) {
- /*
- * We attempt to resolve the long form of the file name explicitly.
- * We only do this for file names that might still exist on disk.
- * If this fails, we use the name given by ReadDirectoryChangesW.
- * This may be the long form or the 8.3 short name in some cases.
- */
- if (file_info->Action != FILE_ACTION_REMOVED &&
- file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
- /* Construct a full path to the file. */
- size = wcslen(handle->dirw) +
- file_info->FileNameLength / sizeof(WCHAR) + 2;
-
- filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
- if (!filenamew) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
- file_info->FileNameLength / sizeof(WCHAR),
- file_info->FileName);
-
- filenamew[size - 1] = L'\0';
-
- /* Convert to long name. */
- size = GetLongPathNameW(filenamew, NULL, 0);
-
- if (size) {
- long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
- if (!long_filenamew) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- size = GetLongPathNameW(filenamew, long_filenamew, size);
- if (size) {
- long_filenamew[size] = '\0';
- } else {
- uv__free(long_filenamew);
- long_filenamew = NULL;
- }
- }
-
- uv__free(filenamew);
-
- if (long_filenamew) {
- /* Get the file name out of the long path. */
- uv_relative_path(long_filenamew,
- handle->dirw,
- &filenamew);
- uv__free(long_filenamew);
- long_filenamew = filenamew;
- sizew = -1;
- }
- }
- /*
- * Removed or renamed events cannot be resolved to the long form.
- * We therefore use the name given by ReadDirectoryChangesW.
- * This may be the long form or the 8.3 short name in some cases.
- */
- if (!long_filenamew) {
- filenamew = file_info->FileName;
- sizew = file_info->FileNameLength / sizeof(WCHAR);
- }
- } else {
- /* We already have the long name of the file, so just use it. */
- filenamew = handle->filew;
- sizew = -1;
- }
-
- if (filenamew) {
- /* Convert the filename to utf8. */
- size = WideCharToMultiByte(CP_UTF8,
- 0,
- filenamew,
- sizew,
- NULL,
- 0,
- NULL,
- NULL);
- if (size) {
- filename = (char*)uv__malloc(size + 1);
- if (!filename) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- size = WideCharToMultiByte(CP_UTF8,
- 0,
- filenamew,
- sizew,
- filename,
- size,
- NULL,
- NULL);
- if (size) {
- filename[size] = '\0';
- } else {
- uv__free(filename);
- filename = NULL;
- }
- }
- }
-
- switch (file_info->Action) {
- case FILE_ACTION_ADDED:
- case FILE_ACTION_REMOVED:
- case FILE_ACTION_RENAMED_OLD_NAME:
- case FILE_ACTION_RENAMED_NEW_NAME:
- handle->cb(handle, filename, UV_RENAME, 0);
- break;
-
- case FILE_ACTION_MODIFIED:
- handle->cb(handle, filename, UV_CHANGE, 0);
- break;
- }
-
- uv__free(filename);
- filename = NULL;
- uv__free(long_filenamew);
- long_filenamew = NULL;
- }
-
- offset = file_info->NextEntryOffset;
- } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
- } else {
- handle->cb(handle, NULL, UV_CHANGE, 0);
- }
- } else {
- err = GET_REQ_ERROR(req);
- handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
- }
-
- if (!(handle->flags & UV__HANDLE_CLOSING)) {
- uv_fs_event_queue_readdirchanges(loop, handle);
- } else {
- uv_want_endgame(loop, (uv_handle_t*)handle);
- }
-}
-
-
-void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
- uv_fs_event_stop(handle);
-
- uv__handle_closing(handle);
-
- if (!handle->req_pending) {
- uv_want_endgame(loop, (uv_handle_t*)handle);
- }
-
-}
-
-
-void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
- if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) {
- assert(!(handle->flags & UV_HANDLE_CLOSED));
-
- if (handle->buffer) {
- uv__free(handle->buffer);
- handle->buffer = NULL;
- }
-
- uv__handle_close(handle);
- }
-}