コード例 #1
0
ファイル: process.c プロジェクト: HenryRawas/libuv
wchar_t* make_program_args(char** args, int verbatim_arguments) {
  wchar_t* dst;
  wchar_t* ptr;
  char** arg;
  size_t size = 0;
  size_t len;
  int arg_count = 0;
  wchar_t* buffer;
  int arg_size;
  int buffer_size = 0;

  /* Count the required size. */
  for (arg = args; *arg; arg++) {
    arg_size = uv_utf8_to_utf16(*arg, NULL, 0) * sizeof(wchar_t);
    size += arg_size;
    buffer_size = arg_size > buffer_size ? arg_size : buffer_size;
    arg_count++;
  }

  /* Adjust for potential quotes. Also assume the worst-case scenario
  /* that every character needs escaping, so we need twice as much space. */
  size = size * 2 + arg_count * 2;

  dst = (wchar_t*)malloc(size);
  if (!dst) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  buffer = (wchar_t*)malloc(buffer_size);
  if (!buffer) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  ptr = dst;
  for (arg = args; *arg; arg++) {
    len = uv_utf8_to_utf16(*arg, buffer, (size_t)(size - (ptr - dst)));
    if (!len) {
      goto error;
    }
    if (verbatim_arguments) {
      wcscpy(ptr, buffer);
      ptr += len - 1;
    } else {
      ptr = quote_cmd_arg(buffer, ptr);
    }
    *ptr++ = *(arg + 1) ? L' ' : L'\0';
  }

  free(buffer);
  return dst;

error:
  free(dst);
  free(buffer);
  return NULL;
}
コード例 #2
0
ファイル: util.c プロジェクト: 5y/node
int uv_set_process_title(const char* title) {
  int err;
  int length;
  WCHAR* title_w = NULL;

  uv__once_init();

  /* Find out how big the buffer for the wide-char title must be */
  length = uv_utf8_to_utf16(title, NULL, 0);
  if (!length) {
    err = GetLastError();
    goto done;
  }

  /* Convert to wide-char string */
  title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
  if (!title_w) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  length = uv_utf8_to_utf16(title, title_w, length);
  if (!length) {
    err = GetLastError();
    goto done;
  }

  /* If the title must be truncated insert a \0 terminator there */
  if (length > MAX_TITLE_LENGTH) {
    title_w[MAX_TITLE_LENGTH - 1] = L'\0';
  }

  if (!SetConsoleTitleW(title_w)) {
    err = GetLastError();
    goto done;
  }

  EnterCriticalSection(&process_title_lock);
  free(process_title);
  process_title = strdup(title);
  LeaveCriticalSection(&process_title_lock);

  err = 0;

done:
  free(title_w);
  return uv_translate_sys_error(err);
}
コード例 #3
0
ファイル: util.c プロジェクト: igorzi/libuv
uv_err_t uv_chdir(const char* dir) {
  uv_err_t err;
  wchar_t* utf16Buffer = NULL;
  size_t utf16Size;

  if (!dir) {
    err.code = UV_EINVAL;
    goto done;
  }

  utf16Size = uv_utf8_to_utf16(dir, NULL, 0);
  if (!utf16Size) {
    err = uv__new_sys_error(GetLastError());
    goto done;
  }

  utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * utf16Size);
  if (!utf16Buffer) {
    err.code = UV_ENOMEM;
    goto done;
  }

  if (!uv_utf8_to_utf16(dir, utf16Buffer, utf16Size)) {
    err = uv__new_sys_error(GetLastError());
    goto done;
  }

  if (_wchdir(utf16Buffer) == -1) {
    err = uv__new_sys_error(_doserrno);
    goto done;
  }

  err = uv_ok_;

done:
  if (utf16Buffer) {
    free(utf16Buffer);
  }

  return err;
}
コード例 #4
0
ファイル: dl.c プロジェクト: 4rejin/node
int uv_dlopen(const char* filename, uv_lib_t* lib) {
  wchar_t filename_w[32768];

  lib->handle = NULL;
  lib->errmsg = NULL;

  if (!uv_utf8_to_utf16(filename, filename_w, ARRAY_SIZE(filename_w))) {
    return uv__dlerror(lib, GetLastError());
  }

  lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  if (lib->handle == NULL) {
    return uv__dlerror(lib, GetLastError());
  }

  return 0;
}
コード例 #5
0
ファイル: dl.c プロジェクト: Jonekee/libuv
uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
    wchar_t filename_w[32768];
    HMODULE handle;

    if (!uv_utf8_to_utf16(filename,
                          filename_w,
                          sizeof(filename_w) / sizeof(wchar_t))) {
        return uv__new_sys_error(GetLastError());
    }

    handle = LoadLibraryW(filename_w);
    if (handle == NULL) {
        return uv__new_sys_error(GetLastError());
    }

    *library = handle;
    return uv_ok_;
}
コード例 #6
0
int uv_fs_event_start(uv_fs_event_t* handle,
                      uv_fs_event_cb cb,
                      const char* path,
                      unsigned int flags) {
  int name_size, is_path_dir;
  DWORD attr, last_error;
  WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
  WCHAR short_path[MAX_PATH];

  if (uv__is_active(handle))
    return UV_EINVAL;

  handle->cb = cb;
  handle->path = uv__strdup(path);
  if (!handle->path) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
  }

  uv__handle_start(handle);

  /* Convert name to UTF16. */
  name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR);
  pathw = (WCHAR*)uv__malloc(name_size);
  if (!pathw) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
  }

  if (!uv_utf8_to_utf16(path, pathw,
      name_size / sizeof(WCHAR))) {
    return uv_translate_sys_error(GetLastError());
  }

  /* Determine whether path is a file or a directory. */
  attr = GetFileAttributesW(pathw);
  if (attr == INVALID_FILE_ATTRIBUTES) {
    last_error = GetLastError();
    goto error;
  }

  is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;

  if (is_path_dir) {
     /* path is a directory, so that's the directory that we will watch. */
    handle->dirw = pathw;
    dir_to_watch = pathw;
  } else {
    /*
     * path is a file.  So we split path into dir & file parts, and
     * watch the dir directory.
     */

    /* Convert to short path. */
    if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
      last_error = GetLastError();
      goto error;
    }

    if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
      last_error = GetLastError();
      goto error;
    }

    if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
      last_error = GetLastError();
      goto error;
    }

    dir_to_watch = dir;
    uv__free(pathw);
    pathw = NULL;
  }

  handle->dir_handle = CreateFileW(dir_to_watch,
                                   FILE_LIST_DIRECTORY,
                                   FILE_SHARE_READ | FILE_SHARE_DELETE |
                                     FILE_SHARE_WRITE,
                                   NULL,
                                   OPEN_EXISTING,
                                   FILE_FLAG_BACKUP_SEMANTICS |
                                     FILE_FLAG_OVERLAPPED,
                                   NULL);

  if (dir) {
    uv__free(dir);
    dir = NULL;
  }

  if (handle->dir_handle == INVALID_HANDLE_VALUE) {
    last_error = GetLastError();
    goto error;
  }

  if (CreateIoCompletionPort(handle->dir_handle,
                             handle->loop->iocp,
                             (ULONG_PTR)handle,
                             0) == NULL) {
    last_error = GetLastError();
    goto error;
  }

  if (!handle->buffer) {
    handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size);
  }
  if (!handle->buffer) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
  }

  memset(&(handle->req.u.io.overlapped), 0,
         sizeof(handle->req.u.io.overlapped));

  if (!ReadDirectoryChangesW(handle->dir_handle,
                             handle->buffer,
                             uv_directory_watcher_buffer_size,
                             (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
                             FILE_NOTIFY_CHANGE_FILE_NAME      |
                               FILE_NOTIFY_CHANGE_DIR_NAME     |
                               FILE_NOTIFY_CHANGE_ATTRIBUTES   |
                               FILE_NOTIFY_CHANGE_SIZE         |
                               FILE_NOTIFY_CHANGE_LAST_WRITE   |
                               FILE_NOTIFY_CHANGE_LAST_ACCESS  |
                               FILE_NOTIFY_CHANGE_CREATION     |
                               FILE_NOTIFY_CHANGE_SECURITY,
                             NULL,
                             &handle->req.u.io.overlapped,
                             NULL)) {
    last_error = GetLastError();
    goto error;
  }

  handle->req_pending = 1;
  return 0;

error:
  if (handle->path) {
    uv__free(handle->path);
    handle->path = NULL;
  }

  if (handle->filew) {
    uv__free(handle->filew);
    handle->filew = NULL;
  }

  if (handle->short_filew) {
    uv__free(handle->short_filew);
    handle->short_filew = NULL;
  }

  uv__free(pathw);

  if (handle->dir_handle != INVALID_HANDLE_VALUE) {
    CloseHandle(handle->dir_handle);
    handle->dir_handle = INVALID_HANDLE_VALUE;
  }

  if (handle->buffer) {
    uv__free(handle->buffer);
    handle->buffer = NULL;
  }

  return uv_translate_sys_error(last_error);
}
コード例 #7
0
ファイル: process.c プロジェクト: Ankso/node
/*
 * The way windows takes environment variables is different than what C does;
 * Windows wants a contiguous block of null-terminated strings, terminated
 * with an additional null.
 *
 * Windows has a few "essential" environment variables. winsock will fail
 * to initialize if SYSTEMROOT is not defined; some APIs make reference to
 * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that
 * these get defined if the input environment block does not contain any
 * values for them.
 */
WCHAR* make_program_env(char** env_block) {
  WCHAR* dst;
  WCHAR* ptr;
  char** env;
  int env_len = 1 * sizeof(WCHAR); /* room for closing null */
  int len;
  int i;
  DWORD var_size;

  env_var_t required_vars[] = {
    E_V("SYSTEMROOT"),
    E_V("SYSTEMDRIVE"),
    E_V("TEMP"),
  };

  for (env = env_block; *env; env++) {
    check_required_vars_contains_var(required_vars,
                                     ARRAY_SIZE(required_vars),
                                     *env);
    env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(WCHAR));
  }

  for (i = 0; i < ARRAY_SIZE(required_vars); ++i) {
    if (!required_vars[i].supplied) {
      env_len += required_vars[i].len * sizeof(WCHAR);
      var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0);
      if (var_size == 0) {
        uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
      }
      required_vars[i].value_len = (int)var_size;
      env_len += (int)var_size * sizeof(WCHAR);
    }
  }

  dst = malloc(env_len);
  if (!dst) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  ptr = dst;

  for (env = env_block; *env; env++, ptr += len) {
    len = uv_utf8_to_utf16(*env, ptr, (size_t)(env_len - (ptr - dst)));
    if (!len) {
      free(dst);
      return NULL;
    }
  }

  for (i = 0; i < ARRAY_SIZE(required_vars); ++i) {
    if (!required_vars[i].supplied) {
      wcscpy(ptr, required_vars[i].wide);
      ptr += required_vars[i].len - 1;
      *ptr++ = L'=';
      var_size = GetEnvironmentVariableW(required_vars[i].wide,
                                         ptr,
                                         required_vars[i].value_len);
      if (var_size == 0) {
        uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
      }
      ptr += required_vars[i].value_len;
    }
  }

  *ptr = L'\0';
  return dst;
}
コード例 #8
0
ファイル: getaddrinfo.c プロジェクト: 178620086/Node4Android
/*
 * Entry point for getaddrinfo
 * we convert the UTF-8 strings to UNICODE
 * and save the UNICODE string pointers in the handle
 * We also copy hints so that caller does not need to keep memory until the
 * callback.
 * return UV_OK if a callback will be made
 * return error code if validation fails
 *
 * To minimize allocation we calculate total size required,
 * and copy all structs and referenced strings into the one block.
 * Each size calculation is adjusted to avoid unaligned pointers.
 */
int uv_getaddrinfo(uv_loop_t* loop,
                   uv_getaddrinfo_t* handle,
                   uv_getaddrinfo_cb getaddrinfo_cb,
                   const char* node,
                   const char* service,
                   const struct addrinfo* hints) {
  int nodesize = 0;
  int servicesize = 0;
  int hintssize = 0;
  char* alloc_ptr = NULL;

  if (handle == NULL || getaddrinfo_cb == NULL ||
     (node == NULL && service == NULL)) {
    uv__set_sys_error(loop, WSAEINVAL);
    goto error;
  }

  uv_req_init(loop, (uv_req_t*)handle);

  handle->getaddrinfo_cb = getaddrinfo_cb;
  handle->res = NULL;
  handle->type = UV_GETADDRINFO;
  handle->loop = loop;

  /* calculate required memory size for all input values */
  if (node != NULL) {
    nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t));
    if (nodesize == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
  }

  if (service != NULL) {
    servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
                               sizeof(wchar_t));
    if (servicesize == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
  }
  if (hints != NULL) {
    hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW));
  }

  /* allocate memory for inputs, and partition it as needed */
  alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
  if (!alloc_ptr) {
    uv__set_sys_error(loop, WSAENOBUFS);
    goto error;
  }

  /* save alloc_ptr now so we can free if error */
  handle->alloc = (void*)alloc_ptr;

  /* convert node string to UTF16 into allocated memory and save pointer in */
  /* handle */
  if (node != NULL) {
    handle->node = (wchar_t*)alloc_ptr;
    if (uv_utf8_to_utf16(node,
                         (wchar_t*) alloc_ptr,
                         nodesize / sizeof(wchar_t)) == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
    alloc_ptr += nodesize;
  } else {
    handle->node = NULL;
  }

  /* convert service string to UTF16 into allocated memory and save pointer */
  /* in handle */
  if (service != NULL) {
    handle->service = (wchar_t*)alloc_ptr;
    if (uv_utf8_to_utf16(service,
                         (wchar_t*) alloc_ptr,
                         servicesize / sizeof(wchar_t)) == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
    alloc_ptr += servicesize;
  } else {
    handle->service = NULL;
  }

  /* copy hints to allocated memory and save pointer in handle */
  if (hints != NULL) {
    handle->hints = (struct addrinfoW*)alloc_ptr;
    handle->hints->ai_family = hints->ai_family;
    handle->hints->ai_socktype = hints->ai_socktype;
    handle->hints->ai_protocol = hints->ai_protocol;
    handle->hints->ai_flags = hints->ai_flags;
    handle->hints->ai_addrlen = 0;
    handle->hints->ai_canonname = NULL;
    handle->hints->ai_addr = NULL;
    handle->hints->ai_next = NULL;
  } else {
    handle->hints = NULL;
  }

  /* init request for Post handling */
  uv_req_init(loop, &handle->getadddrinfo_req);
  handle->getadddrinfo_req.data = handle;
  handle->getadddrinfo_req.type = UV_GETADDRINFO_REQ;

  /* Ask thread to run. Treat this as a long operation */
  if (QueueUserWorkItem(&getaddrinfo_thread_proc,
                        handle,
                        WT_EXECUTELONGFUNCTION) == 0) {
    uv__set_sys_error(loop, GetLastError());
    goto error;
  }

  uv_ref(loop);

  return 0;

error:
  if (handle != NULL && handle->alloc != NULL) {
    free(handle->alloc);
  }
  return -1;
}
コード例 #9
0
ファイル: getaddrinfo.c プロジェクト: 353355756/node
/*
 * Entry point for getaddrinfo
 * we convert the UTF-8 strings to UNICODE
 * and save the UNICODE string pointers in the req
 * We also copy hints so that caller does not need to keep memory until the
 * callback.
 * return 0 if a callback will be made
 * return error code if validation fails
 *
 * To minimize allocation we calculate total size required,
 * and copy all structs and referenced strings into the one block.
 * Each size calculation is adjusted to avoid unaligned pointers.
 */
int uv_getaddrinfo(uv_loop_t* loop,
                   uv_getaddrinfo_t* req,
                   uv_getaddrinfo_cb getaddrinfo_cb,
                   const char* node,
                   const char* service,
                   const struct addrinfo* hints) {
  int nodesize = 0;
  int servicesize = 0;
  int hintssize = 0;
  char* alloc_ptr = NULL;
  int err;

  if (req == NULL || getaddrinfo_cb == NULL ||
     (node == NULL && service == NULL)) {
    err = WSAEINVAL;
    goto error;
  }

  uv_req_init(loop, (uv_req_t*)req);

  req->getaddrinfo_cb = getaddrinfo_cb;
  req->res = NULL;
  req->type = UV_GETADDRINFO;
  req->loop = loop;
  req->retcode = 0;

  /* calculate required memory size for all input values */
  if (node != NULL) {
    nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR));
    if (nodesize == 0) {
      err = GetLastError();
      goto error;
    }
  }

  if (service != NULL) {
    servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
                               sizeof(WCHAR));
    if (servicesize == 0) {
      err = GetLastError();
      goto error;
    }
  }
  if (hints != NULL) {
    hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW));
  }

  /* allocate memory for inputs, and partition it as needed */
  alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
  if (!alloc_ptr) {
    err = WSAENOBUFS;
    goto error;
  }

  /* save alloc_ptr now so we can free if error */
  req->alloc = (void*)alloc_ptr;

  /* convert node string to UTF16 into allocated memory and save pointer in */
  /* the reques. */
  if (node != NULL) {
    req->node = (WCHAR*)alloc_ptr;
    if (uv_utf8_to_utf16(node,
                         (WCHAR*) alloc_ptr,
                         nodesize / sizeof(WCHAR)) == 0) {
      err = GetLastError();
      goto error;
    }
    alloc_ptr += nodesize;
  } else {
    req->node = NULL;
  }

  /* convert service string to UTF16 into allocated memory and save pointer */
  /* in the req. */
  if (service != NULL) {
    req->service = (WCHAR*)alloc_ptr;
    if (uv_utf8_to_utf16(service,
                         (WCHAR*) alloc_ptr,
                         servicesize / sizeof(WCHAR)) == 0) {
      err = GetLastError();
      goto error;
    }
    alloc_ptr += servicesize;
  } else {
    req->service = NULL;
  }

  /* copy hints to allocated memory and save pointer in req */
  if (hints != NULL) {
    req->hints = (struct addrinfoW*)alloc_ptr;
    req->hints->ai_family = hints->ai_family;
    req->hints->ai_socktype = hints->ai_socktype;
    req->hints->ai_protocol = hints->ai_protocol;
    req->hints->ai_flags = hints->ai_flags;
    req->hints->ai_addrlen = 0;
    req->hints->ai_canonname = NULL;
    req->hints->ai_addr = NULL;
    req->hints->ai_next = NULL;
  } else {
    req->hints = NULL;
  }

  uv__work_submit(loop,
                  &req->work_req,
                  uv__getaddrinfo_work,
                  uv__getaddrinfo_done);

  uv__req_register(loop, req);

  return 0;

error:
  if (req != NULL && req->alloc != NULL) {
    free(req->alloc);
  }
  return uv_translate_sys_error(err);
}
コード例 #10
0
ファイル: pipe.c プロジェクト: Cycle-Applications/node
void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  uv_loop_t* loop = handle->loop;
  int errorno, nameSize;
  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
  DWORD duplex_flags;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
  handle->name = (WCHAR*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
    errorno = GetLastError();
    goto error;
  }

  pipeHandle = open_named_pipe(handle->name, &duplex_flags);
  if (pipeHandle == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc,
                             req,
                             WT_EXECUTELONGFUNCTION)) {
        errorno = GetLastError();
        goto error;
      }

      REGISTER_HANDLE_REQ(loop, handle, req);
      handle->reqs_pending++;

      return;
    }

    errorno = GetLastError();
    goto error;
  }

  assert(pipeHandle != INVALID_HANDLE_VALUE);

  if (uv_set_pipe_handle(loop,
                         (uv_pipe_t*) req->handle,
                         pipeHandle,
                         duplex_flags)) {
    errorno = GetLastError();
    goto error;
  }

  SET_REQ_SUCCESS(req);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  REGISTER_HANDLE_REQ(loop, handle, req);
  return;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(pipeHandle);
  }

  /* Make this req pending reporting an error. */
  SET_REQ_ERROR(req, errorno);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  REGISTER_HANDLE_REQ(loop, handle, req);
  return;
}
コード例 #11
0
ファイル: pipe.c プロジェクト: Cycle-Applications/node
/* Creates a pipe server. */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
  uv_loop_t* loop = handle->loop;
  int i, errorno, nameSize;
  uv_pipe_accept_t* req;

  if (handle->flags & UV_HANDLE_BOUND) {
    uv__set_sys_error(loop, WSAEINVAL);
    return -1;
  }

  if (!name) {
    uv__set_sys_error(loop, WSAEINVAL);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
    handle->pending_instances = default_pending_pipe_instances;
  }

  handle->accept_reqs = (uv_pipe_accept_t*)
    malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
  if (!handle->accept_reqs) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  for (i = 0; i < handle->pending_instances; i++) {
    req = &handle->accept_reqs[i];
    uv_req_init(loop, (uv_req_t*) req);
    req->type = UV_ACCEPT;
    req->data = handle;
    req->pipeHandle = INVALID_HANDLE_VALUE;
    req->next_pending = NULL;
  }

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
  handle->name = (WCHAR*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
    uv__set_sys_error(loop, GetLastError());
    return -1;
  }

  /*
   * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
   * If this fails then there's already a pipe server for the given pipe name.
   */
  handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
      PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
      FILE_FLAG_FIRST_PIPE_INSTANCE,
      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
      PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);

  if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
    errorno = GetLastError();
    if (errorno == ERROR_ACCESS_DENIED) {
      uv__set_error(loop, UV_EADDRINUSE, errorno);
    } else if (errorno == ERROR_PATH_NOT_FOUND || errorno == ERROR_INVALID_NAME) {
      uv__set_error(loop, UV_EACCES, errorno);
    } else {
      uv__set_sys_error(loop, errorno);
    }
    goto error;
  }

  if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) {
    uv__set_sys_error(loop, GetLastError());
    goto error;
  }

  handle->pending_accepts = NULL;
  handle->flags |= UV_HANDLE_PIPESERVER;
  handle->flags |= UV_HANDLE_BOUND;

  return 0;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(handle->accept_reqs[0].pipeHandle);
    handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
  }

  return -1;
}
コード例 #12
0
ファイル: fs-event.c プロジェクト: Laner/gitbin
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
    const char* filename, uv_fs_event_cb cb) {
  int name_size;
  DWORD attr, last_error;
  wchar_t* dir = NULL, *dir_to_watch, *filenamew;
  wchar_t short_path[MAX_PATH];

  uv_fs_event_init_handle(loop, handle, filename, cb);

  /* Convert name to UTF16. */
  name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(wchar_t);
  filenamew = (wchar_t*)malloc(name_size);
  if (!filenamew) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(filename, filenamew, 
      name_size / sizeof(wchar_t))) {
    uv__set_sys_error(loop, GetLastError());
    return -1;
  }

  /* Determine whether filename is a file or a directory. */
  attr = GetFileAttributesW(filenamew);
  if (attr == INVALID_FILE_ATTRIBUTES) {
    last_error = GetLastError();
    goto error;
  }

  handle->is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;

  if (handle->is_path_dir) {
     /* filename is a directory, so that's the directory that we will watch. */
    dir_to_watch = filenamew;
  } else {
    /* 
     * filename is a file.  So we split filename into dir & file parts, and
     * watch the dir directory.
     */
    
    /* Convert to short path. */
    if (!GetShortPathNameW(filenamew, short_path, COUNTOF(short_path))) {
      last_error = GetLastError();
      goto error;
    }

    if (uv_split_path(filenamew, &dir, &handle->filew) != 0) {
      last_error = GetLastError();
      goto error;
    }

    if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
      last_error = GetLastError();
      goto error;
    }

    dir_to_watch = dir;
  }

  handle->dir_handle = CreateFileW(dir_to_watch,
                                   FILE_LIST_DIRECTORY,
                                   FILE_SHARE_READ | FILE_SHARE_DELETE |
                                     FILE_SHARE_WRITE,
                                   NULL,
                                   OPEN_EXISTING,
                                   FILE_FLAG_BACKUP_SEMANTICS |
                                     FILE_FLAG_OVERLAPPED,
                                   NULL);

  if (dir) {
    free(dir);
    dir = NULL;
  }

  if (handle->dir_handle == INVALID_HANDLE_VALUE) {
    last_error = GetLastError();
    goto error;
  }

  if (CreateIoCompletionPort(handle->dir_handle,
                             loop->iocp,
                             (ULONG_PTR)handle,
                             0) == NULL) {
    last_error = GetLastError();
    goto error;
  }

  handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size, 
    sizeof(DWORD));
  if (!handle->buffer) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));

  if (!ReadDirectoryChangesW(handle->dir_handle,
                             handle->buffer,
                             uv_directory_watcher_buffer_size,
                             FALSE,
                             FILE_NOTIFY_CHANGE_FILE_NAME      |
                               FILE_NOTIFY_CHANGE_DIR_NAME     |
                               FILE_NOTIFY_CHANGE_ATTRIBUTES   |
                               FILE_NOTIFY_CHANGE_SIZE         |
                               FILE_NOTIFY_CHANGE_LAST_WRITE   |
                               FILE_NOTIFY_CHANGE_LAST_ACCESS  |
                               FILE_NOTIFY_CHANGE_CREATION     |
                               FILE_NOTIFY_CHANGE_SECURITY,
                             NULL,
                             &handle->req.overlapped,
                             NULL)) {
    last_error = GetLastError();
    goto error;
  }

  handle->req_pending = 1;
  return 0;

error:
  if (handle->filename) {
    free(handle->filename);
    handle->filename = NULL;
  }

  if (handle->filew) {
    free(handle->filew);
    handle->filew = NULL;
  }

  if (handle->short_filew) {
    free(handle->short_filew);
    handle->short_filew = NULL;
  }

  if (handle->dir_handle != INVALID_HANDLE_VALUE) {
    CloseHandle(handle->dir_handle);
    handle->dir_handle = INVALID_HANDLE_VALUE;
  }

  if (handle->buffer) {
    _aligned_free(handle->buffer);
    handle->buffer = NULL;
  }

  uv__set_sys_error(loop, last_error);
  return -1;
}
コード例 #13
0
ファイル: pipe.c プロジェクト: diffidentDude/node
int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  int errno, nameSize;
  HANDLE pipeHandle;

  handle->handle = INVALID_HANDLE_VALUE;

  uv_req_init((uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
  handle->name = (wchar_t*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
    errno = GetLastError();
    goto error;
  }

  pipeHandle = CreateFileW(handle->name,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          NULL,
                          OPEN_EXISTING,
                          FILE_FLAG_OVERLAPPED,
                          NULL);

  if (pipeHandle == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
        errno = GetLastError();
        goto error;
      }

      return 0;
    }

    errno = GetLastError();
    goto error;
  }

  if (uv_set_pipe_handle((uv_pipe_t*)req->handle, pipeHandle)) {
    errno = GetLastError();
    goto error;
  }

  handle->handle = pipeHandle;

  req->error = uv_ok_;
  uv_insert_pending_req((uv_req_t*) req);
  handle->reqs_pending++;
  return 0;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(pipeHandle);
  }
  uv_set_sys_error(errno);
  return -1;
}
コード例 #14
0
ファイル: pipe.c プロジェクト: 337240552/node
void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  uv_loop_t* loop = handle->loop;
  int errno, nameSize;

  handle->handle = INVALID_HANDLE_VALUE;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
  handle->name = (wchar_t*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
    errno = GetLastError();
    goto error;
  }

  if (open_named_pipe(handle) != 0) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc,
                             req,
                             WT_EXECUTELONGFUNCTION)) {
        errno = GetLastError();
        goto error;
      }

      handle->reqs_pending++;

      return;
    }

    errno = GetLastError();
    goto error;
  }

  assert(handle->handle != INVALID_HANDLE_VALUE);

  /* Ensure that what we just opened is actually a pipe */
  if (!GetNamedPipeInfo(handle->handle, NULL, NULL, NULL, NULL)) {
    errno = WSAENOTSOCK;
    goto error;
  }

  if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, handle->handle)) {
    errno = GetLastError();
    goto error;
  }

  SET_REQ_SUCCESS(req);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  return;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (handle->handle != INVALID_HANDLE_VALUE) {
    CloseHandle(handle->handle);
    handle->handle = INVALID_HANDLE_VALUE;
  }

  /* Make this req pending reporting an error. */
  SET_REQ_ERROR(req, errno);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  return;
}