Esempio n. 1
0
static void
getaddr(struct sockaddr **dst, int *len, char *name, char *port)
{
    if (*name == '/') {
        unixaddr(dst, len, name);
        return;
    }
    inetaddr(dst, len, name, port);
}
Esempio n. 2
0
  Object* IO::socket_read(STATE, Fixnum* bytes, Fixnum* flags, Fixnum* type) {
    char buf[1024];
    socklen_t alen = sizeof(buf);
    size_t size = (size_t)bytes->to_native();

    String* buffer = String::create_pinned(state, bytes);

    OnStack<1> variables(state, buffer);

    ssize_t bytes_read;
    native_int t = type->to_native();

  retry:
    state->vm()->interrupt_with_signal();
    state->vm()->thread()->sleep(state, cTrue);

    {
      UnmanagedPhase unmanaged(state);

      bytes_read = recvfrom(descriptor(state),
                            (char*)buffer->byte_address(), size,
                            flags->to_native(),
                            (struct sockaddr*)buf, &alen);
    }

    state->vm()->thread()->sleep(state, cFalse);
    state->vm()->clear_waiter();

    buffer->unpin();

    if(bytes_read == -1) {
      if(errno == EINTR) {
        if(state->vm()->thread_interrupted_p(state)) return NULL;
        ensure_open(state);
        goto retry;
      } else {
        Exception::raise_errno_error(state, "read(2) failed");
      }

      return NULL;
    }

    buffer->num_bytes(state, Fixnum::from(bytes_read));

    if(t == 0) return buffer; // none

    Array* ary = Array::create(state, 2);
    ary->set(state, 0, buffer);

    switch(type->to_native()) {
    case 1: // ip
      // Hack from MRI:
      // OSX doesn't return a 'from' result from recvfrom for connection-oriented sockets
      if(alen && alen != sizeof(buf)) {
        ary->set(state, 1, ipaddr(state, (struct sockaddr*)buf, alen));
      } else {
        ary->set(state, 1, cNil);
      }
      break;
#ifndef RBX_WINDOWS
    case 2: // unix
      ary->set(state, 1, unixaddr(state, (struct sockaddr_un*)buf, alen));
      break;
#endif
    default:
      ary->set(state, 1, String::create(state, buf, alen));
    }

    return ary;
  }