📄 sockopt.c
字号:
/***********************************************************************//* *//* Module: sockopt.c *//* Release: 2001.3 *//* Version: 99.0 *//* Purpose: getsockopt() and setsockopt() implementation *//* *//*---------------------------------------------------------------------*//* *//* Copyright 1999, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "../tcp_ipp.h"/***********************************************************************//* Macro Definitions *//***********************************************************************/#define Ms2Ticks(ms) ((ms) * OsTicksPerSec / 1000)#define Ticks2Ms(ticks) ((ticks) * 1000 / OsTicksPerSec)/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* getsockopt: Get setting of specified socket option *//* *//* Returns: 0 if no errors, else -1 with errno set to error code *//* *//***********************************************************************/int getsockopt(int s, int level, int optname, void *oval, int *olen){ SOCKET sock = &Socks[s - 1]; int rc = 0;#if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* Verify protocol has been initialized. */ /*-------------------------------------------------------------------*/ if (!Net.Initialized) { NetError(NULL, ENETDOWN); return -1; } /*-------------------------------------------------------------------*/ /* Check for valid socket ID. */ /*-------------------------------------------------------------------*/ if (InvalidHandle(s)) { NetError(NULL, ENOTSOCK); return -1; } /*-------------------------------------------------------------------*/ /* Check that the option is accessible and its length is correct. */ /*-------------------------------------------------------------------*/ if ((oval == NULL) || ((optname == SO_LINGER) && (*olen != sizeof(struct linger))) || ((optname != SO_LINGER) && (*olen != sizeof(int)))) { NetError(sock, EFAULT); return -1; } /*-------------------------------------------------------------------*/ /* Verify protocol level and option name consistency */ /*-------------------------------------------------------------------*/ if (level == IPPROTO_TCP) { if (optname != TCP_NODELAY) { NetError(sock, ENOPROTOOPT); return -1; } } else if (level != SOL_SOCKET) { NetError(sock, ENOPROTOOPT); return -1; }#endif /*-------------------------------------------------------------------*/ /* Gain exclusive socket API and stack internals access. */ /*-------------------------------------------------------------------*/ if (semPend(sock->api_access, WAIT_FOREVER)) { NetError(NULL, ENOTSOCK); return -1; } semPend(Net.IntSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Determine which option is requested. */ /*-------------------------------------------------------------------*/ switch (optname) { case SO_BROADCAST: /*---------------------------------------------------------------*/ /* Verify that socket type is UDP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_DGRAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output setting of UDP broadcast flag. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_BROADCAST) != 0; break; case SO_NOCHECKSUM: /*---------------------------------------------------------------*/ /* Verify that socket type is UDP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_DGRAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output setting of UDP no checksum flag. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_NOCHECKSUM) != 0; break; case SO_CONTIMEO: /*---------------------------------------------------------------*/ /* Output connect() timeout setting in milliseconds. */ /*---------------------------------------------------------------*/ *(int *)oval = Ticks2Ms(sock->connect_timeo); break; case SO_TOS: /*---------------------------------------------------------------*/ /* Output the type of service setting. */ /*---------------------------------------------------------------*/ *(int *)oval = sock->ip_tos; break; case SO_DONTROUTE: /*---------------------------------------------------------------*/ /* Output setting of omitting routing flag. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_DONTROUTE) != 0; break; case SO_KEEPALIVE: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output setting of keep-alive flag. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_KEEPALIVE) != 0; break; case SO_LINGER: { struct linger *lp = oval; /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output setting of linger and forceful close flags. */ /*---------------------------------------------------------------*/ lp->l_onoff = (sock->flags & SF_LINGER) != 0; lp->l_linger = (sock->flags & SF_FORCEFUL) == 0; break; } case SO_OOBINLINE: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output TRUE iff OOB data left in-line. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_INLINE) != 0; break; case SO_RCVBUF: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output size of receive buffer in bytes. */ /*---------------------------------------------------------------*/ *(int *)oval = sock->rb_size; break; case SO_RCVTIMEO: /*---------------------------------------------------------------*/ /* Output receive() timeout setting in milliseconds. */ /*---------------------------------------------------------------*/ *(int *)oval = Ticks2Ms(sock->recv_timeo); break; case SO_REUSEADDR: /*---------------------------------------------------------------*/ /* Output setting of local address re-use flag. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_REUSEADDR) != 0; break; case SO_SNDBUF: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output size of send buffer in bytes. */ /*---------------------------------------------------------------*/ *(int *)oval = sock->sb_size; break; case SO_SNDTIMEO: /*---------------------------------------------------------------*/ /* Output send() timeout setting in milliseconds. */ /*---------------------------------------------------------------*/ *(int *)oval = Ticks2Ms(sock->send_timeo); break; case SO_TYPE: /*---------------------------------------------------------------*/ /* Output socket type (SOCK_STREAM or SOCK_DGRAM). */ /*---------------------------------------------------------------*/ *(int *)oval = sock->type; break; case TCP_NODELAY: /*---------------------------------------------------------------*/ /* Verify that socket type is TCP. */ /*---------------------------------------------------------------*/ if (sock->type != SOCK_STREAM) { rc = -1; NetError(sock, EOPNOTSUPP); break; } /*---------------------------------------------------------------*/ /* Output TRUE iff Nagle's algorithm is disabled. */ /*---------------------------------------------------------------*/ *(int *)oval = (sock->flags & SF_NODELAY) != 0; break; default: rc = -1; NetError(sock, ENOPROTOOPT); break; } /*-------------------------------------------------------------------*/ /* Release exclusive API and internals access. */ /*-------------------------------------------------------------------*/ semPost(sock->api_access); semPost(Net.IntSem); return rc;}/***********************************************************************//* setsockopt: Set specified socket option *//* *//* Returns: 0 if no errors, else -1 with errno set to error code *//* *//***********************************************************************/int setsockopt(int s, int level, int optname, void *oval, int olen){ SOCKET sock = &Socks[s - 1]; int rc = 0;#if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* Verify protocol has been initialized. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -