fs-event.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 <errno.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "uv.h"
28 #include "internal.h"
29 #include "handle-inl.h"
30 #include "req-inl.h"
31 
32 
33 const unsigned int uv_directory_watcher_buffer_size = 4096;
34 
35 
38  assert(handle->dir_handle != INVALID_HANDLE_VALUE);
39  assert(!handle->req_pending);
40 
41  memset(&(handle->req.u.io.overlapped), 0,
42  sizeof(handle->req.u.io.overlapped));
43  if (!ReadDirectoryChangesW(handle->dir_handle,
44  handle->buffer,
46  (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
47  FILE_NOTIFY_CHANGE_FILE_NAME |
48  FILE_NOTIFY_CHANGE_DIR_NAME |
49  FILE_NOTIFY_CHANGE_ATTRIBUTES |
50  FILE_NOTIFY_CHANGE_SIZE |
51  FILE_NOTIFY_CHANGE_LAST_WRITE |
52  FILE_NOTIFY_CHANGE_LAST_ACCESS |
53  FILE_NOTIFY_CHANGE_CREATION |
54  FILE_NOTIFY_CHANGE_SECURITY,
55  NULL,
56  &handle->req.u.io.overlapped,
57  NULL)) {
58  /* Make this req pending reporting an error. */
59  SET_REQ_ERROR(&handle->req, GetLastError());
61  }
62 
63  handle->req_pending = 1;
64 }
65 
66 static void uv_relative_path(const WCHAR* filename,
67  const WCHAR* dir,
68  WCHAR** relpath) {
69  size_t relpathlen;
70  size_t filenamelen = wcslen(filename);
71  size_t dirlen = wcslen(dir);
72  assert(!_wcsnicmp(filename, dir, dirlen));
73  if (dirlen > 0 && dir[dirlen - 1] == '\\')
74  dirlen--;
75  relpathlen = filenamelen - dirlen - 1;
76  *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR));
77  if (!*relpath)
78  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
79  wcsncpy(*relpath, filename + dirlen + 1, relpathlen);
80  (*relpath)[relpathlen] = L'\0';
81 }
82 
83 static int uv_split_path(const WCHAR* filename, WCHAR** dir,
84  WCHAR** file) {
85  size_t len, i;
86 
87  if (filename == NULL) {
88  if (dir != NULL)
89  *dir = NULL;
90  *file = NULL;
91  return 0;
92  }
93 
94  len = wcslen(filename);
95  i = len;
96  while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
97 
98  if (i == 0) {
99  if (dir) {
100  *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
101  if (!*dir) {
102  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
103  }
104 
105  if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
106  uv__free(*dir);
107  *dir = NULL;
108  return -1;
109  }
110  }
111 
112  *file = wcsdup(filename);
113  } else {
114  if (dir) {
115  *dir = (WCHAR*)uv__malloc((i + 2) * sizeof(WCHAR));
116  if (!*dir) {
117  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
118  }
119  wcsncpy(*dir, filename, i + 1);
120  (*dir)[i + 1] = L'\0';
121  }
122 
123  *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR));
124  if (!*file) {
125  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
126  }
127  wcsncpy(*file, filename + i + 1, len - i - 1);
128  (*file)[len - i - 1] = L'\0';
129  }
130 
131  return 0;
132 }
133 
134 
136  uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT);
137  handle->dir_handle = INVALID_HANDLE_VALUE;
138  handle->buffer = NULL;
139  handle->req_pending = 0;
140  handle->filew = NULL;
141  handle->short_filew = NULL;
142  handle->dirw = NULL;
143 
144  UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ);
145  handle->req.data = handle;
146 
147  return 0;
148 }
149 
150 
153  const char* path,
154  unsigned int flags) {
155  int name_size, is_path_dir, size;
156  DWORD attr, last_error;
157  WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
158  WCHAR short_path_buffer[MAX_PATH];
159  WCHAR* short_path, *long_path;
160 
161  if (uv__is_active(handle))
162  return UV_EINVAL;
163 
164  handle->cb = cb;
165  handle->path = uv__strdup(path);
166  if (!handle->path) {
167  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
168  }
169 
171 
172  /* Convert name to UTF16. */
173 
174  name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) *
175  sizeof(WCHAR);
176  pathw = (WCHAR*)uv__malloc(name_size);
177  if (!pathw) {
178  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
179  }
180 
181  if (!MultiByteToWideChar(CP_UTF8,
182  0,
183  path,
184  -1,
185  pathw,
186  name_size / sizeof(WCHAR))) {
187  return uv_translate_sys_error(GetLastError());
188  }
189 
190  /* Determine whether path is a file or a directory. */
191  attr = GetFileAttributesW(pathw);
192  if (attr == INVALID_FILE_ATTRIBUTES) {
193  last_error = GetLastError();
194  goto error;
195  }
196 
197  is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
198 
199  if (is_path_dir) {
200  /* path is a directory, so that's the directory that we will watch. */
201 
202  /* Convert to long path. */
203  size = GetLongPathNameW(pathw, NULL, 0);
204 
205  if (size) {
206  long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
207  if (!long_path) {
208  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
209  }
210 
211  size = GetLongPathNameW(pathw, long_path, size);
212  if (size) {
213  long_path[size] = '\0';
214  } else {
216  long_path = NULL;
217  }
218 
219  if (long_path) {
220  uv__free(pathw);
221  pathw = long_path;
222  }
223  }
224 
225  dir_to_watch = pathw;
226  } else {
227  /*
228  * path is a file. So we split path into dir & file parts, and
229  * watch the dir directory.
230  */
231 
232  /* Convert to short path. */
233  if (GetShortPathNameW(pathw,
234  short_path_buffer,
235  ARRAY_SIZE(short_path_buffer))) {
236  short_path = short_path_buffer;
237  } else {
238  short_path = NULL;
239  }
240 
241  if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
242  last_error = GetLastError();
243  goto error;
244  }
245 
246  if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
247  last_error = GetLastError();
248  goto error;
249  }
250 
251  dir_to_watch = dir;
252  uv__free(pathw);
253  pathw = NULL;
254  }
255 
256  handle->dir_handle = CreateFileW(dir_to_watch,
257  FILE_LIST_DIRECTORY,
258  FILE_SHARE_READ | FILE_SHARE_DELETE |
259  FILE_SHARE_WRITE,
260  NULL,
261  OPEN_EXISTING,
262  FILE_FLAG_BACKUP_SEMANTICS |
263  FILE_FLAG_OVERLAPPED,
264  NULL);
265 
266  if (dir) {
267  uv__free(dir);
268  dir = NULL;
269  }
270 
271  if (handle->dir_handle == INVALID_HANDLE_VALUE) {
272  last_error = GetLastError();
273  goto error;
274  }
275 
276  if (CreateIoCompletionPort(handle->dir_handle,
277  handle->loop->iocp,
278  (ULONG_PTR)handle,
279  0) == NULL) {
280  last_error = GetLastError();
281  goto error;
282  }
283 
284  if (!handle->buffer) {
286  }
287  if (!handle->buffer) {
288  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
289  }
290 
291  memset(&(handle->req.u.io.overlapped), 0,
292  sizeof(handle->req.u.io.overlapped));
293 
294  if (!ReadDirectoryChangesW(handle->dir_handle,
295  handle->buffer,
298  FILE_NOTIFY_CHANGE_FILE_NAME |
299  FILE_NOTIFY_CHANGE_DIR_NAME |
300  FILE_NOTIFY_CHANGE_ATTRIBUTES |
301  FILE_NOTIFY_CHANGE_SIZE |
302  FILE_NOTIFY_CHANGE_LAST_WRITE |
303  FILE_NOTIFY_CHANGE_LAST_ACCESS |
304  FILE_NOTIFY_CHANGE_CREATION |
305  FILE_NOTIFY_CHANGE_SECURITY,
306  NULL,
307  &handle->req.u.io.overlapped,
308  NULL)) {
309  last_error = GetLastError();
310  goto error;
311  }
312 
313  assert(is_path_dir ? pathw != NULL : pathw == NULL);
314  handle->dirw = pathw;
315  handle->req_pending = 1;
316  return 0;
317 
318 error:
319  if (handle->path) {
320  uv__free(handle->path);
321  handle->path = NULL;
322  }
323 
324  if (handle->filew) {
325  uv__free(handle->filew);
326  handle->filew = NULL;
327  }
328 
329  if (handle->short_filew) {
330  uv__free(handle->short_filew);
331  handle->short_filew = NULL;
332  }
333 
334  uv__free(pathw);
335 
336  if (handle->dir_handle != INVALID_HANDLE_VALUE) {
337  CloseHandle(handle->dir_handle);
338  handle->dir_handle = INVALID_HANDLE_VALUE;
339  }
340 
341  if (handle->buffer) {
342  uv__free(handle->buffer);
343  handle->buffer = NULL;
344  }
345 
346  if (uv__is_active(handle))
348 
349  return uv_translate_sys_error(last_error);
350 }
351 
352 
354  if (!uv__is_active(handle))
355  return 0;
356 
357  if (handle->dir_handle != INVALID_HANDLE_VALUE) {
358  CloseHandle(handle->dir_handle);
359  handle->dir_handle = INVALID_HANDLE_VALUE;
360  }
361 
363 
364  if (handle->filew) {
365  uv__free(handle->filew);
366  handle->filew = NULL;
367  }
368 
369  if (handle->short_filew) {
370  uv__free(handle->short_filew);
371  handle->short_filew = NULL;
372  }
373 
374  if (handle->path) {
375  uv__free(handle->path);
376  handle->path = NULL;
377  }
378 
379  if (handle->dirw) {
380  uv__free(handle->dirw);
381  handle->dirw = NULL;
382  }
383 
384  return 0;
385 }
386 
387 
388 static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) {
389  size_t str_len;
390 
391  if (str == NULL)
392  return -1;
393 
394  str_len = wcslen(str);
395 
396  /*
397  Since we only care about equality, return early if the strings
398  aren't the same length
399  */
400  if (str_len != (file_name_len / sizeof(WCHAR)))
401  return -1;
402 
403  return _wcsnicmp(str, file_name, str_len);
404 }
405 
406 
409  FILE_NOTIFY_INFORMATION* file_info;
410  int err, sizew, size;
411  char* filename = NULL;
412  WCHAR* filenamew = NULL;
413  WCHAR* long_filenamew = NULL;
414  DWORD offset = 0;
415 
416  assert(req->type == UV_FS_EVENT_REQ);
417  assert(handle->req_pending);
418  handle->req_pending = 0;
419 
420  /* Don't report any callbacks if:
421  * - We're closing, just push the handle onto the endgame queue
422  * - We are not active, just ignore the callback
423  */
424  if (!uv__is_active(handle)) {
425  if (handle->flags & UV_HANDLE_CLOSING) {
427  }
428  return;
429  }
430 
431  file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
432 
433  if (REQ_SUCCESS(req)) {
434  if (req->u.io.overlapped.InternalHigh > 0) {
435  do {
436  file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
437  assert(!filename);
438  assert(!filenamew);
439  assert(!long_filenamew);
440 
441  /*
442  * Fire the event only if we were asked to watch a directory,
443  * or if the filename filter matches.
444  */
445  if (handle->dirw ||
446  file_info_cmp(handle->filew,
447  file_info->FileName,
448  file_info->FileNameLength) == 0 ||
449  file_info_cmp(handle->short_filew,
450  file_info->FileName,
451  file_info->FileNameLength) == 0) {
452 
453  if (handle->dirw) {
454  /*
455  * We attempt to resolve the long form of the file name explicitly.
456  * We only do this for file names that might still exist on disk.
457  * If this fails, we use the name given by ReadDirectoryChangesW.
458  * This may be the long form or the 8.3 short name in some cases.
459  */
460  if (file_info->Action != FILE_ACTION_REMOVED &&
461  file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
462  /* Construct a full path to the file. */
463  size = wcslen(handle->dirw) +
464  file_info->FileNameLength / sizeof(WCHAR) + 2;
465 
466  filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
467  if (!filenamew) {
468  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
469  }
470 
471  _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
472  file_info->FileNameLength / (DWORD)sizeof(WCHAR),
473  file_info->FileName);
474 
475  filenamew[size - 1] = L'\0';
476 
477  /* Convert to long name. */
478  size = GetLongPathNameW(filenamew, NULL, 0);
479 
480  if (size) {
481  long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
482  if (!long_filenamew) {
483  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
484  }
485 
486  size = GetLongPathNameW(filenamew, long_filenamew, size);
487  if (size) {
488  long_filenamew[size] = '\0';
489  } else {
490  uv__free(long_filenamew);
491  long_filenamew = NULL;
492  }
493  }
494 
495  uv__free(filenamew);
496 
497  if (long_filenamew) {
498  /* Get the file name out of the long path. */
499  uv_relative_path(long_filenamew,
500  handle->dirw,
501  &filenamew);
502  uv__free(long_filenamew);
503  long_filenamew = filenamew;
504  sizew = -1;
505  } else {
506  /* We couldn't get the long filename, use the one reported. */
507  filenamew = file_info->FileName;
508  sizew = file_info->FileNameLength / sizeof(WCHAR);
509  }
510  } else {
511  /*
512  * Removed or renamed events cannot be resolved to the long form.
513  * We therefore use the name given by ReadDirectoryChangesW.
514  * This may be the long form or the 8.3 short name in some cases.
515  */
516  filenamew = file_info->FileName;
517  sizew = file_info->FileNameLength / sizeof(WCHAR);
518  }
519  } else {
520  /* We already have the long name of the file, so just use it. */
521  filenamew = handle->filew;
522  sizew = -1;
523  }
524 
525  /* Convert the filename to utf8. */
526  uv__convert_utf16_to_utf8(filenamew, sizew, &filename);
527 
528  switch (file_info->Action) {
529  case FILE_ACTION_ADDED:
530  case FILE_ACTION_REMOVED:
531  case FILE_ACTION_RENAMED_OLD_NAME:
532  case FILE_ACTION_RENAMED_NEW_NAME:
533  handle->cb(handle, filename, UV_RENAME, 0);
534  break;
535 
536  case FILE_ACTION_MODIFIED:
537  handle->cb(handle, filename, UV_CHANGE, 0);
538  break;
539  }
540 
542  filename = NULL;
543  uv__free(long_filenamew);
544  long_filenamew = NULL;
545  filenamew = NULL;
546  }
547 
548  offset = file_info->NextEntryOffset;
549  } while (offset && !(handle->flags & UV_HANDLE_CLOSING));
550  } else {
551  handle->cb(handle, NULL, UV_CHANGE, 0);
552  }
553  } else {
554  err = GET_REQ_ERROR(req);
555  handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
556  }
557 
558  if (!(handle->flags & UV_HANDLE_CLOSING)) {
560  } else {
562  }
563 }
564 
565 
568 
570 
571  if (!handle->req_pending) {
573  }
574 
575 }
576 
577 
579  if ((handle->flags & UV_HANDLE_CLOSING) && !handle->req_pending) {
580  assert(!(handle->flags & UV_HANDLE_CLOSED));
581 
582  if (handle->buffer) {
583  uv__free(handle->buffer);
584  handle->buffer = NULL;
585  }
586 
588  }
589 }
uv__is_active
#define uv__is_active(h)
Definition: uv-common.h:235
xds_interop_client.str
str
Definition: xds_interop_client.py:487
TRUE
const BOOL TRUE
Definition: undname.c:48
async_greeter_server_with_graceful_shutdown.loop
loop
Definition: async_greeter_server_with_graceful_shutdown.py:59
REQ_SUCCESS
#define REQ_SUCCESS(req)
Definition: req-inl.h:46
uv_fs_event_s
Definition: uv.h:1533
filename
const char * filename
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
UV_HANDLE_CLOSED
@ UV_HANDLE_CLOSED
Definition: uv-common.h:67
make_grpcio_tools.long_path
def long_path(path)
Definition: make_grpcio_tools.py:131
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
memset
return memset(p, 0, total)
uv__malloc
void * uv__malloc(size_t size)
Definition: uv-common.c:75
string.h
error
grpc_error_handle error
Definition: retry_filter.cc:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
uv__handle_close
#define uv__handle_close(handle)
Definition: handle-inl.h:76
GET_REQ_ERROR
#define GET_REQ_ERROR(req)
Definition: req-inl.h:49
check_documentation.path
path
Definition: check_documentation.py:57
uv_split_path
static int uv_split_path(const WCHAR *filename, WCHAR **dir, WCHAR **file)
Definition: fs-event.c:83
uv_want_endgame
static INLINE void uv_want_endgame(uv_loop_t *loop, uv_handle_t *handle)
Definition: handle-inl.h:88
uv_fs_event_stop
int uv_fs_event_stop(uv_fs_event_t *handle)
Definition: fs-event.c:353
uv_process_fs_event_req
void uv_process_fs_event_req(uv_loop_t *loop, uv_req_t *req, uv_fs_event_t *handle)
Definition: fs-event.c:407
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
req-inl.h
uv__handle_closing
#define uv__handle_closing(handle)
Definition: handle-inl.h:63
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
SET_REQ_ERROR
#define SET_REQ_ERROR(req, error)
Definition: req-inl.h:34
uv__strdup
char * uv__strdup(const char *s)
Definition: uv-common.c:55
uv_fs_event_endgame
void uv_fs_event_endgame(uv_loop_t *loop, uv_fs_event_t *handle)
Definition: fs-event.c:578
uv_fs_event_start
int uv_fs_event_start(uv_fs_event_t *handle, uv_fs_event_cb cb, const char *path, unsigned int flags)
Definition: fs-event.c:151
UV_RENAME
@ UV_RENAME
Definition: uv.h:1528
uv__free
void uv__free(void *ptr)
Definition: uv-common.c:81
uv_relative_path
static void uv_relative_path(const WCHAR *filename, const WCHAR *dir, WCHAR **relpath)
Definition: fs-event.c:66
uv__handle_init
#define uv__handle_init(loop_, h, type_)
Definition: uv-common.h:284
UV_CHANGE
@ UV_CHANGE
Definition: uv.h:1529
uv_insert_pending_req
static INLINE void uv_insert_pending_req(uv_loop_t *loop, uv_req_t *req)
Definition: req-inl.h:90
uv_fatal_error
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35
uv.h
UV_REQ_INIT
#define UV_REQ_INIT(req, typ)
Definition: uv-common.h:305
UV_HANDLE_CLOSING
@ UV_HANDLE_CLOSING
Definition: uv-common.h:66
file_info_cmp
static int file_info_cmp(WCHAR *str, WCHAR *file_name, size_t file_name_len)
Definition: fs-event.c:388
attr
OPENSSL_EXPORT X509_ATTRIBUTE * attr
Definition: x509.h:1666
FALSE
const BOOL FALSE
Definition: undname.c:47
UV_FS_EVENT_RECURSIVE
@ UV_FS_EVENT_RECURSIVE
Definition: uv.h:1607
uv_fs_event_queue_readdirchanges
static void uv_fs_event_queue_readdirchanges(uv_loop_t *loop, uv_fs_event_t *handle)
Definition: fs-event.c:36
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
uv_fs_event_init
int uv_fs_event_init(uv_loop_t *loop, uv_fs_event_t *handle)
Definition: fs-event.c:135
uv_fs_event_cb
void(* uv_fs_event_cb)(uv_fs_event_t *handle, const char *filename, int events, int status)
Definition: uv.h:366
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE
Definition: bloaty/third_party/zlib/contrib/minizip/iowin32.c:21
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
uv_loop_s
Definition: uv.h:1767
uv_directory_watcher_buffer_size
const unsigned int uv_directory_watcher_buffer_size
Definition: fs-event.c:33
internal.h
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
uv__handle_start
#define uv__handle_start(h)
Definition: uv-common.h:241
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
uv_fs_event_close
void uv_fs_event_close(uv_loop_t *loop, uv_fs_event_t *handle)
Definition: fs-event.c:566
handle-inl.h
uv__handle_stop
#define uv__handle_stop(h)
Definition: uv-common.h:249
uv_req_s
Definition: uv.h:404
errno.h
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:22