void fs__fsync(uv_fs_t* req, uv_file file) { int result = FlushFileBuffers((HANDLE)_get_osfhandle(file)) ? 0 : -1; if (result == -1) { SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); } else { SET_REQ_RESULT(req, result); } }
void fs__link(uv_fs_t* req, const char* path, const char* new_path) { int result = CreateHardLinkA(new_path, path, NULL) ? 0 : -1; if (result == -1) { SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); } else { SET_REQ_RESULT(req, result); } }
void fs__stat(uv_fs_t* req, const char* path) { int result; result = _stati64(path, &req->stat); if (result == -1) { req->ptr = NULL; } else { req->ptr = &req->stat; } SET_REQ_RESULT(req, result); }
void fs__fstat(uv_fs_t* req, uv_file file) { int result; result = _fstati64(file, &req->stat); if (result == -1) { req->ptr = NULL; } else { req->ptr = &req->stat; } SET_REQ_RESULT(req, result); }
void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset) { int result = 0; if (offset != -1) { result = _lseek(file, offset, SEEK_SET); } if (result != -1) { result = _write(file, buf, length); } SET_REQ_RESULT(req, result); }
void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset) { HANDLE handle; OVERLAPPED overlapped, *overlapped_ptr; LARGE_INTEGER offset_; DWORD bytes; handle = (HANDLE) _get_osfhandle(file); if (handle == INVALID_HANDLE_VALUE) { SET_REQ_RESULT(req, -1); return; } if (length > INT_MAX) { SET_REQ_ERROR(req, ERROR_INSUFFICIENT_BUFFER); return; } if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); offset_.QuadPart = offset; overlapped.Offset = offset_.LowPart; overlapped.OffsetHigh = offset_.HighPart; overlapped_ptr = &overlapped; } else { overlapped_ptr = NULL; } if (WriteFile(handle, buf, length, &bytes, overlapped_ptr)) { SET_REQ_RESULT(req, bytes); } else { SET_REQ_ERROR(req, GetLastError()); } }
void fs__symlink(uv_fs_t* req, const char* path, const char* new_path, int flags) { int result; if (pCreateSymbolicLinkA) { result = pCreateSymbolicLinkA(new_path, path, flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1; if (result == -1) { SET_REQ_LAST_ERROR(req, GetLastError()); } } else { result = -1; errno = ENOSYS; } SET_REQ_RESULT(req, result); }
void fs__fstat(uv_fs_t* req, uv_file file) { int result; req->ptr = malloc(sizeof(struct _stat)); if (!req->ptr) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } result = _fstat(file, (struct _stat*)req->ptr); if (result == -1) { free(req->ptr); req->ptr = NULL; } else { req->flags |= UV_FS_FREE_PTR; } SET_REQ_RESULT(req, result); }
void fs__fchmod(uv_fs_t* req, uv_file file, int mode) { int result; HANDLE handle; NTSTATUS nt_status; IO_STATUS_BLOCK io_status; FILE_BASIC_INFORMATION file_info; handle = (HANDLE)_get_osfhandle(file); nt_status = pNtQueryInformationFile(handle, &io_status, &file_info, sizeof file_info, FileBasicInformation); if (nt_status != STATUS_SUCCESS) { result = -1; goto done; } if (mode & _S_IWRITE) { file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; } else { file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; } nt_status = pNtSetInformationFile(handle, &io_status, &file_info, sizeof file_info, FileBasicInformation); if (nt_status != STATUS_SUCCESS) { result = -1; goto done; } result = 0; done: SET_REQ_RESULT(req, result); }
void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file, off_t in_offset, size_t length) { const size_t max_buf_size = 65536; size_t buf_size = length < max_buf_size ? length : max_buf_size; int n, result = 0; char* buf = (char*)malloc(buf_size); if (!buf) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } if (in_offset != -1) { result = _lseek(in_file, in_offset, SEEK_SET); } if (result != -1) { while (length > 0) { n = _read(in_file, buf, length < buf_size ? length : buf_size); if (n == 0) { break; } else if (n == -1) { result = -1; break; } length -= n; n = _write(out_file, buf, n); if (n == -1) { result = -1; break; } result += n; } } SET_REQ_RESULT(req, result); }
void fs__utime(uv_fs_t* req, const char* path, double atime, double mtime) { int result; struct _utimbuf b = {(time_t)atime, (time_t)mtime}; result = _utime(path, &b); SET_REQ_RESULT(req, result); }
void fs__chmod(uv_fs_t* req, const char* path, int mode) { int result = _chmod(path, mode); SET_REQ_RESULT(req, result); }
void fs__ftruncate(uv_fs_t* req, uv_file file, off_t offset) { int result = _chsize(file, offset); SET_REQ_RESULT(req, result); }
void fs__open(uv_fs_t* req, const char* path, int flags, int mode) { int result = _open(path, flags, mode); SET_REQ_RESULT(req, result); }
void fs__open(uv_fs_t* req, const char* path, int flags, int mode) { DWORD access; DWORD share; SECURITY_ATTRIBUTES sa; DWORD disposition; DWORD attributes; HANDLE file; int result, current_umask; /* Obtain the active umask. umask() never fails and returns the previous */ /* umask. */ current_umask = umask(0); umask(current_umask); /* convert flags and mode to CreateFile parameters */ switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { case _O_RDONLY: access = GENERIC_READ; break; case _O_WRONLY: access = GENERIC_WRITE; break; case _O_RDWR: access = GENERIC_READ | GENERIC_WRITE; break; default: result = -1; goto end; } /* * Here is where we deviate significantly from what CRT's _open() * does. We indiscriminately use all the sharing modes, to match * UNIX semantics. In particular, this ensures that the file can * be deleted even whilst it's open, fixing issue #1449. */ share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; if (flags & _O_NOINHERIT) { sa.bInheritHandle = FALSE; } else { sa.bInheritHandle = TRUE; } switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) { case 0: case _O_EXCL: disposition = OPEN_EXISTING; break; case _O_CREAT: disposition = OPEN_ALWAYS; break; case _O_CREAT | _O_EXCL: case _O_CREAT | _O_TRUNC | _O_EXCL: disposition = CREATE_NEW; break; case _O_TRUNC: case _O_TRUNC | _O_EXCL: disposition = TRUNCATE_EXISTING; break; case _O_CREAT | _O_TRUNC: disposition = CREATE_ALWAYS; break; default: result = -1; goto end; } attributes = FILE_ATTRIBUTE_NORMAL; if (flags & _O_CREAT) { if (!((mode & ~current_umask) & _S_IWRITE)) { attributes |= FILE_ATTRIBUTE_READONLY; } } if (flags & _O_TEMPORARY ) { attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY; access |= DELETE; } if (flags & _O_SHORT_LIVED) { attributes |= FILE_ATTRIBUTE_TEMPORARY; } switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) { case 0: break; case _O_SEQUENTIAL: attributes |= FILE_FLAG_SEQUENTIAL_SCAN; break; case _O_RANDOM: attributes |= FILE_FLAG_RANDOM_ACCESS; break; default: result = -1; goto end; } file = CreateFileA(path, access, share, &sa, disposition, attributes, NULL); if (file == INVALID_HANDLE_VALUE) { SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); return; } result = _open_osfhandle((intptr_t)file, flags); end: SET_REQ_RESULT(req, result); }
void fs__readdir(uv_fs_t* req, const char* path, int flags) { int result; char* buf, *ptr, *name; HANDLE dir; WIN32_FIND_DATAA ent = {0}; size_t len = strlen(path); size_t buf_size = 4096; const char* fmt = !len ? "./*" : (path[len - 1] == '/' || path[len - 1] == '\\') ? "%s*" : "%s\\*"; char* path2 = (char*)malloc(len + 4); if (!path2) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } sprintf(path2, fmt, path); dir = FindFirstFileA(path2, &ent); free(path2); if(dir == INVALID_HANDLE_VALUE) { SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); return; } buf = (char*)malloc(buf_size); if (!buf) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } ptr = buf; result = 0; do { name = ent.cFileName; if (name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))) { len = strlen(name); while ((ptr - buf) + len + 1 > buf_size) { buf_size *= 2; path2 = buf; buf = (char*)realloc(buf, buf_size); if (!buf) { uv_fatal_error(ERROR_OUTOFMEMORY, "realloc"); } ptr = buf + (ptr - path2); } strcpy(ptr, name); ptr += len + 1; result++; } } while(FindNextFileA(dir, &ent)); FindClose(dir); req->ptr = buf; req->flags |= UV_FS_FREE_PTR; done: SET_REQ_RESULT(req, result); }
void fs__rmdir(uv_fs_t* req, const char* path) { int result = _rmdir(path); SET_REQ_RESULT(req, result); }
void fs__mkdir(uv_fs_t* req, const char* path, int mode) { int result = _mkdir(path); SET_REQ_RESULT(req, result); }
void fs__unlink(uv_fs_t* req, const char* path) { int result = _unlink(path); SET_REQ_RESULT(req, result); }
void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) { int result; struct _utimbuf b = {(time_t)atime, (time_t)mtime}; result = _futime(file, &b); SET_REQ_RESULT(req, result); }
void fs__rename(uv_fs_t* req, const char* path, const char* new_path) { int result = rename(path, new_path); SET_REQ_RESULT(req, result); }
void fs__fsync(uv_fs_t* req, uv_file file) { int result = FlushFileBuffers((HANDLE)_get_osfhandle(file)) ? 0 : -1; SET_REQ_RESULT(req, result); }
void fs__readlink(uv_fs_t* req, const char* path) { int result = -1; BOOL rv; HANDLE symlink; void* buffer = NULL; DWORD bytes_returned; REPARSE_DATA_BUFFER* reparse_data; int utf8size; symlink = CreateFileA(path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (INVALID_HANDLE_VALUE == symlink) { result = -1; SET_REQ_LAST_ERROR(req, GetLastError()); goto done; } buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); if (!buffer) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } rv = DeviceIoControl(symlink, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytes_returned, NULL); if (!rv) { result = -1; SET_REQ_LAST_ERROR(req, GetLastError()); goto done; } reparse_data = buffer; if (reparse_data->ReparseTag != IO_REPARSE_TAG_SYMLINK) { result = -1; /* something is seriously wrong */ SET_REQ_LAST_ERROR(req, GetLastError()); goto done; } utf8size = uv_utf16_to_utf8(reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)), reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t), NULL, 0); if (!utf8size) { result = -1; SET_REQ_LAST_ERROR(req, GetLastError()); goto done; } req->ptr = malloc(utf8size + 1); if (!req->ptr) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } req->flags |= UV_FS_FREE_PTR; utf8size = uv_utf16_to_utf8(reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)), reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t), req->ptr, utf8size); if (!utf8size) { result = -1; SET_REQ_LAST_ERROR(req, GetLastError()); goto done; } ((char*)req->ptr)[utf8size] = '\0'; result = 0; done: if (buffer) { free(buffer); } if (symlink != INVALID_HANDLE_VALUE) { CloseHandle(symlink); } SET_REQ_RESULT(req, result); }
void fs__close(uv_fs_t* req, uv_file file) { int result = _close(file); SET_REQ_RESULT(req, result); }