Ejemplo n.º 1
0
/**
 * raw_socket_read - Read data from a socket - Implements Connection::conn_read()
 */
int raw_socket_read(struct Connection *conn, char *buf, size_t count)
{
  int rc;

  mutt_sig_allow_interrupt(1);
  do
  {
    rc = read(conn->fd, buf, count);
  } while (rc < 0 && (errno == EINTR));

  if (rc < 0)
  {
    mutt_error(_("Error talking to %s (%s)"), conn->account.host, strerror(errno));
    SigInt = 0;
  }
  mutt_sig_allow_interrupt(0);

  if (SigInt)
  {
    mutt_error(_("Connection to %s has been aborted"), conn->account.host);
    SigInt = 0;
    rc = -1;
  }

  return rc;
}
Ejemplo n.º 2
0
/**
 * raw_socket_write - Write data to a socket - Implements Connection::conn_write()
 */
int raw_socket_write(struct Connection *conn, const char *buf, size_t count)
{
  int rc;
  size_t sent = 0;

  mutt_sig_allow_interrupt(1);
  do
  {
    do
    {
      rc = write(conn->fd, buf + sent, count - sent);
    } while (rc < 0 && (errno == EINTR));

    if (rc < 0)
    {
      mutt_error(_("Error talking to %s (%s)"), conn->account.host, strerror(errno));
      mutt_sig_allow_interrupt(0);
      return -1;
    }

    sent += rc;
  } while ((sent < count) && (SigInt == 0));

  mutt_sig_allow_interrupt(0);
  return sent;
}
Ejemplo n.º 3
0
/**
 * mutt_getch - Read a character from the input buffer
 * @retval obj Event to process
 *
 * The priority for reading events is:
 * 1. UngetKeyEvents buffer
 * 2. MacroEvents buffer
 * 3. Keyboard
 *
 * This function can return:
 * - Error `{ -1, OP_NULL }`
 * - Timeout `{ -2, OP_NULL }`
 */
struct Event mutt_getch(void)
{
  int ch;
  struct Event err = { -1, OP_NULL }, ret;
  struct Event timeout = { -2, OP_NULL };

  if (UngetCount)
    return UngetKeyEvents[--UngetCount];

  if (!OptIgnoreMacroEvents && MacroBufferCount)
    return MacroEvents[--MacroBufferCount];

  SigInt = 0;

  mutt_sig_allow_interrupt(1);
#ifdef KEY_RESIZE
  /* ncurses 4.2 sends this when the screen is resized */
  ch = KEY_RESIZE;
  while (ch == KEY_RESIZE)
#endif /* KEY_RESIZE */
#ifdef USE_INOTIFY
    ch = mutt_monitor_getch();
#else
  ch = getch();
#endif /* USE_INOTIFY */
  mutt_sig_allow_interrupt(0);

  if (SigInt)
  {
    mutt_query_exit();
    return err;
  }

  /* either timeout, a sigwinch (if timeout is set), or the terminal
   * has been lost */
  if (ch == ERR)
  {
    if (!isatty(0))
      mutt_exit(1);

    return timeout;
  }

  if ((ch & 0x80) && C_MetaKey)
  {
    /* send ALT-x as ESC-x */
    ch &= ~0x80;
    mutt_unget_event(ch, 0);
    ret.ch = '\033';
    ret.op = 0;
    return ret;
  }

  ret.ch = ch;
  ret.op = 0;
  return (ch == ctrl('G')) ? err : ret;
}
Ejemplo n.º 4
0
/**
 * socket_connect - set up to connect to a socket fd
 * @param fd File descriptor to connect with
 * @param sa Address info
 * @retval  0 Success
 * @retval >0 An errno, e.g. EPERM
 * @retval -1 Error
 */
static int socket_connect(int fd, struct sockaddr *sa)
{
  int sa_size;
  int save_errno;
  sigset_t set;

  if (sa->sa_family == AF_INET)
    sa_size = sizeof(struct sockaddr_in);
#ifdef HAVE_GETADDRINFO
  else if (sa->sa_family == AF_INET6)
    sa_size = sizeof(struct sockaddr_in6);
#endif
  else
  {
    mutt_debug(LL_DEBUG1, "Unknown address family!\n");
    return -1;
  }

  if (C_ConnectTimeout > 0)
    alarm(C_ConnectTimeout);

  mutt_sig_allow_interrupt(1);

  /* FreeBSD's connect() does not respect SA_RESTART, meaning
   * a SIGWINCH will cause the connect to fail. */
  sigemptyset(&set);
  sigaddset(&set, SIGWINCH);
  sigprocmask(SIG_BLOCK, &set, NULL);

  save_errno = 0;

  if (connect(fd, sa, sa_size) < 0)
  {
    save_errno = errno;
    mutt_debug(LL_DEBUG2, "Connection failed. errno: %d\n", errno);
    SigInt = 0; /* reset in case we caught SIGINTR while in connect() */
  }

  if (C_ConnectTimeout > 0)
    alarm(0);
  mutt_sig_allow_interrupt(0);
  sigprocmask(SIG_UNBLOCK, &set, NULL);

  return save_errno;
}