diff options
author | srinivas%netscape.com <devnull@localhost> | 1999-10-22 20:49:19 +0000 |
---|---|---|
committer | srinivas%netscape.com <devnull@localhost> | 1999-10-22 20:49:19 +0000 |
commit | f7bdd4e60380c1b5c0bc92ea06ef55d82bcd25a3 (patch) | |
tree | fac8ee0bec60218ef8014b1f842c3cc67581f6cd | |
parent | 1028ee5bd887410a9d7f70b3c397c9a1ba9d9d5f (diff) | |
download | nspr-hg-f7bdd4e60380c1b5c0bc92ea06ef55d82bcd25a3.tar.gz |
Add PR_SendFile to the PRIOMethods tables to enable use in layered FDs.
Bugzilla #17012.
-rw-r--r-- | pr/include/prio.h | 15 | ||||
-rw-r--r-- | pr/src/io/prfile.c | 18 | ||||
-rw-r--r-- | pr/src/io/priometh.c | 14 | ||||
-rw-r--r-- | pr/src/io/prlayer.c | 19 | ||||
-rw-r--r-- | pr/src/io/prpolevt.c | 8 | ||||
-rw-r--r-- | pr/src/io/prsocket.c | 110 | ||||
-rw-r--r-- | pr/src/pthreads/ptio.c | 120 |
7 files changed, 206 insertions, 98 deletions
diff --git a/pr/include/prio.h b/pr/include/prio.h index c0c6983f..49e5fdd2 100644 --- a/pr/include/prio.h +++ b/pr/include/prio.h @@ -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( diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c index aae96f12..fa05e0bd 100644 --- a/pr/src/io/prfile.c +++ b/pr/src/io/prfile.c @@ -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) diff --git a/pr/src/io/priometh.c b/pr/src/io/priometh.c index 843695ed..0203d28b 100644 --- a/pr/src/io/priometh.c +++ b/pr/src/io/priometh.c @@ -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 */ diff --git a/pr/src/io/prlayer.c b/pr/src/io/prlayer.c index d1861f93..39a5d694 100644 --- a/pr/src/io/prlayer.c +++ b/pr/src/io/prlayer.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() diff --git a/pr/src/io/prpolevt.c b/pr/src/io/prpolevt.c index 589c0a77..a345634d 100644 --- a/pr/src/io/prpolevt.c +++ b/pr/src/io/prpolevt.c @@ -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; diff --git a/pr/src/io/prsocket.c b/pr/src/io/prsocket.c index 5ebd6248..cb6dc897 100644 --- a/pr/src/io/prsocket.c +++ b/pr/src/io/prsocket.c @@ -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; -} diff --git a/pr/src/pthreads/ptio.c b/pr/src/pthreads/ptio.c index 96d5520a..e39977c4 100644 --- a/pr/src/pthreads/ptio.c +++ b/pr/src/pthreads/ptio.c @@ -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 */ |