gsize socket_getInputBufferSpace(Socket* socket) { MAGIC_ASSERT(socket); utility_assert(socket->inputBufferSize >= socket->inputBufferLength); gsize bufferSize = socket_getInputBufferSize(socket); if(bufferSize < socket->inputBufferLength) { return 0; } else { return bufferSize - socket->inputBufferLength; } }
gint system_getSockOpt(gint fd, gint level, gint optname, gpointer optval, socklen_t* optlen) { if(!optlen) { errno = EFAULT; return -1; } Host* node = _system_switchInShadowContext(); Descriptor* descriptor = host_lookupDescriptor(node, fd); gint result = 0; /* TODO: implement socket options */ if(descriptor) { if(level == SOL_SOCKET || level == SOL_IP || level == SOL_TCP) { DescriptorType t = descriptor_getType(descriptor); switch (optname) { case TCP_INFO: { if(t == DT_TCPSOCKET) { if(optval) { TCP* tcp = (TCP*)descriptor; tcp_getInfo(tcp, (struct tcp_info *)optval); } *optlen = sizeof(struct tcp_info); result = 0; } else { warning("called getsockopt with TCP_INFO on non-TCP socket"); errno = ENOPROTOOPT; result = -1; } break; } case SO_SNDBUF: { if(*optlen < sizeof(gint)) { warning("called getsockopt with SO_SNDBUF with optlen < %i", (gint)(sizeof(gint))); errno = EINVAL; result = -1; } else if (t != DT_TCPSOCKET && t != DT_UDPSOCKET) { warning("called getsockopt with SO_SNDBUF on non-socket"); errno = ENOPROTOOPT; result = -1; } else { if(optval) { *((gint*) optval) = (gint) socket_getOutputBufferSize((Socket*)descriptor); } *optlen = sizeof(gint); } break; } case SO_RCVBUF: { if(*optlen < sizeof(gint)) { warning("called getsockopt with SO_RCVBUF with optlen < %i", (gint)(sizeof(gint))); errno = EINVAL; result = -1; } else if (t != DT_TCPSOCKET && t != DT_UDPSOCKET) { warning("called getsockopt with SO_RCVBUF on non-socket"); errno = ENOPROTOOPT; result = -1; } else { if(optval) { *((gint*) optval) = (gint) socket_getInputBufferSize((Socket*)descriptor); } *optlen = sizeof(gint); } break; } case SO_ERROR: { if(optval) { *((gint*)optval) = 0; } *optlen = sizeof(gint); result = 0; break; } default: { warning("getsockopt optname %i not implemented", optname); errno = ENOSYS; result = -1; break; } } } else { warning("getsockopt level %i not implemented", level); errno = ENOSYS; result = -1; } } else { errno = EBADF; result = -1; } _system_switchOutShadowContext(node); return result; }