win/fs.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <direct.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <io.h>
28 #include <limits.h>
29 #include <sys/stat.h>
30 #include <sys/utime.h>
31 #include <stdio.h>
32 
33 #include "uv.h"
34 #include "internal.h"
35 #include "req-inl.h"
36 #include "handle-inl.h"
37 #include "fs-fd-hash-inl.h"
38 
39 
40 #define UV_FS_FREE_PATHS 0x0002
41 #define UV_FS_FREE_PTR 0x0008
42 #define UV_FS_CLEANEDUP 0x0010
43 
44 
45 #define INIT(subtype) \
46  do { \
47  if (req == NULL) \
48  return UV_EINVAL; \
49  uv_fs_req_init(loop, req, subtype, cb); \
50  } \
51  while (0)
52 
53 #define POST \
54  do { \
55  if (cb != NULL) { \
56  uv__req_register(loop, req); \
57  uv__work_submit(loop, \
58  &req->work_req, \
59  UV__WORK_FAST_IO, \
60  uv__fs_work, \
61  uv__fs_done); \
62  return 0; \
63  } else { \
64  uv__fs_work(&req->work_req); \
65  return req->result; \
66  } \
67  } \
68  while (0)
69 
70 #define SET_REQ_RESULT(req, result_value) \
71  do { \
72  req->result = (result_value); \
73  if (req->result == -1) { \
74  req->sys_errno_ = _doserrno; \
75  req->result = uv_translate_sys_error(req->sys_errno_); \
76  } \
77  } while (0)
78 
79 #define SET_REQ_WIN32_ERROR(req, sys_errno) \
80  do { \
81  req->sys_errno_ = (sys_errno); \
82  req->result = uv_translate_sys_error(req->sys_errno_); \
83  } while (0)
84 
85 #define SET_REQ_UV_ERROR(req, uv_errno, sys_errno) \
86  do { \
87  req->result = (uv_errno); \
88  req->sys_errno_ = (sys_errno); \
89  } while (0)
90 
91 #define VERIFY_FD(fd, req) \
92  if (fd == -1) { \
93  req->result = UV_EBADF; \
94  req->sys_errno_ = ERROR_INVALID_HANDLE; \
95  return; \
96  }
97 
98 #define MILLIONu (1000U * 1000U)
99 #define BILLIONu (1000U * 1000U * 1000U)
100 
101 #define FILETIME_TO_UINT(filetime) \
102  (*((uint64_t*) &(filetime)) - (uint64_t) 116444736 * BILLIONu)
103 
104 #define FILETIME_TO_TIME_T(filetime) \
105  (FILETIME_TO_UINT(filetime) / (10u * MILLIONu))
106 
107 #define FILETIME_TO_TIME_NS(filetime, secs) \
108  ((FILETIME_TO_UINT(filetime) - (secs * (uint64_t) 10 * MILLIONu)) * 100U)
109 
110 #define FILETIME_TO_TIMESPEC(ts, filetime) \
111  do { \
112  (ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \
113  (ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \
114  } while(0)
115 
116 #define TIME_T_TO_FILETIME(time, filetime_ptr) \
117  do { \
118  uint64_t bigtime = ((uint64_t) ((time) * (uint64_t) 10 * MILLIONu)) + \
119  (uint64_t) 116444736 * BILLIONu; \
120  (filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \
121  (filetime_ptr)->dwHighDateTime = bigtime >> 32; \
122  } while(0)
123 
124 #define IS_SLASH(c) ((c) == L'\\' || (c) == L'/')
125 #define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \
126  ((c) >= L'A' && (c) <= L'Z'))
127 
128 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
129 
130 const WCHAR JUNCTION_PREFIX[] = L"\\??\\";
131 const WCHAR JUNCTION_PREFIX_LEN = 4;
132 
133 const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\";
134 const WCHAR LONG_PATH_PREFIX_LEN = 4;
135 
136 const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
137 const WCHAR UNC_PATH_PREFIX_LEN = 8;
138 
140 
142 
143 
144 void uv_fs_init(void) {
145  SYSTEM_INFO system_info;
146 
147  GetSystemInfo(&system_info);
148  uv__allocation_granularity = system_info.dwAllocationGranularity;
149 
151 }
152 
153 
154 INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
155  const char* new_path, const int copy_path) {
156  char* buf;
157  char* pos;
158  ssize_t buf_sz = 0, path_len = 0, pathw_len = 0, new_pathw_len = 0;
159 
160  /* new_path can only be set if path is also set. */
161  assert(new_path == NULL || path != NULL);
162 
163  if (path != NULL) {
164  pathw_len = MultiByteToWideChar(CP_UTF8,
165  0,
166  path,
167  -1,
168  NULL,
169  0);
170  if (pathw_len == 0) {
171  return GetLastError();
172  }
173 
174  buf_sz += pathw_len * sizeof(WCHAR);
175  }
176 
177  if (path != NULL && copy_path) {
178  path_len = 1 + strlen(path);
179  buf_sz += path_len;
180  }
181 
182  if (new_path != NULL) {
183  new_pathw_len = MultiByteToWideChar(CP_UTF8,
184  0,
185  new_path,
186  -1,
187  NULL,
188  0);
189  if (new_pathw_len == 0) {
190  return GetLastError();
191  }
192 
193  buf_sz += new_pathw_len * sizeof(WCHAR);
194  }
195 
196 
197  if (buf_sz == 0) {
198  req->file.pathw = NULL;
199  req->fs.info.new_pathw = NULL;
200  req->path = NULL;
201  return 0;
202  }
203 
204  buf = (char*) uv__malloc(buf_sz);
205  if (buf == NULL) {
206  return ERROR_OUTOFMEMORY;
207  }
208 
209  pos = buf;
210 
211  if (path != NULL) {
212  DWORD r = MultiByteToWideChar(CP_UTF8,
213  0,
214  path,
215  -1,
216  (WCHAR*) pos,
217  pathw_len);
218  assert(r == (DWORD) pathw_len);
219  req->file.pathw = (WCHAR*) pos;
220  pos += r * sizeof(WCHAR);
221  } else {
222  req->file.pathw = NULL;
223  }
224 
225  if (new_path != NULL) {
226  DWORD r = MultiByteToWideChar(CP_UTF8,
227  0,
228  new_path,
229  -1,
230  (WCHAR*) pos,
231  new_pathw_len);
232  assert(r == (DWORD) new_pathw_len);
233  req->fs.info.new_pathw = (WCHAR*) pos;
234  pos += r * sizeof(WCHAR);
235  } else {
236  req->fs.info.new_pathw = NULL;
237  }
238 
239  req->path = path;
240  if (path != NULL && copy_path) {
241  memcpy(pos, path, path_len);
242  assert(path_len == buf_sz - (pos - buf));
243  req->path = pos;
244  }
245 
246  req->flags |= UV_FS_FREE_PATHS;
247 
248  return 0;
249 }
250 
251 
252 
254  uv_fs_type fs_type, const uv_fs_cb cb) {
255  uv__once_init();
256  UV_REQ_INIT(req, UV_FS);
257  req->loop = loop;
258  req->flags = 0;
259  req->fs_type = fs_type;
260  req->result = 0;
261  req->ptr = NULL;
262  req->path = NULL;
263  req->cb = cb;
264  memset(&req->fs, 0, sizeof(req->fs));
265 }
266 
267 
268 static int fs__wide_to_utf8(WCHAR* w_source_ptr,
269  DWORD w_source_len,
270  char** target_ptr,
271  uint64_t* target_len_ptr) {
272  int r;
273  int target_len;
274  char* target;
275  target_len = WideCharToMultiByte(CP_UTF8,
276  0,
277  w_source_ptr,
278  w_source_len,
279  NULL,
280  0,
281  NULL,
282  NULL);
283 
284  if (target_len == 0) {
285  return -1;
286  }
287 
288  if (target_len_ptr != NULL) {
289  *target_len_ptr = target_len;
290  }
291 
292  if (target_ptr == NULL) {
293  return 0;
294  }
295 
296  target = uv__malloc(target_len + 1);
297  if (target == NULL) {
298  SetLastError(ERROR_OUTOFMEMORY);
299  return -1;
300  }
301 
302  r = WideCharToMultiByte(CP_UTF8,
303  0,
304  w_source_ptr,
305  w_source_len,
306  target,
307  target_len,
308  NULL,
309  NULL);
310  assert(r == target_len);
311  target[target_len] = '\0';
312  *target_ptr = target;
313  return 0;
314 }
315 
316 
317 INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
318  uint64_t* target_len_ptr) {
319  char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
320  REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
321  WCHAR* w_target;
322  DWORD w_target_len;
323  DWORD bytes;
324 
325  if (!DeviceIoControl(handle,
327  NULL,
328  0,
329  buffer,
330  sizeof buffer,
331  &bytes,
332  NULL)) {
333  return -1;
334  }
335 
336  if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
337  /* Real symlink */
338  w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer +
339  (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset /
340  sizeof(WCHAR));
341  w_target_len =
342  reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength /
343  sizeof(WCHAR);
344 
345  /* Real symlinks can contain pretty much everything, but the only thing we
346  * really care about is undoing the implicit conversion to an NT namespaced
347  * path that CreateSymbolicLink will perform on absolute paths. If the path
348  * is win32-namespaced then the user must have explicitly made it so, and
349  * we better just return the unmodified reparse data. */
350  if (w_target_len >= 4 &&
351  w_target[0] == L'\\' &&
352  w_target[1] == L'?' &&
353  w_target[2] == L'?' &&
354  w_target[3] == L'\\') {
355  /* Starts with \??\ */
356  if (w_target_len >= 6 &&
357  ((w_target[4] >= L'A' && w_target[4] <= L'Z') ||
358  (w_target[4] >= L'a' && w_target[4] <= L'z')) &&
359  w_target[5] == L':' &&
360  (w_target_len == 6 || w_target[6] == L'\\')) {
361  /* \??<drive>:\ */
362  w_target += 4;
363  w_target_len -= 4;
364 
365  } else if (w_target_len >= 8 &&
366  (w_target[4] == L'U' || w_target[4] == L'u') &&
367  (w_target[5] == L'N' || w_target[5] == L'n') &&
368  (w_target[6] == L'C' || w_target[6] == L'c') &&
369  w_target[7] == L'\\') {
370  /* \??\UNC<server><share>\ - make sure the final path looks like
371  * \<server><share>\ */
372  w_target += 6;
373  w_target[0] = L'\\';
374  w_target_len -= 6;
375  }
376  }
377 
378  } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
379  /* Junction. */
380  w_target = reparse_data->MountPointReparseBuffer.PathBuffer +
381  (reparse_data->MountPointReparseBuffer.SubstituteNameOffset /
382  sizeof(WCHAR));
383  w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength /
384  sizeof(WCHAR);
385 
386  /* Only treat junctions that look like \??<drive>:\ as symlink. Junctions
387  * can also be used as mount points, like \??\Volume{<guid>}, but that's
388  * confusing for programs since they wouldn't be able to actually
389  * understand such a path when returned by uv_readlink(). UNC paths are
390  * never valid for junctions so we don't care about them. */
391  if (!(w_target_len >= 6 &&
392  w_target[0] == L'\\' &&
393  w_target[1] == L'?' &&
394  w_target[2] == L'?' &&
395  w_target[3] == L'\\' &&
396  ((w_target[4] >= L'A' && w_target[4] <= L'Z') ||
397  (w_target[4] >= L'a' && w_target[4] <= L'z')) &&
398  w_target[5] == L':' &&
399  (w_target_len == 6 || w_target[6] == L'\\'))) {
400  SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
401  return -1;
402  }
403 
404  /* Remove leading \??\ */
405  w_target += 4;
406  w_target_len -= 4;
407 
408  } else {
409  /* Reparse tag does not indicate a symlink. */
410  SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
411  return -1;
412  }
413 
414  return fs__wide_to_utf8(w_target, w_target_len, target_ptr, target_len_ptr);
415 }
416 
417 
419  DWORD access;
420  DWORD share;
421  DWORD disposition;
422  DWORD attributes = 0;
423  HANDLE file;
424  int fd, current_umask;
425  int flags = req->fs.info.file_flags;
426  struct uv__fd_info_s fd_info;
427 
428  /* Adjust flags to be compatible with the memory file mapping. Save the
429  * original flags to emulate the correct behavior. */
430  if (flags & UV_FS_O_FILEMAP) {
431  fd_info.flags = flags;
432  fd_info.current_pos.QuadPart = 0;
433 
435  UV_FS_O_WRONLY) {
436  /* CreateFileMapping always needs read access */
438  }
439 
440  if (flags & UV_FS_O_APPEND) {
441  /* Clear the append flag and ensure RDRW mode */
442  flags &= ~UV_FS_O_APPEND;
444  flags |= UV_FS_O_RDWR;
445  }
446  }
447 
448  /* Obtain the active umask. umask() never fails and returns the previous
449  * umask. */
450  current_umask = umask(0);
451  umask(current_umask);
452 
453  /* convert flags and mode to CreateFile parameters */
455  case UV_FS_O_RDONLY:
456  access = FILE_GENERIC_READ;
457  break;
458  case UV_FS_O_WRONLY:
459  access = FILE_GENERIC_WRITE;
460  break;
461  case UV_FS_O_RDWR:
462  access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
463  break;
464  default:
465  goto einval;
466  }
467 
468  if (flags & UV_FS_O_APPEND) {
469  access &= ~FILE_WRITE_DATA;
470  access |= FILE_APPEND_DATA;
471  }
472 
473  /*
474  * Here is where we deviate significantly from what CRT's _open()
475  * does. We indiscriminately use all the sharing modes, to match
476  * UNIX semantics. In particular, this ensures that the file can
477  * be deleted even whilst it's open, fixing issue
478  * https://github.com/nodejs/node-v0.x-archive/issues/1449.
479  * We still support exclusive sharing mode, since it is necessary
480  * for opening raw block devices, otherwise Windows will prevent
481  * any attempt to write past the master boot record.
482  */
483  if (flags & UV_FS_O_EXLOCK) {
484  share = 0;
485  } else {
486  share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
487  }
488 
489  switch (flags & (UV_FS_O_CREAT | UV_FS_O_EXCL | UV_FS_O_TRUNC)) {
490  case 0:
491  case UV_FS_O_EXCL:
492  disposition = OPEN_EXISTING;
493  break;
494  case UV_FS_O_CREAT:
495  disposition = OPEN_ALWAYS;
496  break;
499  disposition = CREATE_NEW;
500  break;
501  case UV_FS_O_TRUNC:
503  disposition = TRUNCATE_EXISTING;
504  break;
506  disposition = CREATE_ALWAYS;
507  break;
508  default:
509  goto einval;
510  }
511 
512  attributes |= FILE_ATTRIBUTE_NORMAL;
513  if (flags & UV_FS_O_CREAT) {
514  if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
515  attributes |= FILE_ATTRIBUTE_READONLY;
516  }
517  }
518 
519  if (flags & UV_FS_O_TEMPORARY ) {
520  attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
521  access |= DELETE;
522  }
523 
524  if (flags & UV_FS_O_SHORT_LIVED) {
525  attributes |= FILE_ATTRIBUTE_TEMPORARY;
526  }
527 
528  switch (flags & (UV_FS_O_SEQUENTIAL | UV_FS_O_RANDOM)) {
529  case 0:
530  break;
531  case UV_FS_O_SEQUENTIAL:
532  attributes |= FILE_FLAG_SEQUENTIAL_SCAN;
533  break;
534  case UV_FS_O_RANDOM:
535  attributes |= FILE_FLAG_RANDOM_ACCESS;
536  break;
537  default:
538  goto einval;
539  }
540 
541  if (flags & UV_FS_O_DIRECT) {
542  /*
543  * FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive.
544  * Windows returns 87, ERROR_INVALID_PARAMETER if these are combined.
545  *
546  * FILE_APPEND_DATA is included in FILE_GENERIC_WRITE:
547  *
548  * FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE |
549  * FILE_WRITE_DATA |
550  * FILE_WRITE_ATTRIBUTES |
551  * FILE_WRITE_EA |
552  * FILE_APPEND_DATA |
553  * SYNCHRONIZE
554  *
555  * Note: Appends are also permitted by FILE_WRITE_DATA.
556  *
557  * In order for direct writes and direct appends to succeed, we therefore
558  * exclude FILE_APPEND_DATA if FILE_WRITE_DATA is specified, and otherwise
559  * fail if the user's sole permission is a direct append, since this
560  * particular combination is invalid.
561  */
562  if (access & FILE_APPEND_DATA) {
563  if (access & FILE_WRITE_DATA) {
564  access &= ~FILE_APPEND_DATA;
565  } else {
566  goto einval;
567  }
568  }
569  attributes |= FILE_FLAG_NO_BUFFERING;
570  }
571 
572  switch (flags & (UV_FS_O_DSYNC | UV_FS_O_SYNC)) {
573  case 0:
574  break;
575  case UV_FS_O_DSYNC:
576  case UV_FS_O_SYNC:
577  attributes |= FILE_FLAG_WRITE_THROUGH;
578  break;
579  default:
580  goto einval;
581  }
582 
583  /* Setting this flag makes it possible to open a directory. */
584  attributes |= FILE_FLAG_BACKUP_SEMANTICS;
585 
586  file = CreateFileW(req->file.pathw,
587  access,
588  share,
589  NULL,
590  disposition,
591  attributes,
592  NULL);
593  if (file == INVALID_HANDLE_VALUE) {
594  DWORD error = GetLastError();
595  if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) &&
596  !(flags & UV_FS_O_EXCL)) {
597  /* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was
598  * specified, it means the path referred to a directory. */
599  SET_REQ_UV_ERROR(req, UV_EISDIR, error);
600  } else {
601  SET_REQ_WIN32_ERROR(req, GetLastError());
602  }
603  return;
604  }
605 
606  fd = _open_osfhandle((intptr_t) file, flags);
607  if (fd < 0) {
608  /* The only known failure mode for _open_osfhandle() is EMFILE, in which
609  * case GetLastError() will return zero. However we'll try to handle other
610  * errors as well, should they ever occur.
611  */
612  if (errno == EMFILE)
613  SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
614  else if (GetLastError() != ERROR_SUCCESS)
615  SET_REQ_WIN32_ERROR(req, GetLastError());
616  else
617  SET_REQ_WIN32_ERROR(req, (DWORD) UV_UNKNOWN);
618  CloseHandle(file);
619  return;
620  }
621 
622  if (flags & UV_FS_O_FILEMAP) {
623  FILE_STANDARD_INFO file_info;
624  if (!GetFileInformationByHandleEx(file,
625  FileStandardInfo,
626  &file_info,
627  sizeof file_info)) {
628  SET_REQ_WIN32_ERROR(req, GetLastError());
629  CloseHandle(file);
630  return;
631  }
632  fd_info.is_directory = file_info.Directory;
633 
634  if (fd_info.is_directory) {
635  fd_info.size.QuadPart = 0;
636  fd_info.mapping = INVALID_HANDLE_VALUE;
637  } else {
638  if (!GetFileSizeEx(file, &fd_info.size)) {
639  SET_REQ_WIN32_ERROR(req, GetLastError());
640  CloseHandle(file);
641  return;
642  }
643 
644  if (fd_info.size.QuadPart == 0) {
645  fd_info.mapping = INVALID_HANDLE_VALUE;
646  } else {
647  DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY |
648  UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE;
649  fd_info.mapping = CreateFileMapping(file,
650  NULL,
651  flProtect,
652  fd_info.size.HighPart,
653  fd_info.size.LowPart,
654  NULL);
655  if (fd_info.mapping == NULL) {
656  SET_REQ_WIN32_ERROR(req, GetLastError());
657  CloseHandle(file);
658  return;
659  }
660  }
661  }
662 
663  uv__fd_hash_add(fd, &fd_info);
664  }
665 
666  SET_REQ_RESULT(req, fd);
667  return;
668 
669  einval:
670  SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
671 }
672 
674  int fd = req->file.fd;
675  int result;
676  struct uv__fd_info_s fd_info;
677 
678  VERIFY_FD(fd, req);
679 
680  if (uv__fd_hash_remove(fd, &fd_info)) {
681  if (fd_info.mapping != INVALID_HANDLE_VALUE) {
682  CloseHandle(fd_info.mapping);
683  }
684  }
685 
686  if (fd > 2)
687  result = _close(fd);
688  else
689  result = 0;
690 
691  /* _close doesn't set _doserrno on failure, but it does always set errno
692  * to EBADF on failure.
693  */
694  if (result == -1) {
695  assert(errno == EBADF);
696  SET_REQ_UV_ERROR(req, UV_EBADF, ERROR_INVALID_HANDLE);
697  } else {
698  req->result = 0;
699  }
700 }
701 
702 
703 LONG fs__filemap_ex_filter(LONG excode, PEXCEPTION_POINTERS pep,
704  int* perror) {
705  if (excode != EXCEPTION_IN_PAGE_ERROR) {
706  return EXCEPTION_CONTINUE_SEARCH;
707  }
708 
709  assert(perror != NULL);
710  if (pep != NULL && pep->ExceptionRecord != NULL &&
711  pep->ExceptionRecord->NumberParameters >= 3) {
712  NTSTATUS status = (NTSTATUS)pep->ExceptionRecord->ExceptionInformation[3];
713  *perror = pRtlNtStatusToDosError(status);
714  if (*perror != ERROR_SUCCESS) {
715  return EXCEPTION_EXECUTE_HANDLER;
716  }
717  }
718  *perror = UV_UNKNOWN;
719  return EXCEPTION_EXECUTE_HANDLER;
720 }
721 
722 
723 void fs__read_filemap(uv_fs_t* req, struct uv__fd_info_s* fd_info) {
724  int fd = req->file.fd; /* VERIFY_FD done in fs__read */
725  int rw_flags = fd_info->flags &
727  size_t read_size, done_read;
728  unsigned int index;
729  LARGE_INTEGER pos, end_pos;
730  size_t view_offset;
731  LARGE_INTEGER view_base;
732  void* view;
733 
734  if (rw_flags == UV_FS_O_WRONLY) {
735  SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
736  return;
737  }
738  if (fd_info->is_directory) {
739  SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION);
740  return;
741  }
742 
743  if (req->fs.info.offset == -1) {
744  pos = fd_info->current_pos;
745  } else {
746  pos.QuadPart = req->fs.info.offset;
747  }
748 
749  /* Make sure we wont read past EOF. */
750  if (pos.QuadPart >= fd_info->size.QuadPart) {
751  SET_REQ_RESULT(req, 0);
752  return;
753  }
754 
755  read_size = 0;
756  for (index = 0; index < req->fs.info.nbufs; ++index) {
757  read_size += req->fs.info.bufs[index].len;
758  }
759  read_size = (size_t) MIN((LONGLONG) read_size,
760  fd_info->size.QuadPart - pos.QuadPart);
761  if (read_size == 0) {
762  SET_REQ_RESULT(req, 0);
763  return;
764  }
765 
766  end_pos.QuadPart = pos.QuadPart + read_size;
767 
768  view_offset = pos.QuadPart % uv__allocation_granularity;
769  view_base.QuadPart = pos.QuadPart - view_offset;
770  view = MapViewOfFile(fd_info->mapping,
771  FILE_MAP_READ,
772  view_base.HighPart,
773  view_base.LowPart,
774  view_offset + read_size);
775  if (view == NULL) {
776  SET_REQ_WIN32_ERROR(req, GetLastError());
777  return;
778  }
779 
780  done_read = 0;
781  for (index = 0;
782  index < req->fs.info.nbufs && done_read < read_size;
783  ++index) {
784  int err = 0;
785  size_t this_read_size = MIN(req->fs.info.bufs[index].len,
786  read_size - done_read);
787 #ifdef _MSC_VER
788  __try {
789 #endif
790  memcpy(req->fs.info.bufs[index].base,
791  (char*)view + view_offset + done_read,
792  this_read_size);
793 #ifdef _MSC_VER
794  }
795  __except (fs__filemap_ex_filter(GetExceptionCode(),
796  GetExceptionInformation(), &err)) {
798  UnmapViewOfFile(view);
799  return;
800  }
801 #endif
802  done_read += this_read_size;
803  }
804  assert(done_read == read_size);
805 
806  if (!UnmapViewOfFile(view)) {
807  SET_REQ_WIN32_ERROR(req, GetLastError());
808  return;
809  }
810 
811  if (req->fs.info.offset == -1) {
812  fd_info->current_pos = end_pos;
813  uv__fd_hash_add(fd, fd_info);
814  }
815 
817  return;
818 }
819 
821  int fd = req->file.fd;
822  int64_t offset = req->fs.info.offset;
823  HANDLE handle;
824  OVERLAPPED overlapped, *overlapped_ptr;
825  LARGE_INTEGER offset_;
826  DWORD bytes;
827  DWORD error;
828  int result;
829  unsigned int index;
830  LARGE_INTEGER original_position;
831  LARGE_INTEGER zero_offset;
832  int restore_position;
833  struct uv__fd_info_s fd_info;
834 
835  VERIFY_FD(fd, req);
836 
837  if (uv__fd_hash_get(fd, &fd_info)) {
838  fs__read_filemap(req, &fd_info);
839  return;
840  }
841 
842  zero_offset.QuadPart = 0;
843  restore_position = 0;
845 
846  if (handle == INVALID_HANDLE_VALUE) {
847  SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
848  return;
849  }
850 
851  if (offset != -1) {
852  memset(&overlapped, 0, sizeof overlapped);
853  overlapped_ptr = &overlapped;
854  if (SetFilePointerEx(handle, zero_offset, &original_position,
855  FILE_CURRENT)) {
856  restore_position = 1;
857  }
858  } else {
859  overlapped_ptr = NULL;
860  }
861 
862  index = 0;
863  bytes = 0;
864  do {
865  DWORD incremental_bytes;
866 
867  if (offset != -1) {
868  offset_.QuadPart = offset + bytes;
869  overlapped.Offset = offset_.LowPart;
870  overlapped.OffsetHigh = offset_.HighPart;
871  }
872 
874  req->fs.info.bufs[index].base,
875  req->fs.info.bufs[index].len,
876  &incremental_bytes,
877  overlapped_ptr);
878  bytes += incremental_bytes;
879  ++index;
880  } while (result && index < req->fs.info.nbufs);
881 
882  if (restore_position)
883  SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN);
884 
885  if (result || bytes > 0) {
887  } else {
888  error = GetLastError();
889  if (error == ERROR_HANDLE_EOF) {
891  } else {
893  }
894  }
895 }
896 
897 
899  struct uv__fd_info_s* fd_info) {
900  int fd = req->file.fd; /* VERIFY_FD done in fs__write */
901  int force_append = fd_info->flags & UV_FS_O_APPEND;
902  int rw_flags = fd_info->flags &
904  size_t write_size, done_write;
905  unsigned int index;
906  LARGE_INTEGER zero, pos, end_pos;
907  size_t view_offset;
908  LARGE_INTEGER view_base;
909  void* view;
910  FILETIME ft;
911 
912  if (rw_flags == UV_FS_O_RDONLY) {
913  SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
914  return;
915  }
916  if (fd_info->is_directory) {
917  SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION);
918  return;
919  }
920 
921  write_size = 0;
922  for (index = 0; index < req->fs.info.nbufs; ++index) {
923  write_size += req->fs.info.bufs[index].len;
924  }
925 
926  if (write_size == 0) {
927  SET_REQ_RESULT(req, 0);
928  return;
929  }
930 
931  zero.QuadPart = 0;
932  if (force_append) {
933  pos = fd_info->size;
934  } else if (req->fs.info.offset == -1) {
935  pos = fd_info->current_pos;
936  } else {
937  pos.QuadPart = req->fs.info.offset;
938  }
939 
940  end_pos.QuadPart = pos.QuadPart + write_size;
941 
942  /* Recreate the mapping to enlarge the file if needed */
943  if (end_pos.QuadPart > fd_info->size.QuadPart) {
944  if (fd_info->mapping != INVALID_HANDLE_VALUE) {
945  CloseHandle(fd_info->mapping);
946  }
947 
948  fd_info->mapping = CreateFileMapping(file,
949  NULL,
950  PAGE_READWRITE,
951  end_pos.HighPart,
952  end_pos.LowPart,
953  NULL);
954  if (fd_info->mapping == NULL) {
955  SET_REQ_WIN32_ERROR(req, GetLastError());
956  CloseHandle(file);
957  fd_info->mapping = INVALID_HANDLE_VALUE;
958  fd_info->size.QuadPart = 0;
959  fd_info->current_pos.QuadPart = 0;
960  uv__fd_hash_add(fd, fd_info);
961  return;
962  }
963 
964  fd_info->size = end_pos;
965  uv__fd_hash_add(fd, fd_info);
966  }
967 
968  view_offset = pos.QuadPart % uv__allocation_granularity;
969  view_base.QuadPart = pos.QuadPart - view_offset;
970  view = MapViewOfFile(fd_info->mapping,
971  FILE_MAP_WRITE,
972  view_base.HighPart,
973  view_base.LowPart,
974  view_offset + write_size);
975  if (view == NULL) {
976  SET_REQ_WIN32_ERROR(req, GetLastError());
977  return;
978  }
979 
980  done_write = 0;
981  for (index = 0; index < req->fs.info.nbufs; ++index) {
982  int err = 0;
983 #ifdef _MSC_VER
984  __try {
985 #endif
986  memcpy((char*)view + view_offset + done_write,
987  req->fs.info.bufs[index].base,
988  req->fs.info.bufs[index].len);
989 #ifdef _MSC_VER
990  }
991  __except (fs__filemap_ex_filter(GetExceptionCode(),
992  GetExceptionInformation(), &err)) {
994  UnmapViewOfFile(view);
995  return;
996  }
997 #endif
998  done_write += req->fs.info.bufs[index].len;
999  }
1000  assert(done_write == write_size);
1001 
1002  if (!FlushViewOfFile(view, 0)) {
1003  SET_REQ_WIN32_ERROR(req, GetLastError());
1004  UnmapViewOfFile(view);
1005  return;
1006  }
1007  if (!UnmapViewOfFile(view)) {
1008  SET_REQ_WIN32_ERROR(req, GetLastError());
1009  return;
1010  }
1011 
1012  if (req->fs.info.offset == -1) {
1013  fd_info->current_pos = end_pos;
1014  uv__fd_hash_add(fd, fd_info);
1015  }
1016 
1017  GetSystemTimeAsFileTime(&ft);
1018  SetFileTime(file, NULL, NULL, &ft);
1019 
1021 }
1022 
1024  int fd = req->file.fd;
1025  int64_t offset = req->fs.info.offset;
1026  HANDLE handle;
1027  OVERLAPPED overlapped, *overlapped_ptr;
1028  LARGE_INTEGER offset_;
1029  DWORD bytes;
1030  int result;
1031  unsigned int index;
1032  LARGE_INTEGER original_position;
1033  LARGE_INTEGER zero_offset;
1034  int restore_position;
1035  struct uv__fd_info_s fd_info;
1036 
1037  VERIFY_FD(fd, req);
1038 
1039  zero_offset.QuadPart = 0;
1040  restore_position = 0;
1041  handle = uv__get_osfhandle(fd);
1042  if (handle == INVALID_HANDLE_VALUE) {
1043  SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
1044  return;
1045  }
1046 
1047  if (uv__fd_hash_get(fd, &fd_info)) {
1048  fs__write_filemap(req, handle, &fd_info);
1049  return;
1050  }
1051 
1052  if (offset != -1) {
1053  memset(&overlapped, 0, sizeof overlapped);
1054  overlapped_ptr = &overlapped;
1055  if (SetFilePointerEx(handle, zero_offset, &original_position,
1056  FILE_CURRENT)) {
1057  restore_position = 1;
1058  }
1059  } else {
1060  overlapped_ptr = NULL;
1061  }
1062 
1063  index = 0;
1064  bytes = 0;
1065  do {
1066  DWORD incremental_bytes;
1067 
1068  if (offset != -1) {
1069  offset_.QuadPart = offset + bytes;
1070  overlapped.Offset = offset_.LowPart;
1071  overlapped.OffsetHigh = offset_.HighPart;
1072  }
1073 
1074  result = WriteFile(handle,
1075  req->fs.info.bufs[index].base,
1076  req->fs.info.bufs[index].len,
1077  &incremental_bytes,
1078  overlapped_ptr);
1079  bytes += incremental_bytes;
1080  ++index;
1081  } while (result && index < req->fs.info.nbufs);
1082 
1083  if (restore_position)
1084  SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN);
1085 
1086  if (result || bytes > 0) {
1088  } else {
1089  SET_REQ_WIN32_ERROR(req, GetLastError());
1090  }
1091 }
1092 
1093 
1095  int result = _wrmdir(req->file.pathw);
1097 }
1098 
1099 
1101  const WCHAR* pathw = req->file.pathw;
1102  HANDLE handle;
1103  BY_HANDLE_FILE_INFORMATION info;
1104  FILE_DISPOSITION_INFORMATION disposition;
1105  IO_STATUS_BLOCK iosb;
1106  NTSTATUS status;
1107 
1108  handle = CreateFileW(pathw,
1109  FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
1110  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1111  NULL,
1112  OPEN_EXISTING,
1113  FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
1114  NULL);
1115 
1116  if (handle == INVALID_HANDLE_VALUE) {
1117  SET_REQ_WIN32_ERROR(req, GetLastError());
1118  return;
1119  }
1120 
1121  if (!GetFileInformationByHandle(handle, &info)) {
1122  SET_REQ_WIN32_ERROR(req, GetLastError());
1123  CloseHandle(handle);
1124  return;
1125  }
1126 
1127  if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1128  /* Do not allow deletion of directories, unless it is a symlink. When the
1129  * path refers to a non-symlink directory, report EPERM as mandated by
1130  * POSIX.1. */
1131 
1132  /* Check if it is a reparse point. If it's not, it's a normal directory. */
1133  if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1134  SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
1135  CloseHandle(handle);
1136  return;
1137  }
1138 
1139  /* Read the reparse point and check if it is a valid symlink. If not, don't
1140  * unlink. */
1141  if (fs__readlink_handle(handle, NULL, NULL) < 0) {
1142  DWORD error = GetLastError();
1144  error = ERROR_ACCESS_DENIED;
1146  CloseHandle(handle);
1147  return;
1148  }
1149  }
1150 
1151  if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
1152  /* Remove read-only attribute */
1153  FILE_BASIC_INFORMATION basic = { 0 };
1154 
1155  basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
1156  FILE_ATTRIBUTE_ARCHIVE;
1157 
1159  &iosb,
1160  &basic,
1161  sizeof basic,
1163  if (!NT_SUCCESS(status)) {
1165  CloseHandle(handle);
1166  return;
1167  }
1168  }
1169 
1170  /* Try to set the delete flag. */
1171  disposition.DeleteFile = TRUE;
1173  &iosb,
1174  &disposition,
1175  sizeof disposition,
1177  if (NT_SUCCESS(status)) {
1179  } else {
1181  }
1182 
1183  CloseHandle(handle);
1184 }
1185 
1186 
1188  /* TODO: use req->mode. */
1189  req->result = _wmkdir(req->file.pathw);
1190  if (req->result == -1) {
1191  req->sys_errno_ = _doserrno;
1192  req->result = req->sys_errno_ == ERROR_INVALID_NAME
1193  ? UV_EINVAL
1194  : uv_translate_sys_error(req->sys_errno_);
1195  }
1196 }
1197 
1199 
1200 /* OpenBSD original: lib/libc/stdio/mktemp.c */
1202  static const WCHAR *tempchars =
1203  L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1204  static const size_t num_chars = 62;
1205  static const size_t num_x = 6;
1206  WCHAR *cp, *ep;
1207  unsigned int tries, i;
1208  size_t len;
1209  uint64_t v;
1210 
1211  len = wcslen(req->file.pathw);
1212  ep = req->file.pathw + len;
1213  if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
1214  SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
1215  return;
1216  }
1217 
1218  tries = TMP_MAX;
1219  do {
1220  if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) {
1221  SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE);
1222  break;
1223  }
1224 
1225  cp = ep - num_x;
1226  for (i = 0; i < num_x; i++) {
1227  *cp++ = tempchars[v % num_chars];
1228  v /= num_chars;
1229  }
1230 
1231  if (func(req)) {
1232  if (req->result >= 0) {
1233  len = strlen(req->path);
1234  wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
1235  }
1236  break;
1237  }
1238  } while (--tries);
1239 
1240  if (tries == 0) {
1241  SET_REQ_RESULT(req, -1);
1242  }
1243 }
1244 
1245 
1247  if (_wmkdir(req->file.pathw) == 0) {
1248  SET_REQ_RESULT(req, 0);
1249  return 1;
1250  } else if (errno != EEXIST) {
1251  SET_REQ_RESULT(req, -1);
1252  return 1;
1253  }
1254 
1255  return 0;
1256 }
1257 
1258 
1261 }
1262 
1263 
1265  HANDLE file;
1266  int fd;
1267 
1268  file = CreateFileW(req->file.pathw,
1269  GENERIC_READ | GENERIC_WRITE,
1270  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1271  NULL,
1272  CREATE_NEW,
1273  FILE_ATTRIBUTE_NORMAL,
1274  NULL);
1275 
1276  if (file == INVALID_HANDLE_VALUE) {
1277  DWORD error;
1278  error = GetLastError();
1279 
1280  /* If the file exists, the main fs__mktemp() function
1281  will retry. If it's another error, we want to stop. */
1282  if (error != ERROR_FILE_EXISTS) {
1284  return 1;
1285  }
1286 
1287  return 0;
1288  }
1289 
1290  fd = _open_osfhandle((intptr_t) file, 0);
1291  if (fd < 0) {
1292  /* The only known failure mode for _open_osfhandle() is EMFILE, in which
1293  * case GetLastError() will return zero. However we'll try to handle other
1294  * errors as well, should they ever occur.
1295  */
1296  if (errno == EMFILE)
1297  SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
1298  else if (GetLastError() != ERROR_SUCCESS)
1299  SET_REQ_WIN32_ERROR(req, GetLastError());
1300  else
1301  SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
1302  CloseHandle(file);
1303  return 1;
1304  }
1305 
1306  SET_REQ_RESULT(req, fd);
1307 
1308  return 1;
1309 }
1310 
1311 
1314 }
1315 
1316 
1318  static const size_t dirents_initial_size = 32;
1319 
1320  HANDLE dir_handle = INVALID_HANDLE_VALUE;
1321 
1322  uv__dirent_t** dirents = NULL;
1323  size_t dirents_size = 0;
1324  size_t dirents_used = 0;
1325 
1326  IO_STATUS_BLOCK iosb;
1327  NTSTATUS status;
1328 
1329  /* Buffer to hold directory entries returned by NtQueryDirectoryFile.
1330  * It's important that this buffer can hold at least one entry, regardless
1331  * of the length of the file names present in the enumerated directory.
1332  * A file name is at most 256 WCHARs long.
1333  * According to MSDN, the buffer must be aligned at an 8-byte boundary.
1334  */
1335 #if _MSC_VER
1336  __declspec(align(8)) char buffer[8192];
1337 #else
1338  __attribute__ ((aligned (8))) char buffer[8192];
1339 #endif
1340 
1341  STATIC_ASSERT(sizeof buffer >=
1342  sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR));
1343 
1344  /* Open the directory. */
1345  dir_handle =
1346  CreateFileW(req->file.pathw,
1347  FILE_LIST_DIRECTORY | SYNCHRONIZE,
1348  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1349  NULL,
1350  OPEN_EXISTING,
1351  FILE_FLAG_BACKUP_SEMANTICS,
1352  NULL);
1353  if (dir_handle == INVALID_HANDLE_VALUE)
1354  goto win32_error;
1355 
1356  /* Read the first chunk. */
1357  status = pNtQueryDirectoryFile(dir_handle,
1358  NULL,
1359  NULL,
1360  NULL,
1361  &iosb,
1362  &buffer,
1363  sizeof buffer,
1365  FALSE,
1366  NULL,
1367  TRUE);
1368 
1369  /* If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER.
1370  * This should be reported back as UV_ENOTDIR.
1371  */
1373  goto not_a_directory_error;
1374 
1375  while (NT_SUCCESS(status)) {
1376  char* position = buffer;
1377  size_t next_entry_offset = 0;
1378 
1379  do {
1381  uv__dirent_t* dirent;
1382 
1383  size_t wchar_len;
1384  size_t utf8_len;
1385 
1386  /* Obtain a pointer to the current directory entry. */
1387  position += next_entry_offset;
1389 
1390  /* Fetch the offset to the next directory entry. */
1391  next_entry_offset = info->NextEntryOffset;
1392 
1393  /* Compute the length of the filename in WCHARs. */
1394  wchar_len = info->FileNameLength / sizeof info->FileName[0];
1395 
1396  /* Skip over '.' and '..' entries. It has been reported that
1397  * the SharePoint driver includes the terminating zero byte in
1398  * the filename length. Strip those first.
1399  */
1400  while (wchar_len > 0 && info->FileName[wchar_len - 1] == L'\0')
1401  wchar_len -= 1;
1402 
1403  if (wchar_len == 0)
1404  continue;
1405  if (wchar_len == 1 && info->FileName[0] == L'.')
1406  continue;
1407  if (wchar_len == 2 && info->FileName[0] == L'.' &&
1408  info->FileName[1] == L'.')
1409  continue;
1410 
1411  /* Compute the space required to store the filename as UTF-8. */
1412  utf8_len = WideCharToMultiByte(
1413  CP_UTF8, 0, &info->FileName[0], wchar_len, NULL, 0, NULL, NULL);
1414  if (utf8_len == 0)
1415  goto win32_error;
1416 
1417  /* Resize the dirent array if needed. */
1418  if (dirents_used >= dirents_size) {
1419  size_t new_dirents_size =
1420  dirents_size == 0 ? dirents_initial_size : dirents_size << 1;
1421  uv__dirent_t** new_dirents =
1422  uv__realloc(dirents, new_dirents_size * sizeof *dirents);
1423 
1424  if (new_dirents == NULL)
1425  goto out_of_memory_error;
1426 
1427  dirents_size = new_dirents_size;
1428  dirents = new_dirents;
1429  }
1430 
1431  /* Allocate space for the uv dirent structure. The dirent structure
1432  * includes room for the first character of the filename, but `utf8_len`
1433  * doesn't count the NULL terminator at this point.
1434  */
1435  dirent = uv__malloc(sizeof *dirent + utf8_len);
1436  if (dirent == NULL)
1437  goto out_of_memory_error;
1438 
1439  dirents[dirents_used++] = dirent;
1440 
1441  /* Convert file name to UTF-8. */
1442  if (WideCharToMultiByte(CP_UTF8,
1443  0,
1444  &info->FileName[0],
1445  wchar_len,
1446  &dirent->d_name[0],
1447  utf8_len,
1448  NULL,
1449  NULL) == 0)
1450  goto win32_error;
1451 
1452  /* Add a null terminator to the filename. */
1453  dirent->d_name[utf8_len] = '\0';
1454 
1455  /* Fill out the type field. */
1456  if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE)
1457  dirent->d_type = UV__DT_CHAR;
1458  else if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1459  dirent->d_type = UV__DT_LINK;
1460  else if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1461  dirent->d_type = UV__DT_DIR;
1462  else
1463  dirent->d_type = UV__DT_FILE;
1464  } while (next_entry_offset != 0);
1465 
1466  /* Read the next chunk. */
1467  status = pNtQueryDirectoryFile(dir_handle,
1468  NULL,
1469  NULL,
1470  NULL,
1471  &iosb,
1472  &buffer,
1473  sizeof buffer,
1475  FALSE,
1476  NULL,
1477  FALSE);
1478 
1479  /* After the first pNtQueryDirectoryFile call, the function may return
1480  * STATUS_SUCCESS even if the buffer was too small to hold at least one
1481  * directory entry.
1482  */
1483  if (status == STATUS_SUCCESS && iosb.Information == 0)
1485  }
1486 
1488  goto nt_error;
1489 
1490  CloseHandle(dir_handle);
1491 
1492  /* Store the result in the request object. */
1493  req->ptr = dirents;
1494  if (dirents != NULL)
1495  req->flags |= UV_FS_FREE_PTR;
1496 
1497  SET_REQ_RESULT(req, dirents_used);
1498 
1499  /* `nbufs` will be used as index by uv_fs_scandir_next. */
1500  req->fs.info.nbufs = 0;
1501 
1502  return;
1503 
1504 nt_error:
1506  goto cleanup;
1507 
1508 win32_error:
1509  SET_REQ_WIN32_ERROR(req, GetLastError());
1510  goto cleanup;
1511 
1512 not_a_directory_error:
1513  SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY);
1514  goto cleanup;
1515 
1516 out_of_memory_error:
1517  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
1518  goto cleanup;
1519 
1520 cleanup:
1521  if (dir_handle != INVALID_HANDLE_VALUE)
1522  CloseHandle(dir_handle);
1523  while (dirents_used > 0)
1524  uv__free(dirents[--dirents_used]);
1525  if (dirents != NULL)
1526  uv__free(dirents);
1527 }
1528 
1530  WCHAR* pathw;
1531  size_t len;
1532  const WCHAR* fmt;
1533  WCHAR* find_path;
1534  uv_dir_t* dir;
1535 
1536  pathw = req->file.pathw;
1537  dir = NULL;
1538  find_path = NULL;
1539 
1540  /* Figure out whether path is a file or a directory. */
1541  if (!(GetFileAttributesW(pathw) & FILE_ATTRIBUTE_DIRECTORY)) {
1542  SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY);
1543  goto error;
1544  }
1545 
1546  dir = uv__malloc(sizeof(*dir));
1547  if (dir == NULL) {
1548  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
1549  goto error;
1550  }
1551 
1552  len = wcslen(pathw);
1553 
1554  if (len == 0)
1555  fmt = L"./*";
1556  else if (IS_SLASH(pathw[len - 1]))
1557  fmt = L"%s*";
1558  else
1559  fmt = L"%s\\*";
1560 
1561  find_path = uv__malloc(sizeof(WCHAR) * (len + 4));
1562  if (find_path == NULL) {
1563  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
1564  goto error;
1565  }
1566 
1567  _snwprintf(find_path, len + 3, fmt, pathw);
1568  dir->dir_handle = FindFirstFileW(find_path, &dir->find_data);
1570  find_path = NULL;
1571  if (dir->dir_handle == INVALID_HANDLE_VALUE &&
1572  GetLastError() != ERROR_FILE_NOT_FOUND) {
1573  SET_REQ_WIN32_ERROR(req, GetLastError());
1574  goto error;
1575  }
1576 
1577  dir->need_find_call = FALSE;
1578  req->ptr = dir;
1579  SET_REQ_RESULT(req, 0);
1580  return;
1581 
1582 error:
1583  uv__free(dir);
1585  req->ptr = NULL;
1586 }
1587 
1589  uv_dir_t* dir;
1591  uv__dirent_t dent;
1592  unsigned int dirent_idx;
1593  PWIN32_FIND_DATAW find_data;
1594  unsigned int i;
1595  int r;
1596 
1597  req->flags |= UV_FS_FREE_PTR;
1598  dir = req->ptr;
1599  dirents = dir->dirents;
1600  memset(dirents, 0, dir->nentries * sizeof(*dir->dirents));
1601  find_data = &dir->find_data;
1602  dirent_idx = 0;
1603 
1604  while (dirent_idx < dir->nentries) {
1605  if (dir->need_find_call && FindNextFileW(dir->dir_handle, find_data) == 0) {
1606  if (GetLastError() == ERROR_NO_MORE_FILES)
1607  break;
1608  goto error;
1609  }
1610 
1611  /* Skip "." and ".." entries. */
1612  if (find_data->cFileName[0] == L'.' &&
1613  (find_data->cFileName[1] == L'\0' ||
1614  (find_data->cFileName[1] == L'.' &&
1615  find_data->cFileName[2] == L'\0'))) {
1616  dir->need_find_call = TRUE;
1617  continue;
1618  }
1619 
1620  r = uv__convert_utf16_to_utf8((const WCHAR*) &find_data->cFileName,
1621  -1,
1622  (char**) &dirents[dirent_idx].name);
1623  if (r != 0)
1624  goto error;
1625 
1626  /* Copy file type. */
1627  if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
1628  dent.d_type = UV__DT_DIR;
1629  else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
1630  dent.d_type = UV__DT_LINK;
1631  else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0)
1632  dent.d_type = UV__DT_CHAR;
1633  else
1634  dent.d_type = UV__DT_FILE;
1635 
1636  dirents[dirent_idx].type = uv__fs_get_dirent_type(&dent);
1637  dir->need_find_call = TRUE;
1638  ++dirent_idx;
1639  }
1640 
1641  SET_REQ_RESULT(req, dirent_idx);
1642  return;
1643 
1644 error:
1645  SET_REQ_WIN32_ERROR(req, GetLastError());
1646  for (i = 0; i < dirent_idx; ++i) {
1647  uv__free((char*) dirents[i].name);
1648  dirents[i].name = NULL;
1649  }
1650 }
1651 
1653  uv_dir_t* dir;
1654 
1655  dir = req->ptr;
1656  FindClose(dir->dir_handle);
1657  uv__free(req->ptr);
1658  SET_REQ_RESULT(req, 0);
1659 }
1660 
1661 INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
1662  int do_lstat) {
1663  FILE_ALL_INFORMATION file_info;
1664  FILE_FS_VOLUME_INFORMATION volume_info;
1665  NTSTATUS nt_status;
1666  IO_STATUS_BLOCK io_status;
1667 
1668  nt_status = pNtQueryInformationFile(handle,
1669  &io_status,
1670  &file_info,
1671  sizeof file_info,
1673 
1674  /* Buffer overflow (a warning status code) is expected here. */
1675  if (NT_ERROR(nt_status)) {
1676  SetLastError(pRtlNtStatusToDosError(nt_status));
1677  return -1;
1678  }
1679 
1681  &io_status,
1682  &volume_info,
1683  sizeof volume_info,
1685 
1686  /* Buffer overflow (a warning status code) is expected here. */
1687  if (io_status.Status == STATUS_NOT_IMPLEMENTED) {
1688  statbuf->st_dev = 0;
1689  } else if (NT_ERROR(nt_status)) {
1690  SetLastError(pRtlNtStatusToDosError(nt_status));
1691  return -1;
1692  } else {
1693  statbuf->st_dev = volume_info.VolumeSerialNumber;
1694  }
1695 
1696  /* Todo: st_mode should probably always be 0666 for everyone. We might also
1697  * want to report 0777 if the file is a .exe or a directory.
1698  *
1699  * Currently it's based on whether the 'readonly' attribute is set, which
1700  * makes little sense because the semantics are so different: the 'read-only'
1701  * flag is just a way for a user to protect against accidental deletion, and
1702  * serves no security purpose. Windows uses ACLs for that.
1703  *
1704  * Also people now use uv_fs_chmod() to take away the writable bit for good
1705  * reasons. Windows however just makes the file read-only, which makes it
1706  * impossible to delete the file afterwards, since read-only files can't be
1707  * deleted.
1708  *
1709  * IOW it's all just a clusterfuck and we should think of something that
1710  * makes slightly more sense.
1711  *
1712  * And uv_fs_chmod should probably just fail on windows or be a total no-op.
1713  * There's nothing sensible it can do anyway.
1714  */
1715  statbuf->st_mode = 0;
1716 
1717  /*
1718  * On Windows, FILE_ATTRIBUTE_REPARSE_POINT is a general purpose mechanism
1719  * by which filesystem drivers can intercept and alter file system requests.
1720  *
1721  * The only reparse points we care about are symlinks and mount points, both
1722  * of which are treated as POSIX symlinks. Further, we only care when
1723  * invoked via lstat, which seeks information about the link instead of its
1724  * target. Otherwise, reparse points must be treated as regular files.
1725  */
1726  if (do_lstat &&
1727  (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1728  /*
1729  * If reading the link fails, the reparse point is not a symlink and needs
1730  * to be treated as a regular file. The higher level lstat function will
1731  * detect this failure and retry without do_lstat if appropriate.
1732  */
1733  if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0)
1734  return -1;
1735  statbuf->st_mode |= S_IFLNK;
1736  }
1737 
1738  if (statbuf->st_mode == 0) {
1739  if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1740  statbuf->st_mode |= _S_IFDIR;
1741  statbuf->st_size = 0;
1742  } else {
1743  statbuf->st_mode |= _S_IFREG;
1744  statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart;
1745  }
1746  }
1747 
1748  if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)
1749  statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6);
1750  else
1751  statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
1752  ((_S_IREAD | _S_IWRITE) >> 6);
1753 
1758 
1759  statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart;
1760 
1761  /* st_blocks contains the on-disk allocation size in 512-byte units. */
1762  statbuf->st_blocks =
1763  (uint64_t) file_info.StandardInformation.AllocationSize.QuadPart >> 9;
1764 
1765  statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks;
1766 
1767  /* The st_blksize is supposed to be the 'optimal' number of bytes for reading
1768  * and writing to the disk. That is, for any definition of 'optimal' - it's
1769  * supposed to at least avoid read-update-write behavior when writing to the
1770  * disk.
1771  *
1772  * However nobody knows this and even fewer people actually use this value,
1773  * and in order to fill it out we'd have to make another syscall to query the
1774  * volume for FILE_FS_SECTOR_SIZE_INFORMATION.
1775  *
1776  * Therefore we'll just report a sensible value that's quite commonly okay
1777  * on modern hardware.
1778  *
1779  * 4096 is the minimum required to be compatible with newer Advanced Format
1780  * drives (which have 4096 bytes per physical sector), and to be backwards
1781  * compatible with older drives (which have 512 bytes per physical sector).
1782  */
1783  statbuf->st_blksize = 4096;
1784 
1785  /* Todo: set st_flags to something meaningful. Also provide a wrapper for
1786  * chattr(2).
1787  */
1788  statbuf->st_flags = 0;
1789 
1790  /* Windows has nothing sensible to say about these values, so they'll just
1791  * remain empty.
1792  */
1793  statbuf->st_gid = 0;
1794  statbuf->st_uid = 0;
1795  statbuf->st_rdev = 0;
1796  statbuf->st_gen = 0;
1797 
1798  return 0;
1799 }
1800 
1801 
1802 INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
1803  size_t len = wcslen(pathw);
1804 
1805  /* TODO: ignore namespaced paths. */
1806  if (len > 1 && pathw[len - 2] != L':' &&
1807  (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) {
1808  pathw[len - 1] = '\0';
1809  }
1810 }
1811 
1812 
1814  int do_lstat,
1815  uv_stat_t* statbuf) {
1816  HANDLE handle;
1817  DWORD flags;
1818  DWORD ret;
1819 
1820  flags = FILE_FLAG_BACKUP_SEMANTICS;
1821  if (do_lstat)
1822  flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1823 
1824  handle = CreateFileW(path,
1825  FILE_READ_ATTRIBUTES,
1826  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1827  NULL,
1828  OPEN_EXISTING,
1829  flags,
1830  NULL);
1831 
1833  ret = GetLastError();
1834  else if (fs__stat_handle(handle, statbuf, do_lstat) != 0)
1835  ret = GetLastError();
1836  else
1837  ret = 0;
1838 
1839  CloseHandle(handle);
1840  return ret;
1841 }
1842 
1843 
1844 INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
1845  DWORD error;
1846 
1847  error = fs__stat_impl_from_path(req->file.pathw, do_lstat, &req->statbuf);
1848  if (error != 0) {
1849  if (do_lstat &&
1851  error == ERROR_NOT_A_REPARSE_POINT)) {
1852  /* We opened a reparse point but it was not a symlink. Try again. */
1853  fs__stat_impl(req, 0);
1854  } else {
1855  /* Stat failed. */
1857  }
1858 
1859  return;
1860  }
1861 
1862  req->ptr = &req->statbuf;
1863  req->result = 0;
1864 }
1865 
1866 
1867 static void fs__stat(uv_fs_t* req) {
1868  fs__stat_prepare_path(req->file.pathw);
1869  fs__stat_impl(req, 0);
1870 }
1871 
1872 
1873 static void fs__lstat(uv_fs_t* req) {
1874  fs__stat_prepare_path(req->file.pathw);
1875  fs__stat_impl(req, 1);
1876 }
1877 
1878 
1879 static void fs__fstat(uv_fs_t* req) {
1880  int fd = req->file.fd;
1881  HANDLE handle;
1882 
1883  VERIFY_FD(fd, req);
1884 
1885  handle = uv__get_osfhandle(fd);
1886 
1887  if (handle == INVALID_HANDLE_VALUE) {
1888  SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
1889  return;
1890  }
1891 
1892  if (fs__stat_handle(handle, &req->statbuf, 0) != 0) {
1893  SET_REQ_WIN32_ERROR(req, GetLastError());
1894  return;
1895  }
1896 
1897  req->ptr = &req->statbuf;
1898  req->result = 0;
1899 }
1900 
1901 
1902 static void fs__rename(uv_fs_t* req) {
1903  if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
1904  SET_REQ_WIN32_ERROR(req, GetLastError());
1905  return;
1906  }
1907 
1908  SET_REQ_RESULT(req, 0);
1909 }
1910 
1911 
1913  int fd = req->file.fd;
1914  int result;
1915 
1916  VERIFY_FD(fd, req);
1917 
1918  result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1;
1919  if (result == -1) {
1920  SET_REQ_WIN32_ERROR(req, GetLastError());
1921  } else {
1923  }
1924 }
1925 
1926 
1927 static void fs__fsync(uv_fs_t* req) {
1928  fs__sync_impl(req);
1929 }
1930 
1931 
1932 static void fs__fdatasync(uv_fs_t* req) {
1933  fs__sync_impl(req);
1934 }
1935 
1936 
1937 static void fs__ftruncate(uv_fs_t* req) {
1938  int fd = req->file.fd;
1939  HANDLE handle;
1940  struct uv__fd_info_s fd_info = { 0 };
1941  NTSTATUS status;
1942  IO_STATUS_BLOCK io_status;
1944 
1945  VERIFY_FD(fd, req);
1946 
1947  handle = uv__get_osfhandle(fd);
1948 
1949  if (uv__fd_hash_get(fd, &fd_info)) {
1950  if (fd_info.is_directory) {
1951  SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
1952  return;
1953  }
1954 
1955  if (fd_info.mapping != INVALID_HANDLE_VALUE) {
1956  CloseHandle(fd_info.mapping);
1957  }
1958  }
1959 
1960  eof_info.EndOfFile.QuadPart = req->fs.info.offset;
1961 
1963  &io_status,
1964  &eof_info,
1965  sizeof eof_info,
1967 
1968  if (NT_SUCCESS(status)) {
1969  SET_REQ_RESULT(req, 0);
1970  } else {
1972 
1973  if (fd_info.flags) {
1974  CloseHandle(handle);
1975  fd_info.mapping = INVALID_HANDLE_VALUE;
1976  fd_info.size.QuadPart = 0;
1977  fd_info.current_pos.QuadPart = 0;
1978  uv__fd_hash_add(fd, &fd_info);
1979  return;
1980  }
1981  }
1982 
1983  if (fd_info.flags) {
1984  fd_info.size = eof_info.EndOfFile;
1985 
1986  if (fd_info.size.QuadPart == 0) {
1987  fd_info.mapping = INVALID_HANDLE_VALUE;
1988  } else {
1989  DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY |
1990  UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE;
1991  fd_info.mapping = CreateFileMapping(handle,
1992  NULL,
1993  flProtect,
1994  fd_info.size.HighPart,
1995  fd_info.size.LowPart,
1996  NULL);
1997  if (fd_info.mapping == NULL) {
1998  SET_REQ_WIN32_ERROR(req, GetLastError());
1999  CloseHandle(handle);
2000  fd_info.mapping = INVALID_HANDLE_VALUE;
2001  fd_info.size.QuadPart = 0;
2002  fd_info.current_pos.QuadPart = 0;
2003  uv__fd_hash_add(fd, &fd_info);
2004  return;
2005  }
2006  }
2007 
2008  uv__fd_hash_add(fd, &fd_info);
2009  }
2010 }
2011 
2012 
2013 static void fs__copyfile(uv_fs_t* req) {
2014  int flags;
2015  int overwrite;
2016  uv_stat_t statbuf;
2017  uv_stat_t new_statbuf;
2018 
2019  flags = req->fs.info.file_flags;
2020 
2022  SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
2023  return;
2024  }
2025 
2026  overwrite = flags & UV_FS_COPYFILE_EXCL;
2027 
2028  if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) != 0) {
2029  SET_REQ_RESULT(req, 0);
2030  return;
2031  }
2032 
2033  SET_REQ_WIN32_ERROR(req, GetLastError());
2034  if (req->result != UV_EBUSY)
2035  return;
2036 
2037  /* if error UV_EBUSY check if src and dst file are the same */
2038  if (fs__stat_impl_from_path(req->file.pathw, 0, &statbuf) != 0 ||
2039  fs__stat_impl_from_path(req->fs.info.new_pathw, 0, &new_statbuf) != 0) {
2040  return;
2041  }
2042 
2043  if (statbuf.st_dev == new_statbuf.st_dev &&
2044  statbuf.st_ino == new_statbuf.st_ino) {
2045  SET_REQ_RESULT(req, 0);
2046  }
2047 }
2048 
2049 
2050 static void fs__sendfile(uv_fs_t* req) {
2051  int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
2052  size_t length = req->fs.info.bufsml[0].len;
2053  int64_t offset = req->fs.info.offset;
2054  const size_t max_buf_size = 65536;
2055  size_t buf_size = length < max_buf_size ? length : max_buf_size;
2056  int n, result = 0;
2057  int64_t result_offset = 0;
2058  char* buf = (char*) uv__malloc(buf_size);
2059  if (!buf) {
2060  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
2061  }
2062 
2063  if (offset != -1) {
2064  result_offset = _lseeki64(fd_in, offset, SEEK_SET);
2065  }
2066 
2067  if (result_offset == -1) {
2068  result = -1;
2069  } else {
2070  while (length > 0) {
2071  n = _read(fd_in, buf, length < buf_size ? length : buf_size);
2072  if (n == 0) {
2073  break;
2074  } else if (n == -1) {
2075  result = -1;
2076  break;
2077  }
2078 
2079  length -= n;
2080 
2081  n = _write(fd_out, buf, n);
2082  if (n == -1) {
2083  result = -1;
2084  break;
2085  }
2086 
2087  result += n;
2088  }
2089  }
2090 
2091  uv__free(buf);
2092 
2094 }
2095 
2096 
2097 static void fs__access(uv_fs_t* req) {
2098  DWORD attr = GetFileAttributesW(req->file.pathw);
2099 
2100  if (attr == INVALID_FILE_ATTRIBUTES) {
2101  SET_REQ_WIN32_ERROR(req, GetLastError());
2102  return;
2103  }
2104 
2105  /*
2106  * Access is possible if
2107  * - write access wasn't requested,
2108  * - or the file isn't read-only,
2109  * - or it's a directory.
2110  * (Directories cannot be read-only on Windows.)
2111  */
2112  if (!(req->fs.info.mode & W_OK) ||
2113  !(attr & FILE_ATTRIBUTE_READONLY) ||
2114  (attr & FILE_ATTRIBUTE_DIRECTORY)) {
2115  SET_REQ_RESULT(req, 0);
2116  } else {
2117  SET_REQ_WIN32_ERROR(req, UV_EPERM);
2118  }
2119 
2120 }
2121 
2122 
2123 static void fs__chmod(uv_fs_t* req) {
2124  int result = _wchmod(req->file.pathw, req->fs.info.mode);
2126 }
2127 
2128 
2129 static void fs__fchmod(uv_fs_t* req) {
2130  int fd = req->file.fd;
2131  int clear_archive_flag;
2132  HANDLE handle;
2133  NTSTATUS nt_status;
2134  IO_STATUS_BLOCK io_status;
2135  FILE_BASIC_INFORMATION file_info;
2136 
2137  VERIFY_FD(fd, req);
2138 
2139  handle = ReOpenFile(uv__get_osfhandle(fd), FILE_WRITE_ATTRIBUTES, 0, 0);
2140  if (handle == INVALID_HANDLE_VALUE) {
2141  SET_REQ_WIN32_ERROR(req, GetLastError());
2142  return;
2143  }
2144 
2145  nt_status = pNtQueryInformationFile(handle,
2146  &io_status,
2147  &file_info,
2148  sizeof file_info,
2150 
2151  if (!NT_SUCCESS(nt_status)) {
2153  goto fchmod_cleanup;
2154  }
2155 
2156  /* Test if the Archive attribute is cleared */
2157  if ((file_info.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == 0) {
2158  /* Set Archive flag, otherwise setting or clearing the read-only
2159  flag will not work */
2160  file_info.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
2161  nt_status = pNtSetInformationFile(handle,
2162  &io_status,
2163  &file_info,
2164  sizeof file_info,
2166  if (!NT_SUCCESS(nt_status)) {
2168  goto fchmod_cleanup;
2169  }
2170  /* Remeber to clear the flag later on */
2171  clear_archive_flag = 1;
2172  } else {
2173  clear_archive_flag = 0;
2174  }
2175 
2176  if (req->fs.info.mode & _S_IWRITE) {
2177  file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
2178  } else {
2179  file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
2180  }
2181 
2182  nt_status = pNtSetInformationFile(handle,
2183  &io_status,
2184  &file_info,
2185  sizeof file_info,
2187 
2188  if (!NT_SUCCESS(nt_status)) {
2190  goto fchmod_cleanup;
2191  }
2192 
2193  if (clear_archive_flag) {
2194  file_info.FileAttributes &= ~FILE_ATTRIBUTE_ARCHIVE;
2195  if (file_info.FileAttributes == 0) {
2196  file_info.FileAttributes = FILE_ATTRIBUTE_NORMAL;
2197  }
2198  nt_status = pNtSetInformationFile(handle,
2199  &io_status,
2200  &file_info,
2201  sizeof file_info,
2203  if (!NT_SUCCESS(nt_status)) {
2205  goto fchmod_cleanup;
2206  }
2207  }
2208 
2210 fchmod_cleanup:
2211  CloseHandle(handle);
2212 }
2213 
2214 
2215 INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
2216  FILETIME filetime_a, filetime_m;
2217 
2218  TIME_T_TO_FILETIME(atime, &filetime_a);
2219  TIME_T_TO_FILETIME(mtime, &filetime_m);
2220 
2221  if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) {
2222  return -1;
2223  }
2224 
2225  return 0;
2226 }
2227 
2229  double atime,
2230  double mtime,
2231  int do_lutime) {
2232  HANDLE handle;
2233  DWORD flags;
2234  DWORD ret;
2235 
2236  flags = FILE_FLAG_BACKUP_SEMANTICS;
2237  if (do_lutime) {
2238  flags |= FILE_FLAG_OPEN_REPARSE_POINT;
2239  }
2240 
2241  handle = CreateFileW(path,
2242  FILE_WRITE_ATTRIBUTES,
2243  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2244  NULL,
2245  OPEN_EXISTING,
2246  flags,
2247  NULL);
2248 
2249  if (handle == INVALID_HANDLE_VALUE) {
2250  ret = GetLastError();
2251  } else if (fs__utime_handle(handle, atime, mtime) != 0) {
2252  ret = GetLastError();
2253  } else {
2254  ret = 0;
2255  }
2256 
2257  CloseHandle(handle);
2258  return ret;
2259 }
2260 
2261 INLINE static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
2262  DWORD error;
2263 
2264  error = fs__utime_impl_from_path(req->file.pathw,
2265  req->fs.time.atime,
2266  req->fs.time.mtime,
2267  do_lutime);
2268 
2269  if (error != 0) {
2270  if (do_lutime &&
2272  error == ERROR_NOT_A_REPARSE_POINT)) {
2273  /* Opened file is a reparse point but not a symlink. Try again. */
2274  fs__utime_impl(req, 0);
2275  } else {
2276  /* utime failed. */
2278  }
2279 
2280  return;
2281  }
2282 
2283  req->result = 0;
2284 }
2285 
2286 static void fs__utime(uv_fs_t* req) {
2287  fs__utime_impl(req, /* do_lutime */ 0);
2288 }
2289 
2290 
2291 static void fs__futime(uv_fs_t* req) {
2292  int fd = req->file.fd;
2293  HANDLE handle;
2294  VERIFY_FD(fd, req);
2295 
2296  handle = uv__get_osfhandle(fd);
2297 
2298  if (handle == INVALID_HANDLE_VALUE) {
2299  SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
2300  return;
2301  }
2302 
2303  if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
2304  SET_REQ_WIN32_ERROR(req, GetLastError());
2305  return;
2306  }
2307 
2308  req->result = 0;
2309 }
2310 
2311 static void fs__lutime(uv_fs_t* req) {
2312  fs__utime_impl(req, /* do_lutime */ 1);
2313 }
2314 
2315 
2316 static void fs__link(uv_fs_t* req) {
2317  DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL);
2318  if (r == 0) {
2319  SET_REQ_WIN32_ERROR(req, GetLastError());
2320  } else {
2321  req->result = 0;
2322  }
2323 }
2324 
2325 
2326 static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
2327  const WCHAR* new_path) {
2328  HANDLE handle = INVALID_HANDLE_VALUE;
2329  REPARSE_DATA_BUFFER *buffer = NULL;
2330  int created = 0;
2331  int target_len;
2332  int is_absolute, is_long_path;
2333  int needed_buf_size, used_buf_size, used_data_size, path_buf_len;
2334  int start, len, i;
2335  int add_slash;
2336  DWORD bytes;
2337  WCHAR* path_buf;
2338 
2339  target_len = wcslen(path);
2340  is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0;
2341 
2342  if (is_long_path) {
2343  is_absolute = 1;
2344  } else {
2345  is_absolute = target_len >= 3 && IS_LETTER(path[0]) &&
2346  path[1] == L':' && IS_SLASH(path[2]);
2347  }
2348 
2349  if (!is_absolute) {
2350  /* Not supporting relative paths */
2351  SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED);
2352  return;
2353  }
2354 
2355  /* Do a pessimistic calculation of the required buffer size */
2356  needed_buf_size =
2357  FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
2358  JUNCTION_PREFIX_LEN * sizeof(WCHAR) +
2359  2 * (target_len + 2) * sizeof(WCHAR);
2360 
2361  /* Allocate the buffer */
2362  buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size);
2363  if (!buffer) {
2364  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
2365  }
2366 
2367  /* Grab a pointer to the part of the buffer where filenames go */
2368  path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer);
2369  path_buf_len = 0;
2370 
2371  /* Copy the substitute (internal) target path */
2372  start = path_buf_len;
2373 
2374  wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX,
2376  path_buf_len += JUNCTION_PREFIX_LEN;
2377 
2378  add_slash = 0;
2379  for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
2380  if (IS_SLASH(path[i])) {
2381  add_slash = 1;
2382  continue;
2383  }
2384 
2385  if (add_slash) {
2386  path_buf[path_buf_len++] = L'\\';
2387  add_slash = 0;
2388  }
2389 
2390  path_buf[path_buf_len++] = path[i];
2391  }
2392  path_buf[path_buf_len++] = L'\\';
2393  len = path_buf_len - start;
2394 
2395  /* Set the info about the substitute name */
2396  buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR);
2397  buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR);
2398 
2399  /* Insert null terminator */
2400  path_buf[path_buf_len++] = L'\0';
2401 
2402  /* Copy the print name of the target path */
2403  start = path_buf_len;
2404  add_slash = 0;
2405  for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
2406  if (IS_SLASH(path[i])) {
2407  add_slash = 1;
2408  continue;
2409  }
2410 
2411  if (add_slash) {
2412  path_buf[path_buf_len++] = L'\\';
2413  add_slash = 0;
2414  }
2415 
2416  path_buf[path_buf_len++] = path[i];
2417  }
2418  len = path_buf_len - start;
2419  if (len == 2) {
2420  path_buf[path_buf_len++] = L'\\';
2421  len++;
2422  }
2423 
2424  /* Set the info about the print name */
2425  buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR);
2426  buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR);
2427 
2428  /* Insert another null terminator */
2429  path_buf[path_buf_len++] = L'\0';
2430 
2431  /* Calculate how much buffer space was actually used */
2432  used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
2433  path_buf_len * sizeof(WCHAR);
2434  used_data_size = used_buf_size -
2435  FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer);
2436 
2437  /* Put general info in the data buffer */
2438  buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
2439  buffer->ReparseDataLength = used_data_size;
2440  buffer->Reserved = 0;
2441 
2442  /* Create a new directory */
2443  if (!CreateDirectoryW(new_path, NULL)) {
2444  SET_REQ_WIN32_ERROR(req, GetLastError());
2445  goto error;
2446  }
2447  created = 1;
2448 
2449  /* Open the directory */
2450  handle = CreateFileW(new_path,
2451  GENERIC_WRITE,
2452  0,
2453  NULL,
2454  OPEN_EXISTING,
2455  FILE_FLAG_BACKUP_SEMANTICS |
2456  FILE_FLAG_OPEN_REPARSE_POINT,
2457  NULL);
2458  if (handle == INVALID_HANDLE_VALUE) {
2459  SET_REQ_WIN32_ERROR(req, GetLastError());
2460  goto error;
2461  }
2462 
2463  /* Create the actual reparse point */
2464  if (!DeviceIoControl(handle,
2466  buffer,
2467  used_buf_size,
2468  NULL,
2469  0,
2470  &bytes,
2471  NULL)) {
2472  SET_REQ_WIN32_ERROR(req, GetLastError());
2473  goto error;
2474  }
2475 
2476  /* Clean up */
2477  CloseHandle(handle);
2478  uv__free(buffer);
2479 
2480  SET_REQ_RESULT(req, 0);
2481  return;
2482 
2483 error:
2484  uv__free(buffer);
2485 
2486  if (handle != INVALID_HANDLE_VALUE) {
2487  CloseHandle(handle);
2488  }
2489 
2490  if (created) {
2491  RemoveDirectoryW(new_path);
2492  }
2493 }
2494 
2495 
2496 static void fs__symlink(uv_fs_t* req) {
2497  WCHAR* pathw;
2498  WCHAR* new_pathw;
2499  int flags;
2500  int err;
2501 
2502  pathw = req->file.pathw;
2503  new_pathw = req->fs.info.new_pathw;
2504 
2505  if (req->fs.info.file_flags & UV_FS_SYMLINK_JUNCTION) {
2506  fs__create_junction(req, pathw, new_pathw);
2507  return;
2508  }
2509 
2510  if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR)
2512  else
2514 
2515  if (CreateSymbolicLinkW(new_pathw, pathw, flags)) {
2516  SET_REQ_RESULT(req, 0);
2517  return;
2518  }
2519 
2520  /* Something went wrong. We will test if it is because of user-mode
2521  * symlinks.
2522  */
2523  err = GetLastError();
2524  if (err == ERROR_INVALID_PARAMETER &&
2526  /* This system does not support user-mode symlinks. We will clear the
2527  * unsupported flag and retry.
2528  */
2530  fs__symlink(req);
2531  } else {
2533  }
2534 }
2535 
2536 
2537 static void fs__readlink(uv_fs_t* req) {
2538  HANDLE handle;
2539 
2540  handle = CreateFileW(req->file.pathw,
2541  0,
2542  0,
2543  NULL,
2544  OPEN_EXISTING,
2545  FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
2546  NULL);
2547 
2548  if (handle == INVALID_HANDLE_VALUE) {
2549  SET_REQ_WIN32_ERROR(req, GetLastError());
2550  return;
2551  }
2552 
2553  if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) {
2554  SET_REQ_WIN32_ERROR(req, GetLastError());
2555  CloseHandle(handle);
2556  return;
2557  }
2558 
2559  req->flags |= UV_FS_FREE_PTR;
2560  SET_REQ_RESULT(req, 0);
2561 
2562  CloseHandle(handle);
2563 }
2564 
2565 
2566 static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
2567  int r;
2568  DWORD w_realpath_len;
2569  WCHAR* w_realpath_ptr = NULL;
2570  WCHAR* w_realpath_buf;
2571 
2572  w_realpath_len = GetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
2573  if (w_realpath_len == 0) {
2574  return -1;
2575  }
2576 
2577  w_realpath_buf = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
2578  if (w_realpath_buf == NULL) {
2579  SetLastError(ERROR_OUTOFMEMORY);
2580  return -1;
2581  }
2582  w_realpath_ptr = w_realpath_buf;
2583 
2584  if (GetFinalPathNameByHandleW(
2585  handle, w_realpath_ptr, w_realpath_len, VOLUME_NAME_DOS) == 0) {
2586  uv__free(w_realpath_buf);
2587  SetLastError(ERROR_INVALID_HANDLE);
2588  return -1;
2589  }
2590 
2591  /* convert UNC path to long path */
2592  if (wcsncmp(w_realpath_ptr,
2594  UNC_PATH_PREFIX_LEN) == 0) {
2595  w_realpath_ptr += 6;
2596  *w_realpath_ptr = L'\\';
2597  w_realpath_len -= 6;
2598  } else if (wcsncmp(w_realpath_ptr,
2600  LONG_PATH_PREFIX_LEN) == 0) {
2601  w_realpath_ptr += 4;
2602  w_realpath_len -= 4;
2603  } else {
2604  uv__free(w_realpath_buf);
2605  SetLastError(ERROR_INVALID_HANDLE);
2606  return -1;
2607  }
2608 
2609  r = fs__wide_to_utf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL);
2610  uv__free(w_realpath_buf);
2611  return r;
2612 }
2613 
2614 static void fs__realpath(uv_fs_t* req) {
2615  HANDLE handle;
2616 
2617  handle = CreateFileW(req->file.pathw,
2618  0,
2619  0,
2620  NULL,
2621  OPEN_EXISTING,
2622  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
2623  NULL);
2624  if (handle == INVALID_HANDLE_VALUE) {
2625  SET_REQ_WIN32_ERROR(req, GetLastError());
2626  return;
2627  }
2628 
2629  if (fs__realpath_handle(handle, (char**) &req->ptr) == -1) {
2630  CloseHandle(handle);
2631  SET_REQ_WIN32_ERROR(req, GetLastError());
2632  return;
2633  }
2634 
2635  CloseHandle(handle);
2636  req->flags |= UV_FS_FREE_PTR;
2637  SET_REQ_RESULT(req, 0);
2638 }
2639 
2640 
2641 static void fs__chown(uv_fs_t* req) {
2642  req->result = 0;
2643 }
2644 
2645 
2646 static void fs__fchown(uv_fs_t* req) {
2647  req->result = 0;
2648 }
2649 
2650 
2651 static void fs__lchown(uv_fs_t* req) {
2652  req->result = 0;
2653 }
2654 
2655 
2656 static void fs__statfs(uv_fs_t* req) {
2657  uv_statfs_t* stat_fs;
2658  DWORD sectors_per_cluster;
2659  DWORD bytes_per_sector;
2660  DWORD free_clusters;
2661  DWORD total_clusters;
2662  WCHAR* pathw;
2663 
2664  pathw = req->file.pathw;
2665 retry_get_disk_free_space:
2666  if (0 == GetDiskFreeSpaceW(pathw,
2667  &sectors_per_cluster,
2668  &bytes_per_sector,
2669  &free_clusters,
2670  &total_clusters)) {
2671  DWORD err;
2672  WCHAR* fpart;
2673  size_t len;
2674  DWORD ret;
2675  BOOL is_second;
2676 
2677  err = GetLastError();
2678  is_second = pathw != req->file.pathw;
2679  if (err != ERROR_DIRECTORY || is_second) {
2680  if (is_second)
2681  uv__free(pathw);
2682 
2684  return;
2685  }
2686 
2687  len = MAX_PATH + 1;
2688  pathw = uv__malloc(len * sizeof(*pathw));
2689  if (pathw == NULL) {
2690  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
2691  return;
2692  }
2693 retry_get_full_path_name:
2694  ret = GetFullPathNameW(req->file.pathw,
2695  len,
2696  pathw,
2697  &fpart);
2698  if (ret == 0) {
2699  uv__free(pathw);
2701  return;
2702  } else if (ret > len) {
2703  len = ret;
2704  pathw = uv__reallocf(pathw, len * sizeof(*pathw));
2705  if (pathw == NULL) {
2706  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
2707  return;
2708  }
2709  goto retry_get_full_path_name;
2710  }
2711  if (fpart != 0)
2712  *fpart = L'\0';
2713 
2714  goto retry_get_disk_free_space;
2715  }
2716  if (pathw != req->file.pathw) {
2717  uv__free(pathw);
2718  }
2719 
2720  stat_fs = uv__malloc(sizeof(*stat_fs));
2721  if (stat_fs == NULL) {
2722  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
2723  return;
2724  }
2725 
2726  stat_fs->f_type = 0;
2727  stat_fs->f_bsize = bytes_per_sector * sectors_per_cluster;
2728  stat_fs->f_blocks = total_clusters;
2729  stat_fs->f_bfree = free_clusters;
2730  stat_fs->f_bavail = free_clusters;
2731  stat_fs->f_files = 0;
2732  stat_fs->f_ffree = 0;
2733  req->ptr = stat_fs;
2734  req->flags |= UV_FS_FREE_PTR;
2735  SET_REQ_RESULT(req, 0);
2736 }
2737 
2738 
2739 static void uv__fs_work(struct uv__work* w) {
2740  uv_fs_t* req;
2741 
2743  assert(req->type == UV_FS);
2744 
2745 #define XX(uc, lc) case UV_FS_##uc: fs__##lc(req); break;
2746  switch (req->fs_type) {
2747  XX(OPEN, open)
2748  XX(CLOSE, close)
2749  XX(READ, read)
2750  XX(WRITE, write)
2751  XX(COPYFILE, copyfile)
2752  XX(SENDFILE, sendfile)
2753  XX(STAT, stat)
2754  XX(LSTAT, lstat)
2755  XX(FSTAT, fstat)
2756  XX(FTRUNCATE, ftruncate)
2757  XX(UTIME, utime)
2758  XX(FUTIME, futime)
2759  XX(LUTIME, lutime)
2760  XX(ACCESS, access)
2761  XX(CHMOD, chmod)
2762  XX(FCHMOD, fchmod)
2763  XX(FSYNC, fsync)
2764  XX(FDATASYNC, fdatasync)
2765  XX(UNLINK, unlink)
2766  XX(RMDIR, rmdir)
2767  XX(MKDIR, mkdir)
2768  XX(MKDTEMP, mkdtemp)
2769  XX(MKSTEMP, mkstemp)
2770  XX(RENAME, rename)
2771  XX(SCANDIR, scandir)
2772  XX(READDIR, readdir)
2773  XX(OPENDIR, opendir)
2774  XX(CLOSEDIR, closedir)
2775  XX(LINK, link)
2776  XX(SYMLINK, symlink)
2777  XX(READLINK, readlink)
2778  XX(REALPATH, realpath)
2779  XX(CHOWN, chown)
2780  XX(FCHOWN, fchown)
2781  XX(LCHOWN, lchown)
2782  XX(STATFS, statfs)
2783  default:
2784  assert(!"bad uv_fs_type");
2785  }
2786 }
2787 
2788 
2789 static void uv__fs_done(struct uv__work* w, int status) {
2790  uv_fs_t* req;
2791 
2793  uv__req_unregister(req->loop, req);
2794 
2795  if (status == UV_ECANCELED) {
2796  assert(req->result == 0);
2797  req->result = UV_ECANCELED;
2798  }
2799 
2800  req->cb(req);
2801 }
2802 
2803 
2805  if (req == NULL)
2806  return;
2807 
2808  if (req->flags & UV_FS_CLEANEDUP)
2809  return;
2810 
2811  if (req->flags & UV_FS_FREE_PATHS)
2812  uv__free(req->file.pathw);
2813 
2814  if (req->flags & UV_FS_FREE_PTR) {
2815  if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
2817  else if (req->fs_type == UV_FS_READDIR)
2819  else
2820  uv__free(req->ptr);
2821  }
2822 
2823  if (req->fs.info.bufs != req->fs.info.bufsml)
2824  uv__free(req->fs.info.bufs);
2825 
2826  req->path = NULL;
2827  req->file.pathw = NULL;
2828  req->fs.info.new_pathw = NULL;
2829  req->fs.info.bufs = NULL;
2830  req->ptr = NULL;
2831 
2832  req->flags |= UV_FS_CLEANEDUP;
2833 }
2834 
2835 
2836 int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
2837  int mode, uv_fs_cb cb) {
2838  int err;
2839 
2840  INIT(UV_FS_OPEN);
2841  err = fs__capture_path(req, path, NULL, cb != NULL);
2842  if (err) {
2843  return uv_translate_sys_error(err);
2844  }
2845 
2846  req->fs.info.file_flags = flags;
2847  req->fs.info.mode = mode;
2848  POST;
2849 }
2850 
2851 
2853  INIT(UV_FS_CLOSE);
2854  req->file.fd = fd;
2855  POST;
2856 }
2857 
2858 
2860  uv_fs_t* req,
2861  uv_file fd,
2862  const uv_buf_t bufs[],
2863  unsigned int nbufs,
2864  int64_t offset,
2865  uv_fs_cb cb) {
2866  INIT(UV_FS_READ);
2867 
2868  if (bufs == NULL || nbufs == 0)
2869  return UV_EINVAL;
2870 
2871  req->file.fd = fd;
2872 
2873  req->fs.info.nbufs = nbufs;
2874  req->fs.info.bufs = req->fs.info.bufsml;
2875  if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
2876  req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
2877 
2878  if (req->fs.info.bufs == NULL)
2879  return UV_ENOMEM;
2880 
2881  memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
2882 
2883  req->fs.info.offset = offset;
2884  POST;
2885 }
2886 
2887 
2889  uv_fs_t* req,
2890  uv_file fd,
2891  const uv_buf_t bufs[],
2892  unsigned int nbufs,
2893  int64_t offset,
2894  uv_fs_cb cb) {
2895  INIT(UV_FS_WRITE);
2896 
2897  if (bufs == NULL || nbufs == 0)
2898  return UV_EINVAL;
2899 
2900  req->file.fd = fd;
2901 
2902  req->fs.info.nbufs = nbufs;
2903  req->fs.info.bufs = req->fs.info.bufsml;
2904  if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
2905  req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
2906 
2907  if (req->fs.info.bufs == NULL)
2908  return UV_ENOMEM;
2909 
2910  memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
2911 
2912  req->fs.info.offset = offset;
2913  POST;
2914 }
2915 
2916 
2918  uv_fs_cb cb) {
2919  int err;
2920 
2921  INIT(UV_FS_UNLINK);
2922  err = fs__capture_path(req, path, NULL, cb != NULL);
2923  if (err) {
2924  return uv_translate_sys_error(err);
2925  }
2926 
2927  POST;
2928 }
2929 
2930 
2931 int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
2932  uv_fs_cb cb) {
2933  int err;
2934 
2935  INIT(UV_FS_MKDIR);
2936  err = fs__capture_path(req, path, NULL, cb != NULL);
2937  if (err) {
2938  return uv_translate_sys_error(err);
2939  }
2940 
2941  req->fs.info.mode = mode;
2942  POST;
2943 }
2944 
2945 
2947  uv_fs_t* req,
2948  const char* tpl,
2949  uv_fs_cb cb) {
2950  int err;
2951 
2953  err = fs__capture_path(req, tpl, NULL, TRUE);
2954  if (err)
2955  return uv_translate_sys_error(err);
2956 
2957  POST;
2958 }
2959 
2960 
2962  uv_fs_t* req,
2963  const char* tpl,
2964  uv_fs_cb cb) {
2965  int err;
2966 
2968  err = fs__capture_path(req, tpl, NULL, TRUE);
2969  if (err)
2970  return uv_translate_sys_error(err);
2971 
2972  POST;
2973 }
2974 
2975 
2977  int err;
2978 
2979  INIT(UV_FS_RMDIR);
2980  err = fs__capture_path(req, path, NULL, cb != NULL);
2981  if (err) {
2982  return uv_translate_sys_error(err);
2983  }
2984 
2985  POST;
2986 }
2987 
2988 
2989 int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
2990  uv_fs_cb cb) {
2991  int err;
2992 
2994  err = fs__capture_path(req, path, NULL, cb != NULL);
2995  if (err) {
2996  return uv_translate_sys_error(err);
2997  }
2998 
2999  req->fs.info.file_flags = flags;
3000  POST;
3001 }
3002 
3004  uv_fs_t* req,
3005  const char* path,
3006  uv_fs_cb cb) {
3007  int err;
3008 
3010  err = fs__capture_path(req, path, NULL, cb != NULL);
3011  if (err)
3012  return uv_translate_sys_error(err);
3013  POST;
3014 }
3015 
3017  uv_fs_t* req,
3018  uv_dir_t* dir,
3019  uv_fs_cb cb) {
3021 
3022  if (dir == NULL ||
3023  dir->dirents == NULL ||
3024  dir->dir_handle == INVALID_HANDLE_VALUE) {
3025  return UV_EINVAL;
3026  }
3027 
3028  req->ptr = dir;
3029  POST;
3030 }
3031 
3033  uv_fs_t* req,
3034  uv_dir_t* dir,
3035  uv_fs_cb cb) {
3037  if (dir == NULL)
3038  return UV_EINVAL;
3039  req->ptr = dir;
3040  POST;
3041 }
3042 
3043 int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
3044  const char* new_path, uv_fs_cb cb) {
3045  int err;
3046 
3047  INIT(UV_FS_LINK);
3048  err = fs__capture_path(req, path, new_path, cb != NULL);
3049  if (err) {
3050  return uv_translate_sys_error(err);
3051  }
3052 
3053  POST;
3054 }
3055 
3056 
3058  const char* new_path, int flags, uv_fs_cb cb) {
3059  int err;
3060 
3062  err = fs__capture_path(req, path, new_path, cb != NULL);
3063  if (err) {
3064  return uv_translate_sys_error(err);
3065  }
3066 
3067  req->fs.info.file_flags = flags;
3068  POST;
3069 }
3070 
3071 
3073  uv_fs_cb cb) {
3074  int err;
3075 
3077  err = fs__capture_path(req, path, NULL, cb != NULL);
3078  if (err) {
3079  return uv_translate_sys_error(err);
3080  }
3081 
3082  POST;
3083 }
3084 
3085 
3087  uv_fs_cb cb) {
3088  int err;
3089 
3091 
3092  if (!path) {
3093  return UV_EINVAL;
3094  }
3095 
3096  err = fs__capture_path(req, path, NULL, cb != NULL);
3097  if (err) {
3098  return uv_translate_sys_error(err);
3099  }
3100 
3101  POST;
3102 }
3103 
3104 
3105 int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
3106  uv_gid_t gid, uv_fs_cb cb) {
3107  int err;
3108 
3109  INIT(UV_FS_CHOWN);
3110  err = fs__capture_path(req, path, NULL, cb != NULL);
3111  if (err) {
3112  return uv_translate_sys_error(err);
3113  }
3114 
3115  POST;
3116 }
3117 
3118 
3120  uv_gid_t gid, uv_fs_cb cb) {
3121  INIT(UV_FS_FCHOWN);
3122  POST;
3123 }
3124 
3125 
3127  uv_gid_t gid, uv_fs_cb cb) {
3128  int err;
3129 
3130  INIT(UV_FS_LCHOWN);
3131  err = fs__capture_path(req, path, NULL, cb != NULL);
3132  if (err) {
3133  return uv_translate_sys_error(err);
3134  }
3135  POST;
3136 }
3137 
3138 
3140  int err;
3141 
3142  INIT(UV_FS_STAT);
3143  err = fs__capture_path(req, path, NULL, cb != NULL);
3144  if (err) {
3145  return uv_translate_sys_error(err);
3146  }
3147 
3148  POST;
3149 }
3150 
3151 
3153  int err;
3154 
3155  INIT(UV_FS_LSTAT);
3156  err = fs__capture_path(req, path, NULL, cb != NULL);
3157  if (err) {
3158  return uv_translate_sys_error(err);
3159  }
3160 
3161  POST;
3162 }
3163 
3164 
3166  INIT(UV_FS_FSTAT);
3167  req->file.fd = fd;
3168  POST;
3169 }
3170 
3171 
3173  const char* new_path, uv_fs_cb cb) {
3174  int err;
3175 
3176  INIT(UV_FS_RENAME);
3177  err = fs__capture_path(req, path, new_path, cb != NULL);
3178  if (err) {
3179  return uv_translate_sys_error(err);
3180  }
3181 
3182  POST;
3183 }
3184 
3185 
3187  INIT(UV_FS_FSYNC);
3188  req->file.fd = fd;
3189  POST;
3190 }
3191 
3192 
3195  req->file.fd = fd;
3196  POST;
3197 }
3198 
3199 
3203  req->file.fd = fd;
3204  req->fs.info.offset = offset;
3205  POST;
3206 }
3207 
3208 
3210  uv_fs_t* req,
3211  const char* path,
3212  const char* new_path,
3213  int flags,
3214  uv_fs_cb cb) {
3215  int err;
3216 
3218 
3219  if (flags & ~(UV_FS_COPYFILE_EXCL |
3222  return UV_EINVAL;
3223  }
3224 
3225  err = fs__capture_path(req, path, new_path, cb != NULL);
3226 
3227  if (err)
3228  return uv_translate_sys_error(err);
3229 
3230  req->fs.info.file_flags = flags;
3231  POST;
3232 }
3233 
3234 
3236  uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) {
3238  req->file.fd = fd_in;
3239  req->fs.info.fd_out = fd_out;
3240  req->fs.info.offset = in_offset;
3241  req->fs.info.bufsml[0].len = length;
3242  POST;
3243 }
3244 
3245 
3247  uv_fs_t* req,
3248  const char* path,
3249  int flags,
3250  uv_fs_cb cb) {
3251  int err;
3252 
3253  INIT(UV_FS_ACCESS);
3254  err = fs__capture_path(req, path, NULL, cb != NULL);
3255  if (err)
3256  return uv_translate_sys_error(err);
3257 
3258  req->fs.info.mode = flags;
3259  POST;
3260 }
3261 
3262 
3263 int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
3264  uv_fs_cb cb) {
3265  int err;
3266 
3267  INIT(UV_FS_CHMOD);
3268  err = fs__capture_path(req, path, NULL, cb != NULL);
3269  if (err) {
3270  return uv_translate_sys_error(err);
3271  }
3272 
3273  req->fs.info.mode = mode;
3274  POST;
3275 }
3276 
3277 
3279  uv_fs_cb cb) {
3280  INIT(UV_FS_FCHMOD);
3281  req->file.fd = fd;
3282  req->fs.info.mode = mode;
3283  POST;
3284 }
3285 
3286 
3287 int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
3288  double mtime, uv_fs_cb cb) {
3289  int err;
3290 
3291  INIT(UV_FS_UTIME);
3292  err = fs__capture_path(req, path, NULL, cb != NULL);
3293  if (err) {
3294  return uv_translate_sys_error(err);
3295  }
3296 
3297  req->fs.time.atime = atime;
3298  req->fs.time.mtime = mtime;
3299  POST;
3300 }
3301 
3302 
3303 int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
3304  double mtime, uv_fs_cb cb) {
3305  INIT(UV_FS_FUTIME);
3306  req->file.fd = fd;
3307  req->fs.time.atime = atime;
3308  req->fs.time.mtime = mtime;
3309  POST;
3310 }
3311 
3312 int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
3313  double mtime, uv_fs_cb cb) {
3314  int err;
3315 
3316  INIT(UV_FS_LUTIME);
3317  err = fs__capture_path(req, path, NULL, cb != NULL);
3318  if (err) {
3319  return uv_translate_sys_error(err);
3320  }
3321 
3322  req->fs.time.atime = atime;
3323  req->fs.time.mtime = mtime;
3324  POST;
3325 }
3326 
3327 
3329  uv_fs_t* req,
3330  const char* path,
3331  uv_fs_cb cb) {
3332  int err;
3333 
3334  INIT(UV_FS_STATFS);
3335  err = fs__capture_path(req, path, NULL, cb != NULL);
3336  if (err)
3337  return uv_translate_sys_error(err);
3338 
3339  POST;
3340 }
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
Definition: winapi.h:4108
UV__DT_LINK
#define UV__DT_LINK
Definition: win.h:312
UV_FS_FCHOWN
@ UV_FS_FCHOWN
Definition: uv.h:1274
uv__file_symlink_usermode_flag
static int uv__file_symlink_usermode_flag
Definition: win/fs.c:139
TRUE
const BOOL TRUE
Definition: undname.c:48
UV_FS_COPYFILE_EXCL
#define UV_FS_COPYFILE_EXCL
Definition: uv.h:1345
async_greeter_server_with_graceful_shutdown.loop
loop
Definition: async_greeter_server_with_graceful_shutdown.py:59
uv_stat_t::st_rdev
uint64_t st_rdev
Definition: uv.h:352
fs__mkdtemp_func
static int fs__mkdtemp_func(uv_fs_t *req)
Definition: win/fs.c:1246
fs__futime
static void fs__futime(uv_fs_t *req)
Definition: win/fs.c:2291
fs__link
static void fs__link(uv_fs_t *req)
Definition: win/fs.c:2316
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
uv_fs_init
void uv_fs_init(void)
Definition: win/fs.c:144
uv__fd_info_s::current_pos
LARGE_INTEGER current_pos
Definition: fs-fd-hash-inl.h:29
uv_statfs_s::f_blocks
uint64_t f_blocks
Definition: uv.h:1120
uv__fd_hash_get
static INLINE int uv__fd_hash_get(int fd, struct uv__fd_info_s *info)
Definition: fs-fd-hash-inl.h:100
UV_FS_UTIME
@ UV_FS_UTIME
Definition: uv.h:1257
uv__work
Definition: third_party/libuv/include/uv/threadpool.h:30
_FILE_ALL_INFORMATION::InternalInformation
FILE_INTERNAL_INFORMATION InternalInformation
Definition: winapi.h:4309
uv_fs_stat
int uv_fs_stat(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:3139
UV_FS_CLOSE
@ UV_FS_CLOSE
Definition: uv.h:1249
UV__DT_FILE
#define UV__DT_FILE
Definition: win.h:311
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
fs__stat_impl_from_path
static INLINE DWORD fs__stat_impl_from_path(WCHAR *path, int do_lstat, uv_stat_t *statbuf)
Definition: win/fs.c:1813
uv_statfs_s::f_files
uint64_t f_files
Definition: uv.h:1123
_FILE_DIRECTORY_INFORMATION::FileAttributes
ULONG FileAttributes
Definition: winapi.h:4235
fs__readlink_handle
static INLINE int fs__readlink_handle(HANDLE handle, char **target_ptr, uint64_t *target_len_ptr)
Definition: win/fs.c:317
_FILE_BASIC_INFORMATION
Definition: winapi.h:4257
UV_FS_READ
@ UV_FS_READ
Definition: uv.h:1250
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
STATUS_NO_MORE_FILES
#define STATUS_NO_MORE_FILES
Definition: winapi.h:524
cleanup
void cleanup(void)
Definition: bloaty/third_party/zlib/examples/enough.c:182
rmdir
#define rmdir
Definition: test-fs.c:45
POST
#define POST
Definition: win/fs.c:53
uv_fs_chmod
int uv_fs_chmod(uv_loop_t *loop, uv_fs_t *req, const char *path, int mode, uv_fs_cb cb)
Definition: win/fs.c:3263
LONG_PATH_PREFIX
const WCHAR LONG_PATH_PREFIX[]
Definition: win/fs.c:133
find_path
static WCHAR * find_path(WCHAR *env)
Definition: win/process.c:831
memset
return memset(p, 0, total)
uv_fs_readdir
int uv_fs_readdir(uv_loop_t *loop, uv_fs_t *req, uv_dir_t *dir, uv_fs_cb cb)
Definition: win/fs.c:3016
uv_statfs_s::f_bavail
uint64_t f_bavail
Definition: uv.h:1122
uv__fd_info_s::mapping
HANDLE mapping
Definition: fs-fd-hash-inl.h:27
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
uv__fs_work
static void uv__fs_work(struct uv__work *w)
Definition: win/fs.c:2739
fs__realpath
static void fs__realpath(uv_fs_t *req)
Definition: win/fs.c:2614
uv_fs_req_cleanup
void uv_fs_req_cleanup(uv_fs_t *req)
Definition: win/fs.c:2804
fs__realpath_handle
static ssize_t fs__realpath_handle(HANDLE handle, char **realpath_ptr)
Definition: win/fs.c:2566
_FILE_ALL_INFORMATION
Definition: winapi.h:4306
SET_REQ_RESULT
#define SET_REQ_RESULT(req, result_value)
Definition: win/fs.c:70
UV_FS_O_SHORT_LIVED
#define UV_FS_O_SHORT_LIVED
Definition: unix.h:501
fs__readlink
static void fs__readlink(uv_fs_t *req)
Definition: win/fs.c:2537
UV_FS_MKDTEMP
@ UV_FS_MKDTEMP
Definition: uv.h:1267
uv_dir_s
Definition: uv.h:1286
write
#define write
Definition: test-fs.c:47
INIT
#define INIT(subtype)
Definition: win/fs.c:45
cpp.utils.ReadFile
def ReadFile(filename, print_error=True)
Definition: bloaty/third_party/googletest/googlemock/scripts/generator/cpp/utils.py:30
uv__malloc
void * uv__malloc(size_t size)
Definition: uv-common.c:75
pNtQueryVolumeInformationFile
sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile
Definition: winapi.c:34
UV_FS_O_SEQUENTIAL
#define UV_FS_O_SEQUENTIAL
Definition: unix.h:502
_FILE_ALL_INFORMATION::StandardInformation
FILE_STANDARD_INFORMATION StandardInformation
Definition: winapi.h:4308
position
intern position
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:487
scandir
int scandir(const char *maindir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))
Definition: os390-syscalls.c:41
cpp.keywords.ACCESS
ACCESS
Definition: bloaty/third_party/googletest/googlemock/scripts/generator/cpp/keywords.py:38
fs__sync_impl
static INLINE void fs__sync_impl(uv_fs_t *req)
Definition: win/fs.c:1912
uv_stat_t::st_mtim
uv_timespec_t st_mtim
Definition: uv.h:360
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
UV_FS_MKSTEMP
@ UV_FS_MKSTEMP
Definition: uv.h:1282
STATIC_ASSERT
#define STATIC_ASSERT(expr)
Definition: uv-common.h:60
fs__create_junction
static void fs__create_junction(uv_fs_t *req, const WCHAR *path, const WCHAR *new_path)
Definition: win/fs.c:2326
uv_fs_mkstemp
int uv_fs_mkstemp(uv_loop_t *loop, uv_fs_t *req, const char *tpl, uv_fs_cb cb)
Definition: win/fs.c:2961
fs-fd-hash-inl.h
error
grpc_error_handle error
Definition: retry_filter.cc:499
STATUS_SUCCESS
#define STATUS_SUCCESS
Definition: winapi.h:68
uv_fs_lchown
int uv_fs_lchown(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
Definition: win/fs.c:3126
UV_FS_O_FILEMAP
#define UV_FS_O_FILEMAP
Definition: unix.h:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
JUNCTION_PREFIX_LEN
const WCHAR JUNCTION_PREFIX_LEN
Definition: win/fs.c:131
NT_ERROR
#define NT_ERROR(status)
Definition: winapi.h:64
pNtQueryDirectoryFile
sNtQueryDirectoryFile pNtQueryDirectoryFile
Definition: winapi.c:35
_FILE_END_OF_FILE_INFORMATION::EndOfFile
LARGE_INTEGER EndOfFile
Definition: winapi.h:4303
uv__fs_get_dirent_type
uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t *dent)
Definition: uv-common.c:658
_FILE_ALL_INFORMATION::BasicInformation
FILE_BASIC_INFORMATION BasicInformation
Definition: winapi.h:4307
UV_FS_FSYNC
@ UV_FS_FSYNC
Definition: uv.h:1262
uv_stat_t::st_size
uint64_t st_size
Definition: uv.h:354
uv__dirent_t
struct dirent uv__dirent_t
Definition: unix.h:169
_FILE_DISPOSITION_INFORMATION
Definition: winapi.h:4318
UV_FS_LCHOWN
@ UV_FS_LCHOWN
Definition: uv.h:1277
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
UV_FS_O_EXLOCK
#define UV_FS_O_EXLOCK
Definition: unix.h:445
uv_stat_t::st_gen
uint64_t st_gen
Definition: uv.h:358
UV_FS_O_RDONLY
#define UV_FS_O_RDONLY
Definition: unix.h:470
fs__copyfile
static void fs__copyfile(uv_fs_t *req)
Definition: win/fs.c:2013
status
absl::Status status
Definition: rls.cc:251
uv_statfs_s::f_ffree
uint64_t f_ffree
Definition: uv.h:1124
uv_uid_t
uid_t uv_uid_t
Definition: unix.h:167
uv__fd_info_s::size
LARGE_INTEGER size
Definition: fs-fd-hash-inl.h:28
uv_fs_access
int uv_fs_access(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, uv_fs_cb cb)
Definition: win/fs.c:3246
XX
#define XX(uc, lc)
_FILE_DIRECTORY_INFORMATION
Definition: winapi.h:4226
FileFsVolumeInformation
@ FileFsVolumeInformation
Definition: winapi.h:4339
mode
const char int mode
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
setup.name
name
Definition: setup.py:542
uv_fs_cb
void(* uv_fs_cb)(uv_fs_t *req)
Definition: uv.h:325
check_documentation.path
path
Definition: check_documentation.py:57
UV_FS_O_CREAT
#define UV_FS_O_CREAT
Definition: unix.h:406
UV_FS_FTRUNCATE
@ UV_FS_FTRUNCATE
Definition: uv.h:1256
uv_fs_mkdir
int uv_fs_mkdir(uv_loop_t *loop, uv_fs_t *req, const char *path, int mode, uv_fs_cb cb)
Definition: win/fs.c:2931
SYMBOLIC_LINK_FLAG_DIRECTORY
#define SYMBOLIC_LINK_FLAG_DIRECTORY
Definition: winapi.h:4604
mkdtemp
char * mkdtemp(char *path)
Definition: os390-syscalls.c:425
uv_fs_read
int uv_fs_read(uv_loop_t *loop, uv_fs_t *req, uv_file fd, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
Definition: win/fs.c:2859
UV_FS_READLINK
@ UV_FS_READLINK
Definition: uv.h:1272
fs__utime_impl_from_path
static INLINE DWORD fs__utime_impl_from_path(WCHAR *path, double atime, double mtime, int do_lutime)
Definition: win/fs.c:2228
UV_FS_UNLINK
@ UV_FS_UNLINK
Definition: uv.h:1264
container_of
#define container_of(ptr, type, member)
Definition: uv-common.h:57
LONG_PATH_PREFIX_LEN
const WCHAR LONG_PATH_PREFIX_LEN
Definition: win/fs.c:134
pRtlNtStatusToDosError
sRtlNtStatusToDosError pRtlNtStatusToDosError
Definition: winapi.c:30
uv_fs_chown
int uv_fs_chown(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
Definition: win/fs.c:3105
uv__fs_done
static void uv__fs_done(struct uv__work *w, int status)
Definition: win/fs.c:2789
fs__fsync
static void fs__fsync(uv_fs_t *req)
Definition: win/fs.c:1927
fs__mkdtemp
void fs__mkdtemp(uv_fs_t *req)
Definition: win/fs.c:1259
uv_fs_closedir
int uv_fs_closedir(uv_loop_t *loop, uv_fs_t *req, uv_dir_t *dir, uv_fs_cb cb)
Definition: win/fs.c:3032
uv_fs_s
Definition: uv.h:1294
uv_stat_t::st_blksize
uint64_t st_blksize
Definition: uv.h:355
SET_REQ_WIN32_ERROR
#define SET_REQ_WIN32_ERROR(req, sys_errno)
Definition: win/fs.c:79
IS_SLASH
#define IS_SLASH(c)
Definition: win/fs.c:124
_FILE_DIRECTORY_INFORMATION::NextEntryOffset
ULONG NextEntryOffset
Definition: winapi.h:4227
uv__convert_utf16_to_utf8
int uv__convert_utf16_to_utf8(const WCHAR *utf16, int utf16len, char **utf8)
Definition: libuv/src/win/util.c:1236
fs__utime
static void fs__utime(uv_fs_t *req)
Definition: win/fs.c:2286
BOOL
int BOOL
Definition: undname.c:46
uv_stat_t::st_gid
uint64_t st_gid
Definition: uv.h:351
fs__access
static void fs__access(uv_fs_t *req)
Definition: win/fs.c:2097
UV_FS_FUTIME
@ UV_FS_FUTIME
Definition: uv.h:1258
S_IFLNK
#define S_IFLNK
Definition: win.h:68
UV_FS_O_TRUNC
#define UV_FS_O_TRUNC
Definition: unix.h:490
uv_connect_s::cb
UV_REQ_FIELDS uv_connect_cb cb
Definition: uv.h:582
STATUS_NOT_IMPLEMENTED
#define STATUS_NOT_IMPLEMENTED
Definition: winapi.h:684
fs__mkdir
void fs__mkdir(uv_fs_t *req)
Definition: win/fs.c:1187
fs__lchown
static void fs__lchown(uv_fs_t *req)
Definition: win/fs.c:2651
uv_fs_realpath
int uv_fs_realpath(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:3086
UV_FS_O_RDWR
#define UV_FS_O_RDWR
Definition: unix.h:475
uv__fd_info_s::is_directory
BOOLEAN is_directory
Definition: fs-fd-hash-inl.h:26
dirents
static uv_dirent_t dirents[1]
Definition: test-fs-readdir.c:31
uv__fs_mktemp_func
int(* uv__fs_mktemp_func)(uv_fs_t *req)
Definition: win/fs.c:1198
fs__read_filemap
void fs__read_filemap(uv_fs_t *req, struct uv__fd_info_s *fd_info)
Definition: win/fs.c:723
NT_SUCCESS
#define NT_SUCCESS(status)
Definition: winapi.h:52
req-inl.h
uv_fs_ftruncate
int uv_fs_ftruncate(uv_loop_t *loop, uv_fs_t *req, uv_file fd, int64_t offset, uv_fs_cb cb)
Definition: win/fs.c:3200
fs__fchown
static void fs__fchown(uv_fs_t *req)
Definition: win/fs.c:2646
fs__lutime
static void fs__lutime(uv_fs_t *req)
Definition: win/fs.c:2311
TIME_T_TO_FILETIME
#define TIME_T_TO_FILETIME(time, filetime_ptr)
Definition: win/fs.c:116
UV_FS_O_APPEND
#define UV_FS_O_APPEND
Definition: unix.h:401
UV_FS_STAT
@ UV_FS_STAT
Definition: uv.h:1253
fs__fdatasync
static void fs__fdatasync(uv_fs_t *req)
Definition: win/fs.c:1932
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
fs__lstat
static void fs__lstat(uv_fs_t *req)
Definition: win/fs.c:1873
IO_REPARSE_TAG_SYMLINK
#define IO_REPARSE_TAG_SYMLINK
Definition: winapi.h:4518
start
static uint64_t start
Definition: benchmark-pound.c:74
_FILE_DIRECTORY_INFORMATION::FileNameLength
ULONG FileNameLength
Definition: winapi.h:4236
UV_FS_O_RANDOM
#define UV_FS_O_RANDOM
Definition: unix.h:500
fs__closedir
void fs__closedir(uv_fs_t *req)
Definition: win/fs.c:1652
FileBasicInformation
@ FileBasicInformation
Definition: winapi.h:4171
UV_FS_CHMOD
@ UV_FS_CHMOD
Definition: uv.h:1260
ssize_t
intptr_t ssize_t
Definition: win.h:27
fs__write
void fs__write(uv_fs_t *req)
Definition: win/fs.c:1023
uv_fs_mkdtemp
int uv_fs_mkdtemp(uv_loop_t *loop, uv_fs_t *req, const char *tpl, uv_fs_cb cb)
Definition: win/fs.c:2946
STATUS_BUFFER_OVERFLOW
#define STATUS_BUFFER_OVERFLOW
Definition: winapi.h:520
xds_interop_client.int
int
Definition: xds_interop_client.py:113
MIN
#define MIN(a, b)
Definition: win/fs.c:128
fs__open
void fs__open(uv_fs_t *req)
Definition: win/fs.c:418
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
uv_fs_unlink
int uv_fs_unlink(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:2917
fs__utime_impl
static INLINE void fs__utime_impl(uv_fs_t *req, int do_lutime)
Definition: win/fs.c:2261
uv_stat_t::st_ino
uint64_t st_ino
Definition: uv.h:353
_FILE_BASIC_INFORMATION::LastAccessTime
LARGE_INTEGER LastAccessTime
Definition: winapi.h:4259
SET_REQ_SUCCESS
#define SET_REQ_SUCCESS(req)
Definition: req-inl.h:40
uv_fs_futime
int uv_fs_futime(uv_loop_t *loop, uv_fs_t *req, uv_file fd, double atime, double mtime, uv_fs_cb cb)
Definition: win/fs.c:3303
req
static uv_connect_t req
Definition: test-connection-fail.c:30
uv_translate_sys_error
UV_EXTERN int uv_translate_sys_error(int sys_errno)
Definition: unix/core.c:1244
_FILE_DIRECTORY_INFORMATION::FileName
WCHAR FileName[1]
Definition: winapi.h:4237
UV_FS_READDIR
@ UV_FS_READDIR
Definition: uv.h:1279
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
UNC_PATH_PREFIX
const WCHAR UNC_PATH_PREFIX[]
Definition: win/fs.c:136
uv_fs_req_init
static INLINE void uv_fs_req_init(uv_loop_t *loop, uv_fs_t *req, uv_fs_type fs_type, const uv_fs_cb cb)
Definition: win/fs.c:253
ERROR_SYMLINK_NOT_SUPPORTED
#define ERROR_SYMLINK_NOT_SUPPORTED
Definition: winapi.h:4635
WRITE
#define WRITE(byte)
uv_fs_fchown
int uv_fs_fchown(uv_loop_t *loop, uv_fs_t *req, uv_file fd, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
Definition: win/fs.c:3119
basic
Definition: test_winkernel.cpp:35
UV_FS_COPYFILE_FICLONE
#define UV_FS_COPYFILE_FICLONE
Definition: uv.h:1351
_IO_STATUS_BLOCK
Definition: winapi.h:4159
uv__fd_info_s
Definition: fs-fd-hash-inl.h:24
uv_stat_t::st_mode
uint64_t st_mode
Definition: uv.h:348
FSCTL_GET_REPARSE_POINT
#define FSCTL_GET_REPARSE_POINT
Definition: winapi.h:4504
fs__chmod
static void fs__chmod(uv_fs_t *req)
Definition: win/fs.c:2123
fs__readdir
void fs__readdir(uv_fs_t *req)
Definition: win/fs.c:1588
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
fs__wide_to_utf8
static int fs__wide_to_utf8(WCHAR *w_source_ptr, DWORD w_source_len, char **target_ptr, uint64_t *target_len_ptr)
Definition: win/fs.c:268
uv_dirent_s::name
const char * name
Definition: uv.h:1140
UV_FS_O_WRONLY
#define UV_FS_O_WRONLY
Definition: unix.h:495
uv_stat_t::st_ctim
uv_timespec_t st_ctim
Definition: uv.h:361
__attribute__
__attribute__(void) start
uv_stat_t::st_atim
uv_timespec_t st_atim
Definition: uv.h:359
uv_fs_link
int uv_fs_link(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, uv_fs_cb cb)
Definition: win/fs.c:3043
UV_FS_CLEANEDUP
#define UV_FS_CLEANEDUP
Definition: win/fs.c:42
fs__stat
static void fs__stat(uv_fs_t *req)
Definition: win/fs.c:1867
uv_dirent_s::type
uv_dirent_type_t type
Definition: uv.h:1141
close
#define close
Definition: test-fs.c:48
uv_dir_s::nentries
size_t nentries
Definition: uv.h:1288
UV_FS_FREE_PTR
#define UV_FS_FREE_PTR
Definition: win/fs.c:41
UV_FS_LINK
@ UV_FS_LINK
Definition: uv.h:1270
UV_FS_SYMLINK_DIR
#define UV_FS_SYMLINK_DIR
Definition: uv.h:1476
uv__free
void uv__free(void *ptr)
Definition: uv-common.c:81
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
fs__chown
static void fs__chown(uv_fs_t *req)
Definition: win/fs.c:2641
INLINE
#define INLINE
Definition: third_party/libuv/src/win/internal.h:36
SET_REQ_UV_ERROR
#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno)
Definition: win/fs.c:85
UV_FS_O_EXCL
#define UV_FS_O_EXCL
Definition: unix.h:440
fs__stat_impl
static INLINE void fs__stat_impl(uv_fs_t *req, int do_lstat)
Definition: win/fs.c:1844
fs__opendir
void fs__opendir(uv_fs_t *req)
Definition: win/fs.c:1529
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
uv_file
int uv_file
Definition: unix.h:126
uv_fs_utime
int uv_fs_utime(uv_loop_t *loop, uv_fs_t *req, const char *path, double atime, double mtime, uv_fs_cb cb)
Definition: win/fs.c:3287
uv_fs_close
int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file fd, uv_fs_cb cb)
Definition: win/fs.c:2852
uv__realloc
void * uv__realloc(void *ptr, size_t size)
Definition: uv-common.c:96
UV_FS_SYMLINK_JUNCTION
#define UV_FS_SYMLINK_JUNCTION
Definition: uv.h:1482
_FILE_FS_VOLUME_INFORMATION::VolumeSerialNumber
ULONG VolumeSerialNumber
Definition: winapi.h:4354
UV_FS_CLOSEDIR
@ UV_FS_CLOSEDIR
Definition: uv.h:1280
uv_fs_opendir
int uv_fs_opendir(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:3003
uv__reallocf
void * uv__reallocf(void *ptr, size_t size)
Definition: uv-common.c:103
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
UV_FS_O_TEMPORARY
#define UV_FS_O_TEMPORARY
Definition: unix.h:503
uv_stat_t::st_uid
uint64_t st_uid
Definition: uv.h:350
fs__ftruncate
static void fs__ftruncate(uv_fs_t *req)
Definition: win/fs.c:1937
uv_stat_t::st_birthtim
uv_timespec_t st_birthtim
Definition: uv.h:362
UV_FS_LSTAT
@ UV_FS_LSTAT
Definition: uv.h:1254
UV_FS_COPYFILE_FICLONE_FORCE
#define UV_FS_COPYFILE_FICLONE_FORCE
Definition: uv.h:1357
uv_fs_symlink
int uv_fs_symlink(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, int flags, uv_fs_cb cb)
Definition: win/fs.c:3057
fs__stat_prepare_path
static INLINE void fs__stat_prepare_path(WCHAR *pathw)
Definition: win/fs.c:1802
uv_fatal_error
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35
fs__statfs
static void fs__statfs(uv_fs_t *req)
Definition: win/fs.c:2656
bufs
static uv_buf_t bufs[5]
Definition: benchmark-udp-pummel.c:51
uv.h
uv_fs_fdatasync
int uv_fs_fdatasync(uv_loop_t *loop, uv_fs_t *req, uv_file fd, uv_fs_cb cb)
Definition: win/fs.c:3193
FileAllInformation
@ FileAllInformation
Definition: winapi.h:4185
UV_FS_O_DSYNC
#define UV_FS_O_DSYNC
Definition: unix.h:435
pNtSetInformationFile
sNtSetInformationFile pNtSetInformationFile
Definition: winapi.c:33
UV_REQ_INIT
#define UV_REQ_INIT(req, typ)
Definition: uv-common.h:305
uv_stat_t::st_nlink
uint64_t st_nlink
Definition: uv.h:349
uv_statfs_s
Definition: uv.h:1117
uv_dirent_s
Definition: uv.h:1139
VERIFY_FD
#define VERIFY_FD(fd, req)
Definition: win/fs.c:91
_FILE_END_OF_FILE_INFORMATION
Definition: winapi.h:4302
fs__rename
static void fs__rename(uv_fs_t *req)
Definition: win/fs.c:1902
FileDirectoryInformation
@ FileDirectoryInformation
Definition: winapi.h:4168
_IO_STATUS_BLOCK::Information
ULONG_PTR Information
Definition: winapi.h:4164
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1808
UV_FS_FCHMOD
@ UV_FS_FCHMOD
Definition: uv.h:1261
uv_fs_type
uv_fs_type
Definition: uv.h:1245
_FILE_BASIC_INFORMATION::FileAttributes
DWORD FileAttributes
Definition: winapi.h:4262
fs__fchmod
static void fs__fchmod(uv_fs_t *req)
Definition: win/fs.c:2129
FILETIME_TO_TIMESPEC
#define FILETIME_TO_TIMESPEC(ts, filetime)
Definition: win/fs.c:110
UV_FS_OPENDIR
@ UV_FS_OPENDIR
Definition: uv.h:1278
attr
OPENSSL_EXPORT X509_ATTRIBUTE * attr
Definition: x509.h:1666
uv_buf_t
Definition: unix.h:121
FALSE
const BOOL FALSE
Definition: undname.c:47
FileDispositionInformation
@ FileDispositionInformation
Definition: winapi.h:4180
UV_FS_ACCESS
@ UV_FS_ACCESS
Definition: uv.h:1259
read
int read(izstream &zs, T *x, Items items)
Definition: bloaty/third_party/zlib/contrib/iostream2/zstream.h:115
UV_FS_WRITE
@ UV_FS_WRITE
Definition: uv.h:1251
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
_FILE_STANDARD_INFORMATION::AllocationSize
LARGE_INTEGER AllocationSize
Definition: winapi.h:4266
uv__fd_hash_remove
static INLINE int uv__fd_hash_remove(int fd, struct uv__fd_info_s *info)
Definition: fs-fd-hash-inl.h:145
uv__fd_hash_add
static INLINE void uv__fd_hash_add(int fd, struct uv__fd_info_s *info)
Definition: fs-fd-hash-inl.h:115
fs__rmdir
void fs__rmdir(uv_fs_t *req)
Definition: win/fs.c:1094
UV_FS_FREE_PATHS
#define UV_FS_FREE_PATHS
Definition: win/fs.c:40
uv_stat_t
Definition: uv.h:346
fs__symlink
static void fs__symlink(uv_fs_t *req)
Definition: win/fs.c:2496
absl::time_internal::cctz::detail::align
CONSTEXPR_F fields align(second_tag, fields f) noexcept
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h:325
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
UV_FS_COPYFILE
@ UV_FS_COPYFILE
Definition: uv.h:1276
UV_FS_LUTIME
@ UV_FS_LUTIME
Definition: uv.h:1283
_FILE_STANDARD_INFORMATION::NumberOfLinks
ULONG NumberOfLinks
Definition: winapi.h:4268
uv__get_osfhandle
static INLINE HANDLE uv__get_osfhandle(int fd)
Definition: handle-inl.h:166
UV_FS_CHOWN
@ UV_FS_CHOWN
Definition: uv.h:1273
_FILE_BASIC_INFORMATION::CreationTime
LARGE_INTEGER CreationTime
Definition: winapi.h:4258
FSCTL_SET_REPARSE_POINT
#define FSCTL_SET_REPARSE_POINT
Definition: winapi.h:4497
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
uv_fs_readlink
int uv_fs_readlink(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:3072
uv__fs_scandir_cleanup
void uv__fs_scandir_cleanup(uv_fs_t *req)
Definition: uv-common.c:605
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
fix_build_deps.r
r
Definition: fix_build_deps.py:491
uv_stat_t::st_dev
uint64_t st_dev
Definition: uv.h:347
uv_fs_rename
int uv_fs_rename(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, uv_fs_cb cb)
Definition: win/fs.c:3172
uv_statfs_s::f_bsize
uint64_t f_bsize
Definition: uv.h:1119
W_OK
#define W_OK
Definition: win.h:661
uv_stat_t::st_flags
uint64_t st_flags
Definition: uv.h:357
done_write
static void done_write(void *, grpc_error_handle error)
Definition: bad_server_response_test.cc:94
INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE
Definition: bloaty/third_party/zlib/contrib/minizip/iowin32.c:21
UV_FS_SENDFILE
@ UV_FS_SENDFILE
Definition: uv.h:1252
uv__allocation_granularity
static DWORD uv__allocation_granularity
Definition: win/fs.c:141
UV_FS_FDATASYNC
@ UV_FS_FDATASYNC
Definition: uv.h:1263
uv_fs_lstat
int uv_fs_lstat(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:3152
fs__unlink
void fs__unlink(uv_fs_t *req)
Definition: win/fs.c:1100
uv__fd_info_s::flags
int flags
Definition: fs-fd-hash-inl.h:25
_FILE_INTERNAL_INFORMATION::IndexNumber
LARGE_INTEGER IndexNumber
Definition: winapi.h:4274
FileEndOfFileInformation
@ FileEndOfFileInformation
Definition: winapi.h:4187
UV_FS_OPEN
@ UV_FS_OPEN
Definition: uv.h:1248
UV__DT_DIR
#define UV__DT_DIR
Definition: win.h:310
uv__fs_readdir_cleanup
void uv__fs_readdir_cleanup(uv_fs_t *req)
Definition: uv-common.c:694
UV_FS_SCANDIR
@ UV_FS_SCANDIR
Definition: uv.h:1269
UV_FS_RMDIR
@ UV_FS_RMDIR
Definition: uv.h:1265
unlink
#define unlink
Definition: test-fs-copyfile.c:33
fs__mktemp
void fs__mktemp(uv_fs_t *req, uv__fs_mktemp_func func)
Definition: win/fs.c:1201
UV_FS_SYMLINK
@ UV_FS_SYMLINK
Definition: uv.h:1271
open
#define open
Definition: test-fs.c:46
uv_statfs_s::f_bfree
uint64_t f_bfree
Definition: uv.h:1121
UV_FS_O_DIRECT
#define UV_FS_O_DIRECT
Definition: unix.h:424
fs__filemap_ex_filter
LONG fs__filemap_ex_filter(LONG excode, PEXCEPTION_POINTERS pep, int *perror)
Definition: win/fs.c:703
uv_fs_fstat
int uv_fs_fstat(uv_loop_t *loop, uv_fs_t *req, uv_file fd, uv_fs_cb cb)
Definition: win/fs.c:3165
stat
#define stat
Definition: test-fs.c:50
handle
static csh handle
Definition: test_arm_regression.c:16
_FILE_DISPOSITION_INFORMATION::DeleteFile
BOOLEAN DeleteFile
Definition: winapi.h:4319
uv_fs_open
int uv_fs_open(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, int mode, uv_fs_cb cb)
Definition: win/fs.c:2836
fs__scandir
void fs__scandir(uv_fs_t *req)
Definition: win/fs.c:1317
UV_FS_MKDIR
@ UV_FS_MKDIR
Definition: uv.h:1266
UV_FS_O_SYNC
#define UV_FS_O_SYNC
Definition: unix.h:485
_IO_STATUS_BLOCK::Status
NTSTATUS Status
Definition: winapi.h:4161
uv__once_init
void uv__once_init(void)
Definition: win/core.c:314
uv_fs_rmdir
int uv_fs_rmdir(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:2976
fs__fstat
static void fs__fstat(uv_fs_t *req)
Definition: win/fs.c:1879
uv_loop_s
Definition: uv.h:1767
GetFileSizeEx
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize)
flags
uint32_t flags
Definition: retry_filter.cc:632
UNC_PATH_PREFIX_LEN
const WCHAR UNC_PATH_PREFIX_LEN
Definition: win/fs.c:137
internal.h
uv_fs_fchmod
int uv_fs_fchmod(uv_loop_t *loop, uv_fs_t *req, uv_file fd, int mode, uv_fs_cb cb)
Definition: win/fs.c:3278
fs__capture_path
static INLINE int fs__capture_path(uv_fs_t *req, const char *path, const char *new_path, const int copy_path)
Definition: win/fs.c:154
uv_stat_t::st_blocks
uint64_t st_blocks
Definition: uv.h:356
_FILE_BASIC_INFORMATION::ChangeTime
LARGE_INTEGER ChangeTime
Definition: winapi.h:4261
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
uv_fs_scandir
int uv_fs_scandir(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, uv_fs_cb cb)
Definition: win/fs.c:2989
run_microbenchmark.link
def link(txt, tgt)
Definition: run_microbenchmark.py:67
work_req
static uv_work_t work_req
Definition: test-loop-alive.c:32
_FILE_BASIC_INFORMATION::LastWriteTime
LARGE_INTEGER LastWriteTime
Definition: winapi.h:4260
STATUS_INVALID_PARAMETER
#define STATUS_INVALID_PARAMETER
Definition: winapi.h:728
UV_FS_STATFS
@ UV_FS_STATFS
Definition: uv.h:1281
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
uv__fd_hash_init
static INLINE void uv__fd_hash_init(void)
Definition: fs-fd-hash-inl.h:55
uv_fs_write
int uv_fs_write(uv_loop_t *loop, uv_fs_t *req, uv_file fd, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
Definition: win/fs.c:2888
fs__close
void fs__close(uv_fs_t *req)
Definition: win/fs.c:673
__declspec
__declspec(noreturn) void uv_fatal_error(const int errorno
NTSTATUS
LONG NTSTATUS
Definition: win.h:198
UV__DT_CHAR
#define UV__DT_CHAR
Definition: win.h:315
fs__mkstemp
void fs__mkstemp(uv_fs_t *req)
Definition: win/fs.c:1312
read_size
static int read_size
Definition: test-tcp-close-reset.c:48
access
Definition: bloaty/third_party/zlib/examples/zran.c:75
uv_statfs_s::f_type
uint64_t f_type
Definition: uv.h:1118
_FILE_FS_VOLUME_INFORMATION
Definition: winapi.h:4352
handle-inl.h
pNtQueryInformationFile
sNtQueryInformationFile pNtQueryInformationFile
Definition: winapi.c:32
UV_FS_FSTAT
@ UV_FS_FSTAT
Definition: uv.h:1255
fs__mkstemp_func
static int fs__mkstemp_func(uv_fs_t *req)
Definition: win/fs.c:1264
uv_fs_fsync
int uv_fs_fsync(uv_loop_t *loop, uv_fs_t *req, uv_file fd, uv_fs_cb cb)
Definition: win/fs.c:3186
fs__utime_handle
static INLINE int fs__utime_handle(HANDLE handle, double atime, double mtime)
Definition: win/fs.c:2215
uv_fs_lutime
int uv_fs_lutime(uv_loop_t *loop, uv_fs_t *req, const char *path, double atime, double mtime, uv_fs_cb cb)
Definition: win/fs.c:3312
SEEK_SET
#define SEEK_SET
Definition: bloaty/third_party/zlib/contrib/minizip/zip.c:88
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
uv_fs_copyfile
int uv_fs_copyfile(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, int flags, uv_fs_cb cb)
Definition: win/fs.c:3209
uv_gid_t
gid_t uv_gid_t
Definition: unix.h:166
fs__stat_handle
static INLINE int fs__stat_handle(HANDLE handle, uv_stat_t *statbuf, int do_lstat)
Definition: win/fs.c:1661
IS_LETTER
#define IS_LETTER(c)
Definition: win/fs.c:125
uv_fs_statfs
int uv_fs_statfs(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: win/fs.c:3328
fs__sendfile
static void fs__sendfile(uv_fs_t *req)
Definition: win/fs.c:2050
errno.h
_FILE_STANDARD_INFORMATION::EndOfFile
LARGE_INTEGER EndOfFile
Definition: winapi.h:4267
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
uv__req_unregister
#define uv__req_unregister(loop, req)
Definition: uv-common.h:213
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
UV_FS_REALPATH
@ UV_FS_REALPATH
Definition: uv.h:1275
fs__write_filemap
void fs__write_filemap(uv_fs_t *req, HANDLE file, struct uv__fd_info_s *fd_info)
Definition: win/fs.c:898
JUNCTION_PREFIX
const WCHAR JUNCTION_PREFIX[]
Definition: win/fs.c:130
fs__read
void fs__read(uv_fs_t *req)
Definition: win/fs.c:820
uv_dir_s::dirents
uv_dirent_t * dirents
Definition: uv.h:1287
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
uv__random_rtlgenrandom
int uv__random_rtlgenrandom(void *buf, size_t buflen)
Definition: libuv/src/win/util.c:1867
UV_FS_RENAME
@ UV_FS_RENAME
Definition: uv.h:1268
uv_fs_sendfile
int uv_fs_sendfile(uv_loop_t *loop, uv_fs_t *req, uv_file fd_out, uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb)
Definition: win/fs.c:3235


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:25