Add PR_SendFile to the PRIOMethods tables to enable use in layered FDs.

Bugzilla #17012.
This commit is contained in:
srinivas%netscape.com 1999-10-22 20:49:19 +00:00
Родитель 9cf9ffe640
Коммит b9864b3162
7 изменённых файлов: 206 добавлений и 98 удалений

Просмотреть файл

@ -43,6 +43,7 @@ typedef union PRNetAddr PRNetAddr;
typedef struct PRIOMethods PRIOMethods;
typedef struct PRPollDesc PRPollDesc;
typedef struct PRFilePrivate PRFilePrivate;
typedef struct PRSendFileData PRSendFileData;
/*
***************************************************************************
@ -358,6 +359,10 @@ typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)(
PRFileDesc *fd, PRSocketOptionData *data);
typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
PRFileDesc *fd, const PRSocketOptionData *data);
typedef PRInt32 (PR_CALLBACK *PRSendfileFN)(
PRFileDesc *networkSocket, PRSendFileData *sendData,
PRTransmitFileFlags flags, PRIntervalTime timeout);
typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd);
struct PRIOMethods {
PRDescType file_type; /* Type of file represented (tos) */
@ -392,6 +397,12 @@ struct PRIOMethods {
/* Get current setting of specified option */
PRSetsocketoptionFN setsocketoption;
/* Set value of specified option */
PRSendfileFN sendfile; /* Send a (partial) file with header/trailer*/
PRReservedFN reserved_fn_4; /* reserved for future use */
PRReservedFN reserved_fn_3; /* reserved for future use */
PRReservedFN reserved_fn_2; /* reserved for future use */
PRReservedFN reserved_fn_1; /* reserved for future use */
PRReservedFN reserved_fn_0; /* reserved for future use */
};
/*
@ -1481,7 +1492,7 @@ PR_EXTERN(PRInt32) PR_TransmitFile(
**************************************************************************
*/
typedef struct PRSendFileData {
struct PRSendFileData {
PRFileDesc *fd; /* file to send */
PRUint32 file_offset; /* file offset */
PRSize file_nbytes; /* number of bytes of file data to send */
@ -1491,7 +1502,7 @@ typedef struct PRSendFileData {
PRInt32 hlen; /* header len */
const void *trailer; /* trailer buffer */
PRInt32 tlen; /* trailer len */
} PRSendFileData;
};
PR_EXTERN(PRInt32) PR_SendFile(

Просмотреть файл

@ -155,6 +155,7 @@ static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
return result;
}
#ifndef WIN32
static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd)
{
PRInt32 rv;
@ -168,6 +169,7 @@ static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd)
LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
return rv;
}
#endif
static PRStatus PR_CALLBACK FileInfo(PRFileDesc *fd, PRFileInfo *info)
{
@ -262,7 +264,13 @@ static PRIOMethods _pr_fileMethods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
@ -305,7 +313,13 @@ static PRIOMethods _pr_pipeMethods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)

Просмотреть файл

@ -51,7 +51,13 @@ PRIOMethods _pr_faulty_methods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
PRIntn _PR_InvalidInt()
@ -273,4 +279,10 @@ PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
return((fd->methods->setsocketoption)(fd, data));
}
PR_IMPLEMENT(PRInt32) PR_SendFile(
PRFileDesc *sd, PRSendFileData *sfd,
PRTransmitFileFlags flags, PRIntervalTime timeout)
{
return((sd->methods->sendfile)(sd,sfd,flags,timeout));
}
/* priometh.c */

Просмотреть файл

@ -355,6 +355,17 @@ static PRStatus PR_CALLBACK pl_DefSetsocketoption (
return (fd->lower->methods->setsocketoption)(fd->lower, data);
}
static PRInt32 PR_CALLBACK pl_DefSendfile (
PRFileDesc *sd, PRSendFileData *sfd,
PRTransmitFileFlags flags, PRIntervalTime timeout)
{
PR_ASSERT(sd != NULL);
PR_ASSERT(sd->lower != NULL);
return sd->lower->methods->sendfile(
sd->lower, sfd, flags, timeout);
}
/* Methods for the top of the stack. Just call down to the next fd. */
static PRIOMethods pl_methods = {
PR_DESC_LAYERED,
@ -386,7 +397,13 @@ static PRIOMethods pl_methods = {
pl_DefGetsockopt,
pl_DefSetsockopt,
pl_DefGetsocketoption,
pl_DefSetsocketoption
pl_DefSetsocketoption,
pl_DefSendfile,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods()

Просмотреть файл

@ -93,7 +93,13 @@ static PRIOMethods _pr_polevt_methods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
static PRDescIdentity _pr_polevt_id;

Просмотреть файл

@ -852,6 +852,48 @@ PR_NTFast_UpdateAcceptContext(PRFileDesc *socket, PRFileDesc *acceptSocket)
}
#endif /* WINNT */
static PRInt32 PR_CALLBACK SocketSendFile(
PRFileDesc *sd, PRSendFileData *sfd,
PRTransmitFileFlags flags, PRIntervalTime timeout)
{
PRInt32 rv;
PRThread *me = _PR_MD_CURRENT_THREAD();
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
return -1;
}
if (_PR_IO_PENDING(me)) {
PR_SetError(PR_IO_PENDING_ERROR, 0);
return -1;
}
/* The socket must be in blocking mode. */
if (sd->secret->nonblocking) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return -1;
}
#if defined(WINNT)
rv = _PR_MD_SENDFILE(sd, sfd, flags, timeout);
if ((rv >= 0) && (flags == PR_TRANSMITFILE_CLOSE_SOCKET)) {
/*
* This should be kept the same as SocketClose, except
* that _PR_MD_CLOSE_SOCKET(sd->secret->md.osfd) should
* not be called because the socket will be recycled.
*/
PR_FreeFileDesc(sd);
}
#else
#if defined(XP_UNIX)
rv = _PR_UnixSendFile(sd, sfd, flags, timeout);
#else /* XP_UNIX */
rv = _PR_EmulateSendFile(sd, sfd, flags, timeout);
#endif /* XP_UNIX */
#endif /* WINNT */
return rv;
}
static PRInt32 PR_CALLBACK SocketTransmitFile(PRFileDesc *sd, PRFileDesc *fd,
const void *headers, PRInt32 hlen, PRTransmitFileFlags flags,
PRIntervalTime timeout)
@ -866,7 +908,7 @@ PRIntervalTime timeout)
sfd.trailer = NULL;
sfd.tlen = 0;
return(PR_SendFile(sd, &sfd, flags, timeout));
return(SocketSendFile(sd, &sfd, flags, timeout));
}
static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
@ -1049,7 +1091,13 @@ static PRIOMethods tcpMethods = {
SocketGetSockOpt,
SocketSetSockOpt,
_PR_SocketGetSocketOption,
_PR_SocketSetSocketOption
_PR_SocketSetSocketOption,
SocketSendFile,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
static PRIOMethods udpMethods = {
@ -1082,7 +1130,13 @@ static PRIOMethods udpMethods = {
SocketGetSockOpt,
SocketSetSockOpt,
_PR_SocketGetSocketOption,
_PR_SocketSetSocketOption
_PR_SocketSetSocketOption,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
@ -1116,7 +1170,13 @@ static PRIOMethods socketpollfdMethods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
@ -1870,45 +1930,3 @@ out_of_memory:
#endif /* !defined(NEED_SELECT) */
}
PR_IMPLEMENT(PRInt32) PR_SendFile(
PRFileDesc *sd, PRSendFileData *sfd,
PRTransmitFileFlags flags, PRIntervalTime timeout)
{
PRInt32 rv;
PRThread *me = _PR_MD_CURRENT_THREAD();
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
return -1;
}
if (_PR_IO_PENDING(me)) {
PR_SetError(PR_IO_PENDING_ERROR, 0);
return -1;
}
/* The socket must be in blocking mode. */
if (sd->secret->nonblocking) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return -1;
}
#if defined(WINNT)
rv = _PR_MD_SENDFILE(sd, sfd, flags, timeout);
if ((rv >= 0) && (flags == PR_TRANSMITFILE_CLOSE_SOCKET)) {
/*
* This should be kept the same as SocketClose, except
* that _PR_MD_CLOSE_SOCKET(sd->secret->md.osfd) should
* not be called because the socket will be recycled.
*/
PR_FreeFileDesc(sd);
}
#else
#if defined(XP_UNIX)
rv = _PR_UnixSendFile(sd, sfd, flags, timeout);
#else /* XP_UNIX */
rv = _PR_EmulateSendFile(sd, sfd, flags, timeout);
#endif /* XP_UNIX */
#endif /* WINNT */
return rv;
}

Просмотреть файл

@ -2389,6 +2389,45 @@ static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd,
#endif /* HPUX11 */
#ifdef AIX
extern int _pr_aix_send_file_use_disabled;
#endif
static PRInt32 pt_SendFile(
PRFileDesc *sd, PRSendFileData *sfd,
PRTransmitFileFlags flags, PRIntervalTime timeout)
{
if (pt_TestAbort()) return -1;
/* The socket must be in blocking mode. */
if (sd->secret->nonblocking)
{
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return -1;
}
#ifdef HPUX11
return(pt_HPUXSendFile(sd, sfd, flags, timeout));
#elif defined(AIX)
#ifdef HAVE_SEND_FILE
/*
* A bug in AIX 4.3.2 results in corruption of data transferred by
* send_file(); AIX patch PTF U463956 contains the fix. A user can
* disable the use of send_file function in NSPR, when this patch is
* not installed on the system, by setting the envionment variable
* NSPR_AIX_SEND_FILE_USE_DISABLED to 1.
*/
if (_pr_aix_send_file_use_disabled)
return(_PR_UnixSendFile(sd, sfd, flags, timeout));
else
return(pt_AIXSendFile(sd, sfd, flags, timeout));
#else
return(_PR_UnixSendFile(sd, sfd, flags, timeout));
/* return(pt_AIXDispatchSendFile(sd, sfd, flags, timeout));*/
#endif /* HAVE_SEND_FILE */
#else
return(_PR_UnixSendFile(sd, sfd, flags, timeout));
#endif
}
static PRInt32 pt_TransmitFile(
PRFileDesc *sd, PRFileDesc *fd, const void *headers,
PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
@ -2403,7 +2442,7 @@ static PRInt32 pt_TransmitFile(
sfd.trailer = NULL;
sfd.tlen = 0;
return(PR_SendFile(sd, &sfd, flags, timeout));
return(pt_SendFile(sd, &sfd, flags, timeout));
} /* pt_TransmitFile */
/*
@ -2864,7 +2903,13 @@ static PRIOMethods _pr_file_methods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
static PRIOMethods _pr_pipe_methods = {
@ -2897,7 +2942,13 @@ static PRIOMethods _pr_pipe_methods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
static PRIOMethods _pr_tcp_methods = {
@ -2930,7 +2981,13 @@ static PRIOMethods _pr_tcp_methods = {
pt_GetSockOpt,
pt_SetSockOpt,
pt_GetSocketOption,
pt_SetSocketOption
pt_SetSocketOption,
pt_SendFile,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
static PRIOMethods _pr_udp_methods = {
@ -2963,7 +3020,13 @@ static PRIOMethods _pr_udp_methods = {
pt_GetSockOpt,
pt_SetSockOpt,
pt_GetSocketOption,
pt_SetSocketOption
pt_SetSocketOption,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
@ -2997,7 +3060,13 @@ static PRIOMethods _pr_socketpollfd_methods = {
(PRGetsockoptFN)_PR_InvalidStatus,
(PRSetsockoptFN)_PR_InvalidStatus,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt
};
#if defined(_PR_FCNTL_FLAGS)
@ -4156,45 +4225,6 @@ retry:
}
return rv;
}
#ifdef AIX
extern int _pr_aix_send_file_use_disabled;
#endif
PR_IMPLEMENT(PRInt32) PR_SendFile(
PRFileDesc *sd, PRSendFileData *sfd,
PRTransmitFileFlags flags, PRIntervalTime timeout)
{
if (pt_TestAbort()) return -1;
/* The socket must be in blocking mode. */
if (sd->secret->nonblocking)
{
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return -1;
}
#ifdef HPUX11
return(pt_HPUXSendFile(sd, sfd, flags, timeout));
#elif defined(AIX)
#ifdef HAVE_SEND_FILE
/*
* A bug in AIX 4.3.2 results in corruption of data transferred by
* send_file(); AIX patch PTF U463956 contains the fix. A user can
* disable the use of send_file function in NSPR, when this patch is
* not installed on the system, by setting the envionment variable
* NSPR_AIX_SEND_FILE_USE_DISABLED to 1.
*/
if (_pr_aix_send_file_use_disabled)
return(_PR_UnixSendFile(sd, sfd, flags, timeout));
else
return(pt_AIXSendFile(sd, sfd, flags, timeout));
#else
return(_PR_UnixSendFile(sd, sfd, flags, timeout));
/* return(pt_AIXDispatchSendFile(sd, sfd, flags, timeout));*/
#endif /* HAVE_SEND_FILE */
#else
return(_PR_UnixSendFile(sd, sfd, flags, timeout));
#endif
}
#endif /* defined(_PR_PTHREADS) */
/* ptio.c */