コード例 #1
0
ファイル: util.c プロジェクト: 5y/node
static int uv__get_process_title() {
  WCHAR title_w[MAX_TITLE_LENGTH];
  int length;

  if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
    return -1;
  }

  /* Find out what the size of the buffer is that we need */
  length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
  if (!length) {
    return -1;
  }

  assert(!process_title);
  process_title = (char*)malloc(length);
  if (!process_title) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  /* Do utf16 -> utf8 conversion here */
  if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
    free(process_title);
    return -1;
  }

  return 0;
}
コード例 #2
0
ファイル: util.c プロジェクト: Darkie/node
int uv_exepath(char* buffer, size_t* size) {
  int retVal;
  size_t utf16Size;
  wchar_t* utf16Buffer;

  if (!buffer || !size) {
    return -1;
  }

  utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * *size);
  if (!utf16Buffer) {
    retVal = -1;
    goto done;
  }

  /* Get the path as UTF-16 */
  utf16Size = GetModuleFileNameW(NULL, utf16Buffer, *size - 1);
  if (utf16Size <= 0) {
    /* uv__set_sys_error(loop, GetLastError()); */
    retVal = -1;
    goto done;
  }

  utf16Buffer[utf16Size] = L'\0';

  /* Convert to UTF-8 */
  *size = uv_utf16_to_utf8(utf16Buffer, utf16Size, buffer, *size);
  if (!*size) {
    /* uv__set_sys_error(loop, GetLastError()); */
    retVal = -1;
    goto done;
  }

  buffer[*size] = '\0';
  retVal = 0;

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

  return retVal;
}
コード例 #3
0
ファイル: util.c プロジェクト: igorzi/libuv
uv_err_t uv_cwd(char* buffer, size_t size) {
  uv_err_t err;
  size_t utf8Size;
  wchar_t* utf16Buffer = NULL;

  if (!buffer || !size) {
    err.code = UV_EINVAL;
    goto done;
  }

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

  if (!_wgetcwd(utf16Buffer, size - 1)) {
    err = uv__new_sys_error(_doserrno);
    goto done;
  }

  utf16Buffer[size - 1] = L'\0';

  /* Convert to UTF-8 */
  utf8Size = uv_utf16_to_utf8(utf16Buffer, -1, buffer, size);
  if (utf8Size == 0) {
    err = uv__new_sys_error(GetLastError());
    goto done;
  }

  buffer[utf8Size] = '\0';
  err = uv_ok_;

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

  return err;
}
コード例 #4
0
void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
    uv_fs_event_t* handle) {
  FILE_NOTIFY_INFORMATION* file_info;
  int err, sizew, size, result;
  char* filename = NULL;
  WCHAR* filenamew, *long_filenamew = NULL;
  DWORD offset = 0;

  assert(req->type == UV_FS_EVENT_REQ);
  assert(handle->req_pending);
  handle->req_pending = 0;

  /* Don't report any callbacks if:
   * - We're closing, just push the handle onto the endgame queue
   * - We are not active, just ignore the callback
   */
  if (!uv__is_active(handle)) {
    if (handle->flags & UV__HANDLE_CLOSING) {
      uv_want_endgame(loop, (uv_handle_t*) handle);
    }
    return;
  }

  file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);

  if (REQ_SUCCESS(req)) {
    if (req->u.io.overlapped.InternalHigh > 0) {
      do {
        file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
        assert(!filename);
        assert(!long_filenamew);

        /*
         * Fire the event only if we were asked to watch a directory,
         * or if the filename filter matches.
         */
        if (handle->dirw ||
          _wcsnicmp(handle->filew, file_info->FileName,
            file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
          _wcsnicmp(handle->short_filew, file_info->FileName,
            file_info->FileNameLength / sizeof(WCHAR)) == 0) {

          if (handle->dirw) {
            /*
             * We attempt to resolve the long form of the file name explicitly.
             * We only do this for file names that might still exist on disk.
             * If this fails, we use the name given by ReadDirectoryChangesW.
             * This may be the long form or the 8.3 short name in some cases.
             */
            if (file_info->Action != FILE_ACTION_REMOVED &&
              file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
              /* Construct a full path to the file. */
              size = wcslen(handle->dirw) +
                file_info->FileNameLength / sizeof(WCHAR) + 2;

              filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
              if (!filenamew) {
                uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
              }

              _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
                file_info->FileNameLength / sizeof(WCHAR),
                file_info->FileName);

              filenamew[size - 1] = L'\0';

              /* Convert to long name. */
              size = GetLongPathNameW(filenamew, NULL, 0);

              if (size) {
                long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
                if (!long_filenamew) {
                  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
                }

                size = GetLongPathNameW(filenamew, long_filenamew, size);
                if (size) {
                  long_filenamew[size] = '\0';
                } else {
                  uv__free(long_filenamew);
                  long_filenamew = NULL;
                }
              }

              uv__free(filenamew);

              if (long_filenamew) {
                /* Get the file name out of the long path. */
                result = uv_relative_path(long_filenamew,
                                          handle->dirw,
                                          &filenamew);
                uv__free(long_filenamew);

                if (result == 0) {
                  long_filenamew = filenamew;
                  sizew = -1;
                } else {
                  long_filenamew = NULL;
                }
              }

              /*
               * We could not resolve the long form explicitly.
               * We therefore use the name given by ReadDirectoryChangesW.
               * This may be the long form or the 8.3 short name in some cases.
               */
              if (!long_filenamew) {
                filenamew = file_info->FileName;
                sizew = file_info->FileNameLength / sizeof(WCHAR);
              }
            } else {
              /*
               * Removed or renamed events cannot be resolved to the long form.
               * We therefore use the name given by ReadDirectoryChangesW.
               * This may be the long form or the 8.3 short name in some cases.
               */
              if (!long_filenamew) {
                filenamew = file_info->FileName;
                sizew = file_info->FileNameLength / sizeof(WCHAR);
              }
            }
          } else {
            /* We already have the long name of the file, so just use it. */
            filenamew = handle->filew;
            sizew = -1;
          }

          if (filenamew) {
            /* Convert the filename to utf8. */
            size = uv_utf16_to_utf8(filenamew,
                                    sizew,
                                    NULL,
                                    0);
            if (size) {
              filename = (char*)uv__malloc(size + 1);
              if (!filename) {
                uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
              }

              size = uv_utf16_to_utf8(filenamew,
                                      sizew,
                                      filename,
                                      size);
              if (size) {
                filename[size] = '\0';
              } else {
                uv__free(filename);
                filename = NULL;
              }
            }
          }

          switch (file_info->Action) {
            case FILE_ACTION_ADDED:
            case FILE_ACTION_REMOVED:
            case FILE_ACTION_RENAMED_OLD_NAME:
            case FILE_ACTION_RENAMED_NEW_NAME:
              handle->cb(handle, filename, UV_RENAME, 0);
              break;

            case FILE_ACTION_MODIFIED:
              handle->cb(handle, filename, UV_CHANGE, 0);
              break;
          }

          uv__free(filename);
          filename = NULL;
          uv__free(long_filenamew);
          long_filenamew = NULL;
        }

        offset = file_info->NextEntryOffset;
      } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
    } else {
      handle->cb(handle, NULL, UV_CHANGE, 0);
    }
  } else {
    err = GET_REQ_ERROR(req);
    handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
  }

  if (!(handle->flags & UV__HANDLE_CLOSING)) {
    uv_fs_event_queue_readdirchanges(loop, handle);
  } else {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }
}
コード例 #5
0
ファイル: fs.c プロジェクト: Cahya/node
void fs__readlink(uv_fs_t* req, const char* path) {
  int result = -1;
  BOOL rv;
  HANDLE symlink;
  void* buffer = NULL;
  DWORD bytes_returned;
  REPARSE_DATA_BUFFER* reparse_data;
  int utf8size;

  symlink = CreateFileA(path,
                        0,
                        0,
                        NULL,
                        OPEN_EXISTING,
                        FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
                        NULL);

  if (INVALID_HANDLE_VALUE == symlink) {
    result = -1;
    SET_REQ_LAST_ERROR(req, GetLastError());
    goto done;
  }

  buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
  if (!buffer) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  rv = DeviceIoControl(symlink,
                       FSCTL_GET_REPARSE_POINT,
                       NULL,
                       0,
                       buffer, 
                       MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
                       &bytes_returned,
                       NULL);

  if (!rv) {
    result = -1;
    SET_REQ_LAST_ERROR(req, GetLastError());
    goto done;
  }

  reparse_data = buffer;
  if (reparse_data->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
    result = -1;
    /* something is seriously wrong */
    SET_REQ_LAST_ERROR(req, GetLastError());
    goto done;
  }

  utf8size = uv_utf16_to_utf8(reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)),
                              reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t),
                              NULL,
                              0);
  if (!utf8size) {
    result = -1;
    SET_REQ_LAST_ERROR(req, GetLastError());
    goto done;
  }

  req->ptr = malloc(utf8size + 1);
  if (!req->ptr) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  req->flags |= UV_FS_FREE_PTR;

  utf8size = uv_utf16_to_utf8(reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)),
                              reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t),
                              req->ptr,
                              utf8size);
  if (!utf8size) {
    result = -1;
    SET_REQ_LAST_ERROR(req, GetLastError());
    goto done;
  }

  ((char*)req->ptr)[utf8size] = '\0';
  result = 0;

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

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

  SET_REQ_RESULT(req, result);
}
コード例 #6
0
ファイル: util.c プロジェクト: reid/node
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
                                int* count) {
    unsigned long size = 0;
    IP_ADAPTER_ADDRESSES* adapter_addresses;
    IP_ADAPTER_ADDRESSES* adapter_address;
    uv_interface_address_t* address;
    struct sockaddr* sock_addr;
    int length;
    char* name;
    /* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */
    /* with Windows XP */
    IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;

    if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size)
            != ERROR_BUFFER_OVERFLOW) {
        return uv__new_sys_error(GetLastError());
    }

    adapter_addresses = (IP_ADAPTER_ADDRESSES*)malloc(size);
    if (!adapter_addresses) {
        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
    }

    if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapter_addresses, &size)
            != ERROR_SUCCESS) {
        return uv__new_sys_error(GetLastError());
    }

    /* Count the number of interfaces */
    *count = 0;

    for (adapter_address = adapter_addresses;
            adapter_address != NULL;
            adapter_address = adapter_address->Next) {

        if (adapter_address->OperStatus != IfOperStatusUp)
            continue;

        unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
                          adapter_address->FirstUnicastAddress;

        while (unicast_address) {
            (*count)++;
            unicast_address = unicast_address->Next;
        }
    }

    *addresses = (uv_interface_address_t*)
                 malloc(*count * sizeof(uv_interface_address_t));
    if (!(*addresses)) {
        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
    }

    address = *addresses;

    for (adapter_address = adapter_addresses;
            adapter_address != NULL;
            adapter_address = adapter_address->Next) {

        if (adapter_address->OperStatus != IfOperStatusUp)
            continue;

        name = NULL;
        unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
                          adapter_address->FirstUnicastAddress;

        while (unicast_address) {
            sock_addr = unicast_address->Address.lpSockaddr;
            if (sock_addr->sa_family == AF_INET6) {
                address->address.address6 = *((struct sockaddr_in6 *)sock_addr);
            } else {
                address->address.address4 = *((struct sockaddr_in *)sock_addr);
            }

            address->is_internal =
                adapter_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? 1 : 0;

            if (!name) {
                /* Convert FriendlyName to utf8 */
                length = uv_utf16_to_utf8(adapter_address->FriendlyName, -1, NULL, 0);
                if (length) {
                    name = (char*)malloc(length);
                    if (!name) {
                        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
                    }

                    if (!uv_utf16_to_utf8(adapter_address->FriendlyName, -1, name,
                                          length)) {
                        free(name);
                        name = NULL;
                    }
                }
            }

            assert(name);
            address->name = name;

            unicast_address = unicast_address->Next;
            address++;
        }
    }

    free(adapter_addresses);

    return uv_ok_;
}
コード例 #7
0
ファイル: util.c プロジェクト: reid/node
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
    DWORD sppi_size;
    SYSTEM_INFO system_info;
    DWORD cpu_count, i, r;
    ULONG result_size;
    size_t size;
    uv_err_t err;
    uv_cpu_info_t* cpu_info;

    *cpu_infos = NULL;
    *count = 0;

    uv__once_init();

    GetSystemInfo(&system_info);
    cpu_count = system_info.dwNumberOfProcessors;

    size = cpu_count * sizeof(uv_cpu_info_t);
    *cpu_infos = (uv_cpu_info_t*) malloc(size);
    if (*cpu_infos == NULL) {
        err = uv__new_artificial_error(UV_ENOMEM);
        goto out;
    }
    memset(*cpu_infos, 0, size);

    sppi_size = sizeof(*sppi) * cpu_count;
    sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) malloc(sppi_size);
    if (!sppi) {
        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
    }

    r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
                                  sppi,
                                  sppi_size,
                                  &result_size);
    if (r != ERROR_SUCCESS || result_size != sppi_size) {
        err = uv__new_sys_error(GetLastError());
        goto out;
    }

    for (i = 0; i < cpu_count; i++) {
        WCHAR key_name[128];
        HKEY processor_key;
        DWORD cpu_speed;
        DWORD cpu_speed_size = sizeof(cpu_speed);
        WCHAR cpu_brand[256];
        DWORD cpu_brand_size = sizeof(cpu_brand);

        _snwprintf(key_name,
                   ARRAY_SIZE(key_name),
                   L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
                   i);

        r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                          key_name,
                          0,
                          KEY_QUERY_VALUE,
                          &processor_key);
        if (r != ERROR_SUCCESS) {
            err = uv__new_sys_error(GetLastError());
            goto out;
        }

        if (RegQueryValueExW(processor_key,
                             L"~MHz",
                             NULL, NULL,
                             (BYTE*) &cpu_speed,
                             &cpu_speed_size) != ERROR_SUCCESS) {
            err = uv__new_sys_error(GetLastError());
            RegCloseKey(processor_key);
            goto out;
        }

        if (RegQueryValueExW(processor_key,
                             L"ProcessorNameString",
                             NULL, NULL,
                             (BYTE*) &cpu_brand,
                             &cpu_brand_size) != ERROR_SUCCESS) {
            err = uv__new_sys_error(GetLastError());
            RegCloseKey(processor_key);
            goto out;
        }

        RegCloseKey(processor_key);

        cpu_info = &(*cpu_infos)[i];
        cpu_info->speed = cpu_speed;
        cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
        cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
                                   sppi[i].IdleTime.QuadPart) / 10000;
        cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
        cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
        cpu_info->cpu_times.nice = 0;

        size = uv_utf16_to_utf8(cpu_brand,
                                cpu_brand_size / sizeof(WCHAR),
                                NULL,
                                0);
        if (size == 0) {
            err = uv__new_sys_error(GetLastError());
            goto out;
        }

        /* Allocate 1 extra byte for the null terminator. */
        cpu_info->model = (char*) malloc(size + 1);
        if (cpu_info->model == NULL) {
            err = uv__new_artificial_error(UV_ENOMEM);
            goto out;
        }

        if (uv_utf16_to_utf8(cpu_brand,
                             cpu_brand_size / sizeof(WCHAR),
                             cpu_info->model,
                             size) == 0) {
            err = uv__new_sys_error(GetLastError());
            goto out;
        }

        /* Ensure that cpu_info->model is null terminated. */
        cpu_info->model[size] = '\0';

        (*count)++;
    }

    err = uv_ok_;

out:
    if (sppi) {
        free(sppi);
    }

    if (err.code != UV_OK &&
            *cpu_infos != NULL) {
        int i;

        for (i = 0; i < *count; i++) {
            /* This is safe because the cpu_infos memory area is zeroed out */
            /* immediately after allocating it. */
            free((*cpu_infos)[i].model);
        }
        free(*cpu_infos);

        *cpu_infos = NULL;
        *count = 0;
    }

    return err;
}
コード例 #8
0
ファイル: getaddrinfo.c プロジェクト: 178620086/Node4Android
/*
 * Called from uv_run when complete. Call user specified callback
 * then free returned addrinfo
 * Returned addrinfo strings are converted from UTF-16 to UTF-8.
 *
 * 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.
 */
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
    uv_req_t* req) {
  int addrinfo_len = 0;
  int name_len = 0;
  size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
  struct addrinfoW* addrinfow_ptr;
  struct addrinfo* addrinfo_ptr;
  char* alloc_ptr = NULL;
  char* cur_ptr = NULL;
  uv_err_code uv_ret;

  /* release input parameter memory */
  if (handle->alloc != NULL) {
    free(handle->alloc);
    handle->alloc = NULL;
  }

  uv_ret = uv_translate_eai_error(handle->retcode);
  if (handle->retcode == 0) {
    /* convert addrinfoW to addrinfo */
    /* first calculate required length */
    addrinfow_ptr = handle->res;
    while (addrinfow_ptr != NULL) {
      addrinfo_len += addrinfo_struct_len +
          ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
      if (addrinfow_ptr->ai_canonname != NULL) {
        name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
        if (name_len == 0) {
          uv_ret = uv_translate_sys_error(GetLastError());
          goto complete;
        }
        addrinfo_len += ALIGNED_SIZE(name_len);
      }
      addrinfow_ptr = addrinfow_ptr->ai_next;
    }

    /* allocate memory for addrinfo results */
    alloc_ptr = (char*)malloc(addrinfo_len);

    /* do conversions */
    if (alloc_ptr != NULL) {
      cur_ptr = alloc_ptr;
      addrinfow_ptr = handle->res;

      while (addrinfow_ptr != NULL) {
        /* copy addrinfo struct data */
        assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len);
        addrinfo_ptr = (struct addrinfo*)cur_ptr;
        addrinfo_ptr->ai_family = addrinfow_ptr->ai_family;
        addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype;
        addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol;
        addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags;
        addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen;
        addrinfo_ptr->ai_canonname = NULL;
        addrinfo_ptr->ai_addr = NULL;
        addrinfo_ptr->ai_next = NULL;

        cur_ptr += addrinfo_struct_len;

        /* copy sockaddr */
        if (addrinfo_ptr->ai_addrlen > 0) {
          assert(cur_ptr + addrinfo_ptr->ai_addrlen <=
                 alloc_ptr + addrinfo_len);
          memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen);
          addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr;
          cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen);
        }

        /* convert canonical name to UTF-8 */
        if (addrinfow_ptr->ai_canonname != NULL) {
          name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
                                      -1,
                                      NULL,
                                      0);
          assert(name_len > 0);
          assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
          name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
                                      -1,
                                      cur_ptr,
                                      name_len);
          assert(name_len > 0);
          addrinfo_ptr->ai_canonname = cur_ptr;
          cur_ptr += ALIGNED_SIZE(name_len);
        }
        assert(cur_ptr <= alloc_ptr + addrinfo_len);

        /* set next ptr */
        addrinfow_ptr = addrinfow_ptr->ai_next;
        if (addrinfow_ptr != NULL) {
          addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr;
        }
      }
    } else {
      uv_ret = UV_ENOMEM;
    }

  }

  /* return memory to system */
  if (handle->res != NULL) {
    FreeAddrInfoW(handle->res);
    handle->res = NULL;
  }

complete:
  /* finally do callback with converted result */
  handle->getaddrinfo_cb(handle, uv_ret, (struct addrinfo*)alloc_ptr);

  uv_unref(loop);
}
コード例 #9
0
ファイル: getaddrinfo.c プロジェクト: 353355756/node
/*
 * Called from uv_run when complete. Call user specified callback
 * then free returned addrinfo
 * Returned addrinfo strings are converted from UTF-16 to UTF-8.
 *
 * 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.
 */
static void uv__getaddrinfo_done(struct uv__work* w, int status) {
  uv_getaddrinfo_t* req;
  int addrinfo_len = 0;
  int name_len = 0;
  size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
  struct addrinfoW* addrinfow_ptr;
  struct addrinfo* addrinfo_ptr;
  char* alloc_ptr = NULL;
  char* cur_ptr = NULL;

  req = container_of(w, uv_getaddrinfo_t, work_req);

  /* release input parameter memory */
  if (req->alloc != NULL) {
    free(req->alloc);
    req->alloc = NULL;
  }

  if (status == UV_ECANCELED) {
    assert(req->retcode == 0);
    req->retcode = UV_EAI_CANCELED;
    if (req->res != NULL) {
        FreeAddrInfoW(req->res);
        req->res = NULL;
    }
    goto complete;
  }

  if (req->retcode == 0) {
    /* convert addrinfoW to addrinfo */
    /* first calculate required length */
    addrinfow_ptr = req->res;
    while (addrinfow_ptr != NULL) {
      addrinfo_len += addrinfo_struct_len +
          ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
      if (addrinfow_ptr->ai_canonname != NULL) {
        name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
        if (name_len == 0) {
          req->retcode = uv_translate_sys_error(GetLastError());
          goto complete;
        }
        addrinfo_len += ALIGNED_SIZE(name_len);
      }
      addrinfow_ptr = addrinfow_ptr->ai_next;
    }

    /* allocate memory for addrinfo results */
    alloc_ptr = (char*)malloc(addrinfo_len);

    /* do conversions */
    if (alloc_ptr != NULL) {
      cur_ptr = alloc_ptr;
      addrinfow_ptr = req->res;

      while (addrinfow_ptr != NULL) {
        /* copy addrinfo struct data */
        assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len);
        addrinfo_ptr = (struct addrinfo*)cur_ptr;
        addrinfo_ptr->ai_family = addrinfow_ptr->ai_family;
        addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype;
        addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol;
        addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags;
        addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen;
        addrinfo_ptr->ai_canonname = NULL;
        addrinfo_ptr->ai_addr = NULL;
        addrinfo_ptr->ai_next = NULL;

        cur_ptr += addrinfo_struct_len;

        /* copy sockaddr */
        if (addrinfo_ptr->ai_addrlen > 0) {
          assert(cur_ptr + addrinfo_ptr->ai_addrlen <=
                 alloc_ptr + addrinfo_len);
          memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen);
          addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr;
          cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen);
        }

        /* convert canonical name to UTF-8 */
        if (addrinfow_ptr->ai_canonname != NULL) {
          name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
                                      -1,
                                      NULL,
                                      0);
          assert(name_len > 0);
          assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
          name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
                                      -1,
                                      cur_ptr,
                                      name_len);
          assert(name_len > 0);
          addrinfo_ptr->ai_canonname = cur_ptr;
          cur_ptr += ALIGNED_SIZE(name_len);
        }
        assert(cur_ptr <= alloc_ptr + addrinfo_len);

        /* set next ptr */
        addrinfow_ptr = addrinfow_ptr->ai_next;
        if (addrinfow_ptr != NULL) {
          addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr;
        }
      }
    } else {
      req->retcode = UV_EAI_MEMORY;
    }
  }

  /* return memory to system */
  if (req->res != NULL) {
    FreeAddrInfoW(req->res);
    req->res = NULL;
  }

complete:
  uv__req_unregister(req->loop, req);

  /* finally do callback with converted result */
  req->getaddrinfo_cb(req, req->retcode, (struct addrinfo*)alloc_ptr);
}
コード例 #10
0
ファイル: fs-event.c プロジェクト: Laner/gitbin
void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
    uv_fs_event_t* handle) {
  FILE_NOTIFY_INFORMATION* file_info;
  char* filename = NULL;
  int utf8size;
  DWORD offset = 0;

  assert(req->type == UV_FS_EVENT_REQ);
  assert(handle->req_pending);
  handle->req_pending = 0;

  file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);

  if (REQ_SUCCESS(req)) {
    if (req->overlapped.InternalHigh > 0) {
      do {
        file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);

        /* 
         * Fire the event only if we were asked to watch a directory,
         * or if the filename filter matches.
         */
        if (handle->is_path_dir ||
          _wcsnicmp(handle->filew, file_info->FileName,
            file_info->FileNameLength / sizeof(wchar_t)) == 0 ||
          _wcsnicmp(handle->short_filew, file_info->FileName,
            file_info->FileNameLength / sizeof(wchar_t)) == 0) {
        
          /* Convert the filename to utf8. */
          utf8size = uv_utf16_to_utf8(file_info->FileName,
                                      file_info->FileNameLength / 
                                        sizeof(wchar_t),
                                      NULL,
                                      0);
          if (utf8size) {
            filename = (char*)malloc(utf8size + 1);
            if (!filename) {
              uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
            }

            utf8size = uv_utf16_to_utf8(file_info->FileName,
                                        file_info->FileNameLength /
                                          sizeof(wchar_t),
                                        filename,
                                        utf8size);
            if (utf8size) {
              filename[utf8size] = '\0';
            } else {
              free(filename);
              filename = NULL;
            }
          }

          switch (file_info->Action) {
            case FILE_ACTION_ADDED:
            case FILE_ACTION_REMOVED:
            case FILE_ACTION_RENAMED_OLD_NAME:
            case FILE_ACTION_RENAMED_NEW_NAME:
              handle->cb(handle, filename, UV_RENAME, 0);
              break;

            case FILE_ACTION_MODIFIED:
              handle->cb(handle, filename, UV_CHANGE, 0);
              break;
          }

          free(filename);
          filename = NULL;
        }

        offset = file_info->NextEntryOffset;
      } while(offset);
    } else {
      if (!(handle->flags & UV_HANDLE_CLOSING)) {
        handle->cb(handle, NULL, UV_CHANGE, 0);
      }
    }
  } else {
    uv__set_sys_error(loop, GET_REQ_ERROR(req));
    handle->cb(handle, NULL, 0, -1);
  }

  if (!(handle->flags & UV_HANDLE_CLOSING)) {
    uv_fs_event_queue_readdirchanges(loop, handle);
  } else {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }
}
コード例 #11
0
ファイル: fs-event.c プロジェクト: Appanasamy/node
void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
    uv_fs_event_t* handle) {
  FILE_NOTIFY_INFORMATION* file_info;
  int sizew, size, result;
  char* filename = NULL;
  wchar_t* filenamew, *long_filenamew = NULL;
  DWORD offset = 0;

  assert(req->type == UV_FS_EVENT_REQ);
  assert(handle->req_pending);
  handle->req_pending = 0;

  /* If we're closing, don't report any callbacks, and just push the handle */
  /* onto the endgame queue. */
  if (handle->flags & UV_HANDLE_CLOSING) {
    uv_want_endgame(loop, (uv_handle_t*) handle);
    return;
  };

  file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);

  if (REQ_SUCCESS(req)) {
    if (req->overlapped.InternalHigh > 0) {
      do {
        file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
        assert(!filename);
        assert(!long_filenamew);

        /*
         * Fire the event only if we were asked to watch a directory,
         * or if the filename filter matches.
         */
        if (handle->dirw ||
          _wcsnicmp(handle->filew, file_info->FileName,
            file_info->FileNameLength / sizeof(wchar_t)) == 0 ||
          _wcsnicmp(handle->short_filew, file_info->FileName,
            file_info->FileNameLength / sizeof(wchar_t)) == 0) {

          if (handle->dirw) {
            /*
             * We attempt to convert the file name to its long form for
             * events that still point to valid files on disk.
             * For removed and renamed events, we do not provide the file name.
             */
            if (file_info->Action != FILE_ACTION_REMOVED &&
              file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
              /* Construct a full path to the file. */
              size = wcslen(handle->dirw) +
                file_info->FileNameLength / sizeof(wchar_t) + 2;

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

              _snwprintf(filenamew, size, L"%s\\%s", handle->dirw,
                file_info->FileName);

              filenamew[size - 1] = L'\0';

              /* Convert to long name. */
              size = GetLongPathNameW(filenamew, NULL, 0);

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

                size = GetLongPathNameW(filenamew, long_filenamew, size);
                if (size) {
                  long_filenamew[size] = '\0';
                } else {
                  free(long_filenamew);
                  long_filenamew = NULL;
                }
              }

              free(filenamew);

              if (long_filenamew) {
                /* Get the file name out of the long path. */
                result = uv_split_path(long_filenamew, NULL, &filenamew);
                free(long_filenamew);

                if (result == 0) {
                  long_filenamew = filenamew;
                  sizew = -1;
                } else {
                  long_filenamew = NULL;
                }
              }

              /*
               * If we couldn't get the long name - just use the name
               * provided by ReadDirectoryChangesW.
               */
              if (!long_filenamew) {
                filenamew = file_info->FileName;
                sizew = file_info->FileNameLength / sizeof(wchar_t);
              }
            } else {
              /* Removed or renamed callbacks don't provide filename. */
              filenamew = NULL;
            }
          } else {
            /* We already have the long name of the file, so just use it. */
            filenamew = handle->filew;
            sizew = -1;
          }

          if (filenamew) {
            /* Convert the filename to utf8. */
            size = uv_utf16_to_utf8(filenamew,
                                    sizew,
                                    NULL,
                                    0);
            if (size) {
              filename = (char*)malloc(size + 1);
              if (!filename) {
                uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
              }

              size = uv_utf16_to_utf8(filenamew,
                                      sizew,
                                      filename,
                                      size);
              if (size) {
                filename[size] = '\0';
              } else {
                free(filename);
                filename = NULL;
              }
            }
          }

          switch (file_info->Action) {
            case FILE_ACTION_ADDED:
            case FILE_ACTION_REMOVED:
            case FILE_ACTION_RENAMED_OLD_NAME:
            case FILE_ACTION_RENAMED_NEW_NAME:
              handle->cb(handle, filename, UV_RENAME, 0);
              break;

            case FILE_ACTION_MODIFIED:
              handle->cb(handle, filename, UV_CHANGE, 0);
              break;
          }

          free(filename);
          filename = NULL;
          free(long_filenamew);
          long_filenamew = NULL;
        }

        offset = file_info->NextEntryOffset;
      } while (offset && !(handle->flags & UV_HANDLE_CLOSING));
    } else {
      handle->cb(handle, NULL, UV_CHANGE, 0);
    }
  } else {
    uv__set_sys_error(loop, GET_REQ_ERROR(req));
    handle->cb(handle, NULL, 0, -1);
  }

  if (!(handle->flags & UV_HANDLE_CLOSING)) {
    uv_fs_event_queue_readdirchanges(loop, handle);
  } else {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }
}