Ejemplo n.º 1
0
void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
  assert(handle->type == UV_NAMED_PIPE);

  if (req->cb) {
    if (REQ_SUCCESS(req)) {
      uv_pipe_connection_init(handle);
      ((uv_connect_cb)req->cb)(req, 0);
    } else {
      LOOP->last_error = GET_REQ_UV_ERROR(req);
      ((uv_connect_cb)req->cb)(req, -1);
    }
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Ejemplo n.º 2
0
Archivo: tty.c Proyecto: hghazal/node
void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
    uv_req_t* req) {
  uv_buf_t buf;

  assert(handle->type == UV_TTY);

  buf = handle->read_line_buffer;

  handle->flags &= ~UV_HANDLE_READ_PENDING;
  handle->read_line_buffer = uv_null_buf_;

  if (!REQ_SUCCESS(req)) {
    /* Read was not successful */
    if ((handle->flags & UV_HANDLE_READING) &&
        !(handle->flags & UV_HANDLE_TTY_RAW)) {
      /* Real error */
      handle->flags &= ~UV_HANDLE_READING;
      loop->last_error = GET_REQ_UV_ERROR(req);
      handle->read_cb((uv_stream_t*) handle, -1, buf);
    } else {
      /* The read was cancelled, or whatever we don't care */
      uv_set_sys_error(loop, WSAEWOULDBLOCK); /* maps to UV_EAGAIN */
      handle->read_cb((uv_stream_t*) handle, 0, buf);
    }

  } else {
    /* Read successful */
    /* TODO: read unicode, convert to utf-8 */
    DWORD bytes = req->overlapped.InternalHigh;
    if (bytes == 0) {
      uv_set_sys_error(loop, WSAEWOULDBLOCK); /* maps to UV_EAGAIN */
    }
    handle->read_cb((uv_stream_t*) handle, bytes, buf);
  }

  /* Wait for more input events. */
  if ((handle->flags & UV_HANDLE_READING) &&
      !(handle->flags & UV_HANDLE_READ_PENDING)) {
    uv_tty_queue_read(loop, handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Ejemplo n.º 3
0
void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req) {
  assert(handle->type == UV_NAMED_PIPE);

  handle->write_queue_size -= req->queued_bytes;

  if (req->cb) {
    if (!REQ_SUCCESS(req)) {
      LOOP->last_error = GET_REQ_UV_ERROR(req);
      ((uv_write_cb)req->cb)(req, -1);
    } else {
      ((uv_write_cb)req->cb)(req, 0);
    }
  }

  handle->write_reqs_pending--;
  if (handle->write_reqs_pending == 0 &&
      handle->flags & UV_HANDLE_SHUTTING) {
    uv_want_endgame((uv_handle_t*)handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Ejemplo n.º 4
0
Archivo: tty.c Proyecto: hghazal/node
void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
    uv_req_t* req) {
  /* Shortcut for handle->last_input_record.Event.KeyEvent. */
#define KEV handle->last_input_record.Event.KeyEvent

  DWORD records_left, records_read;
  uv_buf_t buf;
  off_t buf_used;

  assert(handle->type == UV_TTY);
  handle->flags &= ~UV_HANDLE_READ_PENDING;

  if (!(handle->flags & UV_HANDLE_READING) ||
      !(handle->flags & UV_HANDLE_TTY_RAW)) {
    goto out;
  }

  if (!REQ_SUCCESS(req)) {
    /* An error occurred while waiting for the event. */
    if ((handle->flags & UV_HANDLE_READING)) {
      handle->flags &= ~UV_HANDLE_READING;
      loop->last_error = GET_REQ_UV_ERROR(req);
      handle->read_cb((uv_stream_t*)handle, -1, uv_null_buf_);
    }
    goto out;
  }

  /* Fetch the number of events  */
  if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) {
    handle->flags &= ~UV_HANDLE_READING;
    uv_set_sys_error(loop, GetLastError());
    handle->read_cb((uv_stream_t*)handle, -1, uv_null_buf_);
    goto out;
  }

  /* Windows sends a lot of events that we're not interested in, so buf */
  /* will be allocated on demand, when there's actually something to emit. */
  buf = uv_null_buf_;
  buf_used = 0;

  while ((records_left > 0 || handle->last_key_len > 0) &&
         (handle->flags & UV_HANDLE_READING)) {
    if (handle->last_key_len == 0) {
      /* Read the next input record */
      if (!ReadConsoleInputW(handle->handle,
                             &handle->last_input_record,
                             1,
                             &records_read)) {
        uv_set_sys_error(loop, GetLastError());
        handle->flags &= ~UV_HANDLE_READING;
        handle->read_cb((uv_stream_t*) handle, -1, buf);
        goto out;
      }
      records_left--;

      /* Ignore events that are not keyboard events */
      if (handle->last_input_record.EventType != KEY_EVENT) {
        continue;
      }

      /* Ignore keyup events, unless the left alt key was held and a valid */
      /* unicode character was emitted. */
      if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
          KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
        continue;
      }

      /* Ignore keypresses to numpad number keys if the left alt is held */
      /* because the user is composing a character, or windows simulating */
      /* this. */
      if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) &&
          !(KEV.dwControlKeyState & ENHANCED_KEY) &&
          (KEV.wVirtualKeyCode == VK_INSERT ||
          KEV.wVirtualKeyCode == VK_END ||
          KEV.wVirtualKeyCode == VK_DOWN ||
          KEV.wVirtualKeyCode == VK_NEXT ||
          KEV.wVirtualKeyCode == VK_LEFT ||
          KEV.wVirtualKeyCode == VK_CLEAR ||
          KEV.wVirtualKeyCode == VK_RIGHT ||
          KEV.wVirtualKeyCode == VK_HOME ||
          KEV.wVirtualKeyCode == VK_UP ||
          KEV.wVirtualKeyCode == VK_PRIOR ||
          KEV.wVirtualKeyCode == VK_NUMPAD0 ||
          KEV.wVirtualKeyCode == VK_NUMPAD1 ||
          KEV.wVirtualKeyCode == VK_NUMPAD2 ||
          KEV.wVirtualKeyCode == VK_NUMPAD3 ||
          KEV.wVirtualKeyCode == VK_NUMPAD4 ||
          KEV.wVirtualKeyCode == VK_NUMPAD5 ||
          KEV.wVirtualKeyCode == VK_NUMPAD6 ||
          KEV.wVirtualKeyCode == VK_NUMPAD7 ||
          KEV.wVirtualKeyCode == VK_NUMPAD8 ||
          KEV.wVirtualKeyCode == VK_NUMPAD9)) {
        continue;
      }

      if (KEV.uChar.UnicodeChar != 0) {
        int prefix_len, char_len;

        /* Character key pressed */
        if (KEV.uChar.UnicodeChar >= 0xD800 &&
            KEV.uChar.UnicodeChar < 0xDC00) {
          /* UTF-16 high surrogate */
          handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
          continue;
        }

        /* Prefix with \u033 if alt was held, but alt was not used as part */
        /* a compose sequence. */
        if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
            && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
            RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
          handle->last_key[0] = '\033';
          prefix_len = 1;
        } else {
          prefix_len = 0;
        }

        if (KEV.uChar.UnicodeChar >= 0xDC00 &&
            KEV.uChar.UnicodeChar < 0xE000) {
          /* UTF-16 surrogate pair */
          WCHAR utf16_buffer[2] = { handle->last_utf16_high_surrogate,
                                    KEV.uChar.UnicodeChar};
          char_len = WideCharToMultiByte(CP_UTF8,
                                         0,
                                         utf16_buffer,
                                         2,
                                         &handle->last_key[prefix_len],
                                         sizeof handle->last_key,
                                         NULL,
                                         NULL);
        } else {
          /* Single UTF-16 character */
          char_len = WideCharToMultiByte(CP_UTF8,
                                         0,
                                         &KEV.uChar.UnicodeChar,
                                         1,
                                         &handle->last_key[prefix_len],
                                         sizeof handle->last_key,
                                         NULL,
                                         NULL);
        }

        /* Whatever happened, the last character wasn't a high surrogate. */
        handle->last_utf16_high_surrogate = 0;

        /* If the utf16 character(s) couldn't be converted something must */
        /* be wrong. */
        if (!char_len) {
          uv_set_sys_error(loop, GetLastError());
          handle->flags &= ~UV_HANDLE_READING;
          handle->read_cb((uv_stream_t*) handle, -1, buf);
          goto out;
        }

        handle->last_key_len = (unsigned char) (prefix_len + char_len);
        handle->last_key_offset = 0;
        continue;

      } else {
        /* Function key pressed */
        const char* vt100;
        size_t prefix_len, vt100_len;

        vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode,
                                  !!(KEV.dwControlKeyState & SHIFT_PRESSED),
                                  !!(KEV.dwControlKeyState & (
                                    LEFT_CTRL_PRESSED |
                                    RIGHT_CTRL_PRESSED)),
                                  &vt100_len);

        /* If we were unable to map to a vt100 sequence, just ignore. */
        if (!vt100) {
          continue;
        }

        /* Prefix with \x033 when the alt key was held. */
        if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
          handle->last_key[0] = '\033';
          prefix_len = 1;
        } else {
          prefix_len = 0;
        }

        /* Copy the vt100 sequence to the handle buffer. */
        assert(prefix_len + vt100_len < sizeof handle->last_key);
        memcpy(&handle->last_key[prefix_len], vt100, vt100_len);

        handle->last_key_len = (unsigned char) (prefix_len + vt100_len);
        handle->last_key_offset = 0;
        continue;
      }
    } else {
      /* Copy any bytes left from the last keypress to the user buffer. */
      if (handle->last_key_offset < handle->last_key_len) {
        /* Allocate a buffer if needed */
        if (buf_used == 0) {
          buf = handle->alloc_cb((uv_handle_t*) handle, 1024);
        }

        buf.base[buf_used++] = handle->last_key[handle->last_key_offset++];

        /* If the buffer is full, emit it */
        if (buf_used == buf.len) {
          handle->read_cb((uv_stream_t*) handle, buf_used, buf);
          buf = uv_null_buf_;
          buf_used = 0;
        }

        continue;
      }

      /* Apply dwRepeat from the last input record. */
      if (--KEV.wRepeatCount > 0) {
        handle->last_key_offset = 0;
        continue;
      }

      handle->last_key_len = 0;
      continue;
    }
  }

  /* Send the buffer back to the user */
  if (buf_used > 0) {
    handle->read_cb((uv_stream_t*) handle, buf_used, buf);
  }

 out:
  /* Wait for more input events. */
  if ((handle->flags & UV_HANDLE_READING) &&
      !(handle->flags & UV_HANDLE_READ_PENDING)) {
    uv_tty_queue_read(loop, handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);

#undef KEV
}
Ejemplo n.º 5
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;
  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) {
        
          /* 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] = L'\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 {
      handle->cb(handle, NULL, UV_CHANGE, 0);
    }
  } else {
    loop->last_error = GET_REQ_UV_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);
  }
}