ext/iodine/fio.c
/**
 * `fio_flush` attempts to write any remaining data in the internal buffer to
 * the underlying file descriptor and closes the underlying file descriptor once
 * if it's marked for closure (and all the data was sent).
 *
 * Return values: 1 will be returned if data remains in the buffer. 0
 * will be returned if the buffer was fully drained. -1 will be returned on an
 * error or when the connection is closed.
 */
`fio_flush` attempts to write any remaining data in the internal buffer to
the underlying file descriptor and closes the underlying file descriptor once
if it's marked for closure (and all the data was sent).

Return values: 1 will be returned if data remains in the buffer. 0
will be returned if the buffer was fully drained. -1 will be returned on an
error or when the connection is closed.
` fio_flush ` attempts to write any remaining data in the internal buffer to the underlying file descriptor and closes the underlying file descriptor once if it ' s marked for closure ( and all the data was sent ) . Return values : 1 will be returned if data remains in the buffer . 0 will be returned if the buffer was fully drained . - 1 will be returned on an error or when the connection is closed .
ssize_t fio_flush(intptr_t uuid) {
  if (!uuid_is_valid(uuid))
    goto invalid;
  errno = 0;
  ssize_t flushed = 0;
  int tmp;
  if (fio_trylock(&uuid_data(uuid).sock_lock))
    goto would_block;
  if (!uuid_data(uuid).packet)
    goto flush_rw_hook;
  const fio_packet_s *old_packet = uuid_data(uuid).packet;
  const size_t old_sent = uuid_data(uuid).sent;
  tmp = uuid_data(uuid).packet->write_func(fio_uuid2fd(uuid),
                                           uuid_data(uuid).packet);
  if (tmp <= 0) {
    goto test_errno;
  }
  if (uuid_data(uuid).packet_count >= FIO_SLOWLORIS_LIMIT &&
      uuid_data(uuid).packet == old_packet &&
      uuid_data(uuid).sent >= old_sent &&
      (uuid_data(uuid).sent - old_sent) < 32768) {
    goto attacked;
  }
  fio_unlock(&uuid_data(uuid).sock_lock);
  if (!uuid_data(uuid).packet && uuid_data(uuid).close)
    goto closed;
  return uuid_data(uuid).open && uuid_data(uuid).packet != NULL;
would_block:
  errno = EWOULDBLOCK;
  return -1;
closed:
  fio_force_close(uuid);
  return -1;
flush_rw_hook:
  flushed = uuid_data(uuid).rw_hooks->flush(uuid, uuid_data(uuid).rw_udata);
  fio_unlock(&uuid_data(uuid).sock_lock);
  if (!flushed)
    return 0;
  if (flushed < 0) {
    goto test_errno;
  }
  touchfd(fio_uuid2fd(uuid));
  return 1;
test_errno:
  fio_unlock(&uuid_data(uuid).sock_lock);
  switch (errno) {
  case EWOULDBLOCK: 
#if EWOULDBLOCK != EAGAIN
  case EAGAIN: 
#endif
  case ENOTCONN:      
  case EINPROGRESS:   
  case ENOSPC:        
  case EADDRNOTAVAIL: 
  case EINTR:
  case 0:
    return 1;
  case EFAULT:
    FIO_LOG_ERROR("fio_flush EFAULT - possible memory address error sent to "
                  "Unix socket.");
  case EPIPE:  
  case EIO:    
  case EINVAL: 
  case EBADF:
    uuid_data(uuid).close = 1;
    fio_force_close(uuid);
    return -1;
  }
  FIO_LOG_DEBUG("UUID error: %p (%d): %s\n", (void *)uuid, errno,
                strerror(errno));
  return 0;
invalid:
  errno = EBADF;
  return -1;
attacked:
  FIO_LOG_WARNING("(facil.io) possible Slowloris attack from %.*s",
                  (int)fio_peer_addr(uuid).len, fio_peer_addr(uuid).data);
  fio_unlock(&uuid_data(uuid).sock_lock);
  fio_clear_fd(fio_uuid2fd(uuid), 0);
  return -1;
}
ssize_t fio_flush ( intptr_t uuid ) { if ( ! uuid_is_valid ( uuid ) ) goto invalid ; errno = 0 ; ssize_t flushed = 0 ; int tmp ; if ( fio_trylock ( & uuid_data ( uuid ) . sock_lock ) ) goto would_block ; if ( ! uuid_data ( uuid ) . packet ) goto flush_rw_hook ; const fio_packet_s * old_packet = uuid_data ( uuid ) . packet ; const size_t old_sent = uuid_data ( uuid ) . sent ; tmp = uuid_data ( uuid ) . packet -> write_func ( fio_uuid2fd ( uuid ) , uuid_data ( uuid ) . packet ) ; if ( tmp <= 0 ) { goto test_errno ; } if ( uuid_data ( uuid ) . packet_count >= FIO_SLOWLORIS_LIMIT && uuid_data ( uuid ) . packet == old_packet && uuid_data ( uuid ) . sent >= old_sent && ( uuid_data ( uuid ) . sent - old_sent ) < 32768 ) { goto attacked ; } fio_unlock ( & uuid_data ( uuid ) . sock_lock ) ; if ( ! uuid_data ( uuid ) . packet && uuid_data ( uuid ) . close ) goto closed ; return uuid_data ( uuid ) . open && uuid_data ( uuid ) . packet != NULL ; would_block : errno = EWOULDBLOCK ; return -1 ; closed : fio_force_close ( uuid ) ; return -1 ; flush_rw_hook : flushed = uuid_data ( uuid ) . rw_hooks -> flush ( uuid , uuid_data ( uuid ) . rw_udata ) ; fio_unlock ( & uuid_data ( uuid ) . sock_lock ) ; if ( ! flushed ) return 0 ; if ( flushed < 0 ) { goto test_errno ; } touchfd ( fio_uuid2fd ( uuid ) ) ; return 1 ; test_errno : fio_unlock ( & uuid_data ( uuid ) . sock_lock ) ; switch ( errno ) { case EWOULDBLOCK : #if EWOULDBLOCK != EAGAIN case EAGAIN : #endif case ENOTCONN : case EINPROGRESS : case ENOSPC : case EADDRNOTAVAIL : case EINTR : case 0 : return 1 ; case EFAULT : FIO_LOG_ERROR ( " " " " ) ; case EPIPE : case EIO : case EINVAL : case EBADF : uuid_data ( uuid ) . close = 1 ; fio_force_close ( uuid ) ; return -1 ; } FIO_LOG_DEBUG ( " \n " , ( void * ) uuid , errno , strerror ( errno ) ) ; return 0 ; invalid : errno = EBADF ; return -1 ; attacked : FIO_LOG_WARNING ( " " , ( int ) fio_peer_addr ( uuid ) . len , fio_peer_addr ( uuid ) . data ) ; fio_unlock ( & uuid_data ( uuid ) . sock_lock ) ; fio_clear_fd ( fio_uuid2fd ( uuid ) , 0 ) ; return -1 ; }
`fio_flush` attempts to write any remaining data in the internal buffer to
 the underlying file descriptor and closes the underlying file descriptor once
 if it's marked for closure (and all the data was sent).
` fio_flush ` attempts to write any remaining data in the internal buffer to the underlying file descriptor and closes the underlying file descriptor once if it ' s marked for closure ( and all the data was sent ) .
/* start critical section */ /* Slowloris attack assumed */ /* end critical section */ /* test for fio_close marker */ /* return state */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* fallthrough */ /* bad UUID */ /* don't close, just detach from facil.io and mark uuid as invalid */