static int citp_udp_setsockopt(citp_fdinfo* fdinfo, int level, int optname, const void* optval, socklen_t optlen) { citp_sock_fdi *epi = fdi_to_sock_fdi(fdinfo); citp_socket* ep = &epi->sock; ci_sock_cmn* s = ep->s; int rc; Log_VSC(log("%s("EF_FMT", %d, %d)", __FUNCTION__, EF_PRI_ARGS(epi, fdinfo->fd), level, optname)); rc = ci_udp_setsockopt(&epi->sock, fdinfo->fd, level, optname, optval, optlen); Log_V(log(LPF "setsockopt: fd=%d rc=%d", fdinfo->fd, rc)); if( rc == CI_SOCKET_HANDOVER ) { CITP_STATS_NETIF(++epi->sock.netif->state->stats.udp_handover_setsockopt); citp_fdinfo_handover(fdinfo, -1); return 0; } if( ci_opt_is_setting_reuseport(level, optname, optval, optlen) != 0 && ! CI_SOCK_NOT_BOUND(s) ) { ci_log("%s: setting reuseport after binding on udp not supported", __FUNCTION__); return -ENOSYS; } citp_fdinfo_release_ref(fdinfo, 0); return rc; }
static int citp_udp_getsockname(citp_fdinfo* fdinfo, struct sockaddr* sa, socklen_t* p_sa_len) { citp_sock_fdi *epi = fdi_to_sock_fdi(fdinfo); Log_VSC(log(LPF "getsockname("EF_FMT")", EF_PRI_ARGS(epi, fdinfo->fd))); __citp_getsockname(epi->sock.s, sa, p_sa_len); return 0; }
/* fixme kostik: this is partially copy-paste from citp_sock_fcntl */ static int citp_pipe_fcntl(citp_fdinfo* fdinfo, int cmd, long arg) { int rc = 0; citp_pipe_fdi* epi = fdi_to_pipe_fdi(fdinfo); struct oo_pipe* p = epi->pipe; switch ( cmd ) { case F_GETFL: { ci_uint32 flag_nonb = CI_PFD_AFLAG_NONBLOCK; if( ! fdi_is_reader(fdinfo) ) { rc = O_WRONLY; flag_nonb <<= CI_PFD_AFLAG_WRITER_SHIFT; } else flag_nonb <<= CI_PFD_AFLAG_READER_SHIFT; if ( p->aflags & flag_nonb ) rc |= O_NONBLOCK; break; } case F_SETFL: { ci_uint32 bit; rc = ci_sys_fcntl(fdinfo->fd, cmd, arg); if( rc < 0 ) break; bit = CI_PFD_AFLAG_NONBLOCK << (fdi_is_reader(fdinfo) ? CI_PFD_AFLAG_READER_SHIFT : CI_PFD_AFLAG_WRITER_SHIFT); if( arg & (O_NONBLOCK | O_NDELAY) ) ci_bit_mask_set(&p->aflags, bit); else ci_bit_mask_clear(&p->aflags, bit); break; } case F_DUPFD: rc = citp_ep_dup(fdinfo->fd, citp_ep_dup_fcntl_dup, arg); break; #ifdef F_DUPFD_CLOEXEC case F_DUPFD_CLOEXEC: rc = citp_ep_dup(fdinfo->fd, citp_ep_dup_fcntl_dup_cloexec, arg); break; #endif case F_GETFD: case F_SETFD: rc = ci_sys_fcntl(fdinfo->fd, cmd, arg); break; case F_GETLK: case F_SETLK: case F_SETLKW: /* File locks not supported on sockets */ Log_U(ci_log("%s: cmd %d not supported on sockets!",__FUNCTION__, cmd)); errno = ENOTSUP; rc = CI_SOCKET_ERROR; break; case F_GETOWN: case F_SETOWN: #ifdef F_GETOWN_EX case F_GETOWN_EX: #endif #ifdef F_SETOWN_EX case F_SETOWN_EX: #endif rc = ci_sys_fcntl(fdinfo->fd, cmd, arg); if( rc != 0 ) break; p->b.sigown = arg; if( p->b.sigown && (p->b.sb_aflags & CI_SB_AFLAG_O_ASYNC) ) ci_bit_set(&p->b.wake_request, CI_SB_FLAG_WAKE_RX_B); break; #ifdef F_SETPIPE_SZ case F_SETPIPE_SZ: /* System pipe buf size is rounded up to power of two. We * cannot replicate this. */ rc = ci_pipe_set_size(epi->ni, p, arg); if( rc < 0 ) { errno = EINVAL; rc = CI_SOCKET_ERROR; break; } rc = 0; break; #endif #ifdef F_GETPIPE_SZ case F_GETPIPE_SZ: rc = (p->bufs_max - 1) * OO_PIPE_BUF_MAX_SIZE; break; #endif default: /* fixme kostik: logging should include some pipe identification */ errno = ENOTSUP; rc = CI_SOCKET_ERROR; } Log_VSC(log("%s(%d, %d, %ld) = %d (errno=%d)", __FUNCTION__, fdinfo->fd, cmd, arg, rc, errno)); return rc; }