📄 prmapopt.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * This file defines _PR_MapOptionName(). The purpose of putting * _PR_MapOptionName() in a separate file is to work around a Winsock * header file problem on Windows NT. * * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order * to use Service Pack 3 extensions), windows.h includes winsock2.h * (instead of winsock.h), which doesn't define many socket options * defined in winsock.h. * * We need the socket options defined in winsock.h. So this file * includes winsock.h, with _WIN32_WINNT undefined. */#ifdef WINNT#include <winsock.h>#endif#include "primpl.h"#if defined(NEXTSTEP)/* NEXTSTEP is special: this must come before netinet/tcp.h. */#include <netinet/in_systm.h> /* n_short, n_long, n_time */#endif#if defined(XP_UNIX) || defined(OS2) || (defined(XP_BEOS) && defined(BONE_VERSION))#include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */#endif#ifndef _PR_PTHREADSPRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data){ PRStatus rv; PRInt32 length; PRInt32 level, name; /* * PR_SockOpt_Nonblocking is a special case that does not * translate to a getsockopt() call */ if (PR_SockOpt_Nonblocking == data->option) { data->value.non_blocking = fd->secret->nonblocking; return PR_SUCCESS; } rv = _PR_MapOptionName(data->option, &level, &name); if (PR_SUCCESS == rv) { switch (data->option) { case PR_SockOpt_Linger: {#if !defined(XP_BEOS) || defined(BONE_VERSION) struct linger linger; length = sizeof(linger); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char *) &linger, &length); if (PR_SUCCESS == rv) { PR_ASSERT(sizeof(linger) == length); data->value.linger.polarity = (linger.l_onoff) ? PR_TRUE : PR_FALSE; data->value.linger.linger = PR_SecondsToInterval(linger.l_linger); } break;#else PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); return PR_FAILURE;#endif } case PR_SockOpt_Reuseaddr: case PR_SockOpt_Keepalive: case PR_SockOpt_NoDelay: case PR_SockOpt_Broadcast: {#ifdef WIN32 /* Winsock */ BOOL value;#else PRIntn value;#endif length = sizeof(value); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&value, &length); if (PR_SUCCESS == rv) data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE; break; } case PR_SockOpt_McastLoopback: {#ifdef WIN32 /* Winsock */ BOOL bool;#else PRUint8 bool;#endif length = sizeof(bool); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&bool, &length); if (PR_SUCCESS == rv) data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE; break; } case PR_SockOpt_RecvBufferSize: case PR_SockOpt_SendBufferSize: case PR_SockOpt_MaxSegment: { PRIntn value; length = sizeof(value); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&value, &length); if (PR_SUCCESS == rv) data->value.recv_buffer_size = value; break; } case PR_SockOpt_IpTimeToLive: case PR_SockOpt_IpTypeOfService: { /* These options should really be an int (or PRIntn). */ length = sizeof(PRUintn); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&data->value.ip_ttl, &length); break; } case PR_SockOpt_McastTimeToLive: {#ifdef WIN32 /* Winsock */ int ttl;#else PRUint8 ttl;#endif length = sizeof(ttl); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&ttl, &length); if (PR_SUCCESS == rv) data->value.mcast_ttl = ttl; break; }#ifdef IP_ADD_MEMBERSHIP case PR_SockOpt_AddMember: case PR_SockOpt_DropMember: { struct ip_mreq mreq; length = sizeof(mreq); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&mreq, &length); if (PR_SUCCESS == rv) { data->value.add_member.mcaddr.inet.ip = mreq.imr_multiaddr.s_addr; data->value.add_member.ifaddr.inet.ip = mreq.imr_interface.s_addr; } break; }#endif /* IP_ADD_MEMBERSHIP */ case PR_SockOpt_McastInterface: { /* This option is a struct in_addr. */ length = sizeof(data->value.mcast_if.inet.ip); rv = _PR_MD_GETSOCKOPT( fd, level, name, (char*)&data->value.mcast_if.inet.ip, &length); break; } default: PR_NOT_REACHED("Unknown socket option"); break; } } return rv;} /* _PR_SocketGetSocketOption */PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data){ PRStatus rv; PRInt32 level, name; /* * PR_SockOpt_Nonblocking is a special case that does not * translate to a setsockopt call. */ if (PR_SockOpt_Nonblocking == data->option) {#ifdef WINNT PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE) || (fd->secret->nonblocking == data->value.non_blocking)); if (fd->secret->md.io_model_committed && (fd->secret->nonblocking != data->value.non_blocking)) { /* * On NT, once we have associated a socket with the io * completion port, we can't disassociate it. So we * can't change the nonblocking option of the socket * afterwards. */ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; }#endif fd->secret->nonblocking = data->value.non_blocking; return PR_SUCCESS; } rv = _PR_MapOptionName(data->option, &level, &name); if (PR_SUCCESS == rv) { switch (data->option) { case PR_SockOpt_Linger: {#if !defined(XP_BEOS) || defined(BONE_VERSION) struct linger linger; linger.l_onoff = data->value.linger.polarity; linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger); rv = _PR_MD_SETSOCKOPT( fd, level, name, (char*)&linger, sizeof(linger)); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -