VirtualBox

Ignore:
Timestamp:
Nov 10, 2023 2:01:03 PM (15 months ago)
Author:
vboxsync
Message:

libs/xpcom: Remove more now unused code from nsprpub, bugref:10545

Location:
trunk/src/libs/xpcom18a4/nsprpub/pr
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/nsprpub/pr/include/prio.h

    r101935 r102063  
    441441/*
    442442 **************************************************************************
    443  * FUNCTION: PR_GetSpecialFD
    444  * DESCRIPTION: Get the file descriptor that represents the standard input,
    445  *              output, or error stream.
    446  * INPUTS:
    447  *     PRSpecialFD id
    448  *         A value indicating the type of stream desired:
    449  *             PR_StandardInput: standard input
    450  *             PR_StandardOuput: standard output
    451  *             PR_StandardError: standard error
    452  * OUTPUTS: none
    453  * RETURNS: PRFileDesc *
    454  *     If the argument is valid, PR_GetSpecialFD returns a file descriptor
    455  *     that represents the corresponding standard I/O stream.  Otherwise,
    456  *     PR_GetSpecialFD returns NULL and sets error PR_INVALID_ARGUMENT_ERROR.
    457  **************************************************************************
    458  */
    459 
    460 typedef enum PRSpecialFD
    461 {
    462     PR_StandardInput,          /* standard input */
    463     PR_StandardOutput,         /* standard output */
    464     PR_StandardError           /* standard error */
    465 } PRSpecialFD;
    466 
    467 NSPR_API(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id);
    468 
    469 #define PR_STDIN        PR_GetSpecialFD(PR_StandardInput)
    470 #define PR_STDOUT       PR_GetSpecialFD(PR_StandardOutput)
    471 #define PR_STDERR       PR_GetSpecialFD(PR_StandardError)
    472 
    473 /*
    474  **************************************************************************
    475  * Layering file descriptors
    476  *
    477  * File descriptors may be layered. Each layer has it's own identity.
    478  * Identities are allocated by the runtime and are to be associated
    479  * (by the layer implementor) with all layers that are of that type.
    480  * It is then possible to scan the chain of layers and find a layer
    481  * that one recongizes and therefore predict that it will implement
    482  * a desired protocol.
    483  *
    484  * There are three well-known identities:
    485  *      PR_INVALID_IO_LAYER => an invalid layer identity, for error return
    486  *      PR_TOP_IO_LAYER     => the identity of the top of the stack
    487  *      PR_NSPR_IO_LAYER    => the identity used by NSPR proper
    488  * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost
    489  * layer of an existing stack. Ie., the following two constructs are
    490  * equivalent.
    491  *
    492  *      rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer);
    493  *      rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer)
    494  *
    495  * A string may be associated with the creation of the identity. It
    496  * will be copied by the runtime. If queried the runtime will return
    497  * a reference to that copied string (not yet another copy). There
    498  * is no facility for deleting an identity.
    499  **************************************************************************
    500  */
    501 
    502 #define PR_IO_LAYER_HEAD (PRDescIdentity)-3
    503 #define PR_INVALID_IO_LAYER (PRDescIdentity)-1
    504 #define PR_TOP_IO_LAYER (PRDescIdentity)-2
    505 #define PR_NSPR_IO_LAYER (PRDescIdentity)0
    506 
    507 NSPR_API(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name);
    508 NSPR_API(const char*) PR_GetNameForIdentity(PRDescIdentity ident);
    509 NSPR_API(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd);
    510 NSPR_API(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd_stack, PRDescIdentity id);
    511 
    512 /*
    513  **************************************************************************
    514  * PR_GetDefaultIOMethods: Accessing the default methods table.
    515  * You may get a pointer to the default methods table by calling this function.
    516  * You may then select any elements from that table with which to build your
    517  * layer's methods table. You may NOT modify the table directly.
    518  **************************************************************************
    519  */
    520 NSPR_API(const PRIOMethods *) PR_GetDefaultIOMethods(void);
    521 
    522 /*
    523  **************************************************************************
    524  * Creating a layer
    525  *
    526  * A new layer may be allocated by calling PR_CreateIOLayerStub(). The
    527  * file descriptor returned will contain the pointer to the methods table
    528  * provided. The runtime will not modify the table nor test its correctness.
    529  **************************************************************************
    530  */
    531 NSPR_API(PRFileDesc*) PR_CreateIOLayerStub(
    532     PRDescIdentity ident, const PRIOMethods *methods);
    533 
    534 /*
    535  **************************************************************************
    536  * Creating a layer
    537  *
    538  * A new stack may be created by calling PR_CreateIOLayer(). The
    539  * file descriptor returned will point to the top of the stack, which has
    540  * the layer 'fd' as the topmost layer.
    541  *
    542  * NOTE: This function creates a new style stack, which has a fixed, dummy
    543  * header. The old style stack, created by a call to PR_PushIOLayer,
    544  * results in modifying contents of the top layer of the stack, when
    545  * pushing and popping layers of the stack.
    546  **************************************************************************
    547  */
    548 NSPR_API(PRFileDesc*) PR_CreateIOLayer(PRFileDesc* fd);
    549 
    550 /*
    551  **************************************************************************
    552  * Pushing a layer
    553  *
    554  * A file descriptor (perhaps allocated using PR_CreateIOLayerStub()) may
    555  * be pushed into an existing stack of file descriptors at any point the
    556  * caller deems appropriate. The new layer will be inserted into the stack
    557  * just above the layer with the indicated identity.
    558  *
    559  * Note: Even if the identity parameter indicates the top-most layer of
    560  * the stack, the value of the file descriptor describing the original
    561  * stack will not change.
    562  **************************************************************************
    563  */
    564 NSPR_API(PRStatus) PR_PushIOLayer(
    565     PRFileDesc *fd_stack, PRDescIdentity id, PRFileDesc *layer);
    566 
    567 /*
    568  **************************************************************************
    569  * Popping a layer
    570  *
    571  * A layer may be popped from a stack by indicating the identity of the
    572  * layer to be removed. If found, a pointer to the removed object will
    573  * be returned to the caller. The object then becomes the responsibility
    574  * of the caller.
    575  *
    576  * Note: Even if the identity indicates the top layer of the stack, the
    577  * reference returned will not be the file descriptor for the stack and
    578  * that file descriptor will remain valid.
    579  **************************************************************************
    580  */
    581 NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id);
    582 
    583 /*
    584  **************************************************************************
    585443 * FUNCTION:    PR_Open
    586444 * DESCRIPTION:    Open a file for reading, writing, or both.
     
    763621NSPR_API(PRInt32) PR_Write(PRFileDesc *fd,const void *buf,PRInt32 amount);
    764622
    765 /*
    766  ***************************************************************************
    767  * FUNCTION: PR_Writev
    768  * DESCRIPTION:
    769  *     Write data to a socket.  The data is organized in a PRIOVec array. The
    770  *     operation will block until all the data is written or the operation
    771  *     fails.
    772  * INPUTS:
    773  *     PRFileDesc *fd
    774  *         Pointer that points to a PRFileDesc object for a socket.
    775  *     const PRIOVec *iov
    776  *         An array of PRIOVec.  PRIOVec is a struct with the following
    777  *         two fields:
    778  *             char *iov_base;
    779  *             int iov_len;
    780  *     PRInt32 iov_size
    781  *         Number of elements in the iov array. The value of this
    782  *         argument must not be greater than PR_MAX_IOVECTOR_SIZE.
    783  *         If it is, the method will fail (PR_BUFFER_OVERFLOW_ERROR).
    784  *     PRIntervalTime timeout
    785  *       Time limit for completion of the entire write operation.
    786  * OUTPUTS:
    787  *     None
    788  * RETURN:
    789  *     A positive number indicates the number of bytes successfully written.
    790  *     A -1 is an indication that the operation failed. The reason
    791  *     for the failure is obtained by calling PR_GetError().
    792  ***************************************************************************
    793  */
    794 
    795 #define PR_MAX_IOVECTOR_SIZE 16   /* 'iov_size' must be <= */
    796 
    797 NSPR_API(PRInt32) PR_Writev(
    798     PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
    799     PRIntervalTime timeout);
    800 
    801 /*
    802  ***************************************************************************
    803  * FUNCTION: PR_Delete
    804  * DESCRIPTION:
    805  *     Delete a file from the filesystem. The operation may fail if the
    806  *     file is open.
    807  * INPUTS:
    808  *     const char *name
    809  *         Path name of the file to be deleted.
    810  * OUTPUTS:
    811  *     None.
    812  * RETURN: PRStatus
    813  *     The function returns PR_SUCCESS if the file is successfully
    814  *     deleted, otherwise it returns PR_FAILURE.
    815  ***************************************************************************
    816  */
    817 
    818 NSPR_API(PRStatus) PR_Delete(const char *name);
    819 
    820623/**************************************************************************/
    821624
     
    861664NSPR_API(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info);
    862665NSPR_API(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info);
    863 
    864 /*
    865  **************************************************************************
    866  * FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64
    867  * DESCRIPTION:
    868  *     Get information about an open file referred to by the
    869  *     given PRFileDesc object.
    870  * INPUTS:
    871  *     const PRFileDesc *fd
    872  *          A reference to a valid, open file.
    873  * OUTPUTS:
    874  *     Same as PR_GetFileInfo, PR_GetFileInfo64
    875  * RETURN: PRStatus
    876  *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
    877  *     obtained, otherwise it returns PR_FAILURE.
    878  ***************************************************************************
    879  */
    880 
    881 NSPR_API(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info);
    882 NSPR_API(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info);
    883666
    884667/*
     
    918701NSPR_API(PROffset64) PR_Seek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
    919702
    920 /*
    921  ************************************************************************
    922  * FUNCTION: PR_Available
    923  * DESCRIPTION:
    924  *     Determine the amount of data in bytes available for reading
    925  *     in the given file or socket.
    926  * INPUTS:
    927  *     PRFileDesc *fd
    928  *         Pointer to a PRFileDesc object that refers to a file or
    929  *         socket.
    930  * OUTPUTS:
    931  *     None
    932  * RETURN: PRInt32, PRInt64
    933  *     Upon successful completion, PR_Available returns the number of
    934  *     bytes beyond the current read pointer that is available for
    935  *     reading.  Otherwise, it returns a -1 and the reason for the
    936  *     failure can be retrieved via PR_GetError().
    937  ************************************************************************
    938  */
    939 
    940 NSPR_API(PRInt32) PR_Available(PRFileDesc *fd);
    941 
    942 /*
    943  ************************************************************************
    944  * FUNCTION: PR_Sync
    945  * DESCRIPTION:
    946  *     Sync any buffered data for a fd to its backing device (disk).
    947  * INPUTS:
    948  *     PRFileDesc *fd
    949  *         Pointer to a PRFileDesc object that refers to a file or
    950  *         socket
    951  * OUTPUTS:
    952  *     None
    953  * RETURN: PRStatus
    954  *     PR_SUCCESS is returned if the requested access is permitted.
    955  *     Otherwise, PR_FAILURE is returned.
    956  ************************************************************************
    957  */
    958 
    959 NSPR_API(PRStatus)      PR_Sync(PRFileDesc *fd);
    960 
    961 /*
    962  *************************************************************************
    963  * FUNCTION: PR_OpenTCPSocket
    964  * DESCRIPTION:
    965  *     Create a new TCP socket of the specified address family.
    966  * INPUTS:
    967  *     PRIntn af
    968  *       Address family
    969  * OUTPUTS:
    970  *     None
    971  * RETURN: PRFileDesc*
    972  *     Upon successful completion, PR_NewTCPSocket returns a pointer
    973  *     to the PRFileDesc created for the newly opened TCP socket.
    974  *     Returns a NULL pointer if the creation of a new TCP socket failed.
    975  *
    976  **************************************************************************
    977  */
    978 
    979 NSPR_API(PRFileDesc*)    PR_OpenTCPSocket(PRIntn af);
    980 
    981 /*
    982  *************************************************************************
    983  * FUNCTION: PR_Connect
    984  * DESCRIPTION:
    985  *     Initiate a connection on a socket.
    986  * INPUTS:
    987  *     PRFileDesc *fd
    988  *       Points to a PRFileDesc object representing a socket
    989  *     PRNetAddr *addr
    990  *       Specifies the address of the socket in its own communication
    991  *       space.
    992  *     PRIntervalTime timeout
    993  *       Time limit for completion of the connect operation.
    994  * OUTPUTS:
    995  *     None
    996  * RETURN: PRStatus
    997  *     Upon successful completion of connection initiation, PR_Connect
    998  *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
    999  *     failure information can be obtained by calling PR_GetError().
    1000  **************************************************************************
    1001  */
    1002 
    1003 NSPR_API(PRStatus) PR_Connect(
    1004     PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);
    1005 
    1006 /*
    1007  *************************************************************************
    1008  * FUNCTION: PR_ConnectContinue
    1009  * DESCRIPTION:
    1010  *     Continue a nonblocking connect.  After a nonblocking connect
    1011  *     is initiated with PR_Connect() (which fails with
    1012  *     PR_IN_PROGRESS_ERROR), one should call PR_Poll() on the socket,
    1013  *     with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.  When
    1014  *     PR_Poll() returns, one calls PR_ConnectContinue() on the
    1015  *     socket to determine whether the nonblocking connect has
    1016  *     completed or is still in progress.  Repeat the PR_Poll(),
    1017  *     PR_ConnectContinue() sequence until the nonblocking connect
    1018  *     has completed.
    1019  * INPUTS:
    1020  *     PRFileDesc *fd
    1021  *         the file descriptor representing a socket
    1022  *     PRInt16 out_flags
    1023  *         the out_flags field of the poll descriptor returned by
    1024  *         PR_Poll()
    1025  * RETURN: PRStatus
    1026  *     If the nonblocking connect has successfully completed,
    1027  *     PR_ConnectContinue returns PR_SUCCESS.  If PR_ConnectContinue()
    1028  *     returns PR_FAILURE, call PR_GetError():
    1029  *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
    1030  *       progress and has not completed yet.  The caller should poll
    1031  *       on the file descriptor for the in_flags
    1032  *       PR_POLL_WRITE|PR_POLL_EXCEPT and retry PR_ConnectContinue
    1033  *       later when PR_Poll() returns.
    1034  *     - Other errors: the nonblocking connect has failed with this
    1035  *       error code.
    1036  */
    1037 
    1038 NSPR_API(PRStatus)    PR_ConnectContinue(PRFileDesc *fd, PRInt16 out_flags);
    1039 
    1040 /*
    1041  *************************************************************************
    1042  * THIS FUNCTION IS DEPRECATED.  USE PR_ConnectContinue INSTEAD.
    1043  *
    1044  * FUNCTION: PR_GetConnectStatus
    1045  * DESCRIPTION:
    1046  *     Get the completion status of a nonblocking connect.  After
    1047  *     a nonblocking connect is initiated with PR_Connect() (which
    1048  *     fails with PR_IN_PROGRESS_ERROR), one should call PR_Poll()
    1049  *     on the socket, with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.
    1050  *     When PR_Poll() returns, one calls PR_GetConnectStatus on the
    1051  *     PRPollDesc structure to determine whether the nonblocking
    1052  *     connect has succeeded or failed.
    1053  * INPUTS:
    1054  *     const PRPollDesc *pd
    1055  *         Pointer to a PRPollDesc whose fd member is the socket,
    1056  *         and in_flags must contain PR_POLL_WRITE and PR_POLL_EXCEPT.
    1057  *         PR_Poll() should have been called and set the out_flags.
    1058  * RETURN: PRStatus
    1059  *     If the nonblocking connect has successfully completed,
    1060  *     PR_GetConnectStatus returns PR_SUCCESS.  If PR_GetConnectStatus()
    1061  *     returns PR_FAILURE, call PR_GetError():
    1062  *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
    1063  *       progress and has not completed yet.
    1064  *     - Other errors: the nonblocking connect has failed with this
    1065  *       error code.
    1066  */
    1067 
    1068 NSPR_API(PRStatus)    PR_GetConnectStatus(const PRPollDesc *pd);
    1069 
    1070 /*
    1071  *************************************************************************
    1072  * FUNCTION: PR_Accept
    1073  * DESCRIPTION:
    1074  *     Accept a connection on a socket.
    1075  * INPUTS:
    1076  *     PRFileDesc *fd
    1077  *       Points to a PRFileDesc object representing the rendezvous socket
    1078  *       on which the caller is willing to accept new connections.
    1079  *     PRIntervalTime timeout
    1080  *       Time limit for completion of the accept operation.
    1081  * OUTPUTS:
    1082  *     PRNetAddr *addr
    1083  *       Returns the address of the connecting entity in its own
    1084  *       communication space. It may be NULL.
    1085  * RETURN: PRFileDesc*
    1086  *     Upon successful acceptance of a connection, PR_Accept
    1087  *     returns a valid file descriptor. Otherwise, it returns NULL.
    1088  *     Further failure information can be obtained by calling PR_GetError().
    1089  **************************************************************************
    1090  */
    1091 
    1092 NSPR_API(PRFileDesc*) PR_Accept(
    1093     PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);
    1094 
    1095 /*
    1096  *************************************************************************
    1097  * FUNCTION: PR_Bind
    1098  * DESCRIPTION:
    1099  *    Bind an address to a socket.
    1100  * INPUTS:
    1101  *     PRFileDesc *fd
    1102  *       Points to a PRFileDesc object representing a socket.
    1103  *     PRNetAddr *addr
    1104  *       Specifies the address to which the socket will be bound.
    1105  * OUTPUTS:
    1106  *     None
    1107  * RETURN: PRStatus
    1108  *     Upon successful binding of an address to a socket, PR_Bind
    1109  *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
    1110  *     failure information can be obtained by calling PR_GetError().
    1111  **************************************************************************
    1112  */
    1113 
    1114 NSPR_API(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr);
    1115 
    1116 /*
    1117  *************************************************************************
    1118  * FUNCTION: PR_Listen
    1119  * DESCRIPTION:
    1120  *    Listen for connections on a socket.
    1121  * INPUTS:
    1122  *     PRFileDesc *fd
    1123  *       Points to a PRFileDesc object representing a socket that will be
    1124  *       used to listen for new connections.
    1125  *     PRIntn backlog
    1126  *       Specifies the maximum length of the queue of pending connections.
    1127  * OUTPUTS:
    1128  *     None
    1129  * RETURN: PRStatus
    1130  *     Upon successful completion of listen request, PR_Listen
    1131  *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
    1132  *     failure information can be obtained by calling PR_GetError().
    1133  **************************************************************************
    1134  */
    1135 
    1136 NSPR_API(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog);
    1137 
    1138 /*
    1139  *************************************************************************
    1140  * FUNCTION: PR_Shutdown
    1141  * DESCRIPTION:
    1142  *    Shut down part of a full-duplex connection on a socket.
    1143  * INPUTS:
    1144  *     PRFileDesc *fd
    1145  *       Points to a PRFileDesc object representing a connected socket.
    1146  *     PRIntn how
    1147  *       Specifies the kind of disallowed operations on the socket.
    1148  *           PR_SHUTDOWN_RCV - Further receives will be disallowed
    1149  *           PR_SHUTDOWN_SEND - Further sends will be disallowed
    1150  *           PR_SHUTDOWN_BOTH - Further sends and receives will be disallowed
    1151  * OUTPUTS:
    1152  *     None
    1153  * RETURN: PRStatus
    1154  *     Upon successful completion of shutdown request, PR_Shutdown
    1155  *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
    1156  *     failure information can be obtained by calling PR_GetError().
    1157  **************************************************************************
    1158  */
    1159 
    1160 typedef enum PRShutdownHow
    1161 {
    1162     PR_SHUTDOWN_RCV = 0,      /* disallow further receives */
    1163     PR_SHUTDOWN_SEND = 1,     /* disallow further sends */
    1164     PR_SHUTDOWN_BOTH = 2      /* disallow further receives and sends */
    1165 } PRShutdownHow;
    1166 
    1167 NSPR_API(PRStatus)    PR_Shutdown(PRFileDesc *fd, PRShutdownHow how);
    1168 
    1169 /*
    1170  *************************************************************************
    1171  * FUNCTION: PR_Recv
    1172  * DESCRIPTION:
    1173  *    Receive a specified number of bytes from a connected socket.
    1174  *     The operation will block until some positive number of bytes are
    1175  *     transferred, a time out has occurred, or there is an error.
    1176  *     No more than 'amount' bytes will be transferred.
    1177  * INPUTS:
    1178  *     PRFileDesc *fd
    1179  *       points to a PRFileDesc object representing a socket.
    1180  *     void *buf
    1181  *       pointer to a buffer to hold the data received.
    1182  *     PRInt32 amount
    1183  *       the size of 'buf' (in bytes)
    1184  *     PRIntn flags
    1185  *       must be zero or PR_MSG_PEEK.
    1186  *     PRIntervalTime timeout
    1187  *       Time limit for completion of the receive operation.
    1188  * OUTPUTS:
    1189  *     None
    1190  * RETURN: PRInt32
    1191  *         a positive number indicates the number of bytes actually received.
    1192  *         0 means the network connection is closed.
    1193  *         -1 indicates a failure. The reason for the failure is obtained
    1194  *         by calling PR_GetError().
    1195  **************************************************************************
    1196  */
    1197 
    1198 #define PR_MSG_PEEK 0x2
    1199 
    1200 NSPR_API(PRInt32)    PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
    1201                 PRIntn flags, PRIntervalTime timeout);
    1202 
    1203 /*
    1204  *************************************************************************
    1205  * FUNCTION: PR_Send
    1206  * DESCRIPTION:
    1207  *    Send a specified number of bytes from a connected socket.
    1208  *     The operation will block until all bytes are
    1209  *     processed, a time out has occurred, or there is an error.
    1210  * INPUTS:
    1211  *     PRFileDesc *fd
    1212  *       points to a PRFileDesc object representing a socket.
    1213  *     void *buf
    1214  *       pointer to a buffer from where the data is sent.
    1215  *     PRInt32 amount
    1216  *       the size of 'buf' (in bytes)
    1217  *     PRIntn flags
    1218  *        (OBSOLETE - must always be zero)
    1219  *     PRIntervalTime timeout
    1220  *       Time limit for completion of the send operation.
    1221  * OUTPUTS:
    1222  *     None
    1223  * RETURN: PRInt32
    1224  *     A positive number indicates the number of bytes successfully processed.
    1225  *     This number must always equal 'amount'. A -1 is an indication that the
    1226  *     operation failed. The reason for the failure is obtained by calling
    1227  *     PR_GetError().
    1228  **************************************************************************
    1229  */
    1230 
    1231 NSPR_API(PRInt32)    PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
    1232                                 PRIntn flags, PRIntervalTime timeout);
    1233 
    1234 /*
    1235 *************************************************************************
    1236 ** FUNCTION: PR_GetSockName
    1237 ** DESCRIPTION:
    1238 **    Get socket name.  Return the network address for this socket.
    1239 **
    1240 ** INPUTS:
    1241 **     PRFileDesc *fd
    1242 **       Points to a PRFileDesc object representing the socket.
    1243 ** OUTPUTS:
    1244 **     PRNetAddr *addr
    1245 **       Returns the address of the socket in its own communication space.
    1246 ** RETURN: PRStatus
    1247 **     Upon successful completion, PR_GetSockName returns PR_SUCCESS. 
    1248 **     Otherwise, it returns PR_FAILURE.  Further failure information can
    1249 **     be obtained by calling PR_GetError().
    1250 **************************************************************************
    1251 **/
    1252 NSPR_API(PRStatus)      PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr);
    1253 
    1254 /*
    1255 *************************************************************************
    1256 ** FUNCTION: PR_GetPeerName
    1257 ** DESCRIPTION:
    1258 **    Get name of the connected peer.  Return the network address for the
    1259 **    connected peer socket.
    1260 **
    1261 ** INPUTS:
    1262 **     PRFileDesc *fd
    1263 **       Points to a PRFileDesc object representing the connected peer.
    1264 ** OUTPUTS:
    1265 **     PRNetAddr *addr
    1266 **       Returns the address of the connected peer in its own communication
    1267 **       space.
    1268 ** RETURN: PRStatus
    1269 **     Upon successful completion, PR_GetPeerName returns PR_SUCCESS. 
    1270 **     Otherwise, it returns PR_FAILURE.  Further failure information can
    1271 **     be obtained by calling PR_GetError().
    1272 **************************************************************************
    1273 **/
    1274 NSPR_API(PRStatus)      PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr);
    1275 
    1276 NSPR_API(PRStatus)      PR_GetSocketOption(
    1277     PRFileDesc *fd, PRSocketOptionData *data);
    1278 
    1279 NSPR_API(PRStatus)      PR_SetSocketOption(
    1280     PRFileDesc *fd, const PRSocketOptionData *data);
    1281 
    1282 /*
    1283  *********************************************************************
    1284  *
    1285  * File descriptor inheritance
    1286  *
    1287  *********************************************************************
    1288  */
    1289 
    1290 /*
    1291  ************************************************************************
    1292  * FUNCTION: PR_SetFDInheritable
    1293  * DESCRIPTION:
    1294  *    Set the inheritance attribute of a file descriptor.
    1295  *
    1296  * INPUTS:
    1297  *     PRFileDesc *fd
    1298  *       Points to a PRFileDesc object.
    1299  *     PRBool inheritable
    1300  *       If PR_TRUE, the file descriptor fd is set to be inheritable
    1301  *       by a child process.  If PR_FALSE, the file descriptor is set
    1302  *       to be not inheritable by a child process.
    1303  * RETURN: PRStatus
    1304  *     Upon successful completion, PR_SetFDInheritable returns PR_SUCCESS. 
    1305  *     Otherwise, it returns PR_FAILURE.  Further failure information can
    1306  *     be obtained by calling PR_GetError().
    1307  *************************************************************************
    1308  */
    1309 NSPR_API(PRStatus) PR_SetFDInheritable(
    1310     PRFileDesc *fd,
    1311     PRBool inheritable);
    1312 
    1313 /*
    1314  ************************************************************************
    1315  * FUNCTION: PR_GetInheritedFD
    1316  * DESCRIPTION:
    1317  *    Get an inherited file descriptor with the specified name.
    1318  *
    1319  * INPUTS:
    1320  *     const char *name
    1321  *       The name of the inherited file descriptor.
    1322  * RETURN: PRFileDesc *
    1323  *     Upon successful completion, PR_GetInheritedFD returns the
    1324  *     inherited file descriptor with the specified name.  Otherwise, 
    1325  *     it returns NULL.  Further failure information can be obtained
    1326  *     by calling PR_GetError().
    1327  *************************************************************************
    1328  */
    1329 NSPR_API(PRFileDesc *) PR_GetInheritedFD(const char *name);
    1330 
    1331 /*
    1332  ******************************************************************
    1333  *
    1334  * Interprocess communication
    1335  *
    1336  ******************************************************************
    1337  */
    1338 
    1339 /*
    1340  * Creates an anonymous pipe and returns file descriptors for the
    1341  * read and write ends of the pipe.
    1342  */
    1343 
    1344 NSPR_API(PRStatus) PR_CreatePipe(
    1345     PRFileDesc **readPipe,
    1346     PRFileDesc **writePipe
    1347 );
    1348 
    1349 /************************************************************************/
    1350 /************** The following definitions are for poll ******************/
    1351 /************************************************************************/
    1352 
    1353 struct PRPollDesc {
    1354     PRFileDesc* fd;
    1355     PRInt16 in_flags;
    1356     PRInt16 out_flags;
    1357 };
    1358 
    1359 /*
    1360 ** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or
    1361 ** these together to produce the desired poll request.
    1362 */
    1363 
    1364 #if defined(_PR_POLL_BACKCOMPAT)
    1365 
    1366 #include <poll.h>
    1367 #define PR_POLL_READ    POLLIN
    1368 #define PR_POLL_WRITE   POLLOUT
    1369 #define PR_POLL_EXCEPT  POLLPRI
    1370 #define PR_POLL_ERR     POLLERR     /* only in out_flags */
    1371 #define PR_POLL_NVAL    POLLNVAL    /* only in out_flags when fd is bad */
    1372 #define PR_POLL_HUP     POLLHUP     /* only in out_flags */
    1373 
    1374 #else  /* _PR_POLL_BACKCOMPAT */
    1375 
    1376 #define PR_POLL_READ    0x1
    1377 #define PR_POLL_WRITE   0x2
    1378 #define PR_POLL_EXCEPT  0x4
    1379 #define PR_POLL_ERR     0x8         /* only in out_flags */
    1380 #define PR_POLL_NVAL    0x10        /* only in out_flags when fd is bad */
    1381 #define PR_POLL_HUP     0x20        /* only in out_flags */
    1382 
    1383 #endif  /* _PR_POLL_BACKCOMPAT */
    1384 
    1385 /*
    1386 *************************************************************************
    1387 ** FUNCTION:    PR_Poll
    1388 ** DESCRIPTION:
    1389 **
    1390 ** The call returns as soon as I/O is ready on one or more of the underlying
    1391 ** socket objects. A count of the number of ready descriptors is
    1392 ** returned unless a timeout occurs in which case zero is returned.
    1393 **
    1394 ** PRPollDesc.fd should be set to a pointer to a PRFileDesc object
    1395 ** representing a socket. This field can be set to NULL to indicate to
    1396 ** PR_Poll that this PRFileDesc object should be ignored.
    1397 ** PRPollDesc.in_flags should be set to the desired request
    1398 ** (read/write/except or some combination). Upon successful return from
    1399 ** this call PRPollDesc.out_flags will be set to indicate what kind of
    1400 ** i/o can be performed on the respective descriptor. PR_Poll() uses the
    1401 ** out_flags fields as scratch variables during the call. If PR_Poll()
    1402 ** returns 0 or -1, the out_flags fields do not contain meaningful values
    1403 ** and must not be used.
    1404 **
    1405 ** INPUTS:
    1406 **      PRPollDesc *pds         A pointer to an array of PRPollDesc
    1407 **
    1408 **      PRIntn npds             The number of elements in the array
    1409 **                              If this argument is zero PR_Poll is
    1410 **                              equivalent to a PR_Sleep(timeout).
    1411 **
    1412 **      PRIntervalTime timeout  Amount of time the call will block waiting
    1413 **                              for I/O to become ready. If this time expires
    1414 **                              w/o any I/O becoming ready, the result will
    1415 **                              be zero.
    1416 **
    1417 ** OUTPUTS:    None
    1418 ** RETURN:
    1419 **      PRInt32                 Number of PRPollDesc's with events or zero
    1420 **                              if the function timed out or -1 on failure.
    1421 **                              The reason for the failure is obtained by
    1422 **                              calling PR_GetError().
    1423 **************************************************************************
    1424 */
    1425 NSPR_API(PRInt32) PR_Poll(
    1426     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout);
    1427 
    1428703PR_END_EXTERN_C
    1429704
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/io/priometh.c

    r102000 r102063  
    172172}
    173173
    174 PR_IMPLEMENT(PRStatus) PR_Connect(
    175     PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
    176 {
    177         return((fd->methods->connect)(fd,addr,timeout));
    178 }
    179 
    180 PR_IMPLEMENT(PRStatus) PR_ConnectContinue(
    181     PRFileDesc *fd, PRInt16 out_flags)
    182 {
    183         return((fd->methods->connectcontinue)(fd,out_flags));
    184 }
    185 
    186 PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr,
    187 PRIntervalTime timeout)
    188 {
    189         return((fd->methods->accept)(fd,addr,timeout));
    190 }
    191 
    192 PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr)
    193 {
    194         return((fd->methods->bind)(fd,addr));
    195 }
    196 
    197 PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how)
    198 {
    199         return((fd->methods->shutdown)(fd,how));
    200 }
    201 
    202 PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog)
    203 {
    204         return((fd->methods->listen)(fd,backlog));
    205 }
    206 
    207 PR_IMPLEMENT(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
    208 PRIntn flags, PRIntervalTime timeout)
    209 {
    210         return((fd->methods->recv)(fd,buf,amount,flags,timeout));
    211 }
    212 
    213 PR_IMPLEMENT(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
    214 PRIntn flags, PRIntervalTime timeout)
    215 {
    216         return((fd->methods->send)(fd,buf,amount,flags,timeout));
    217 }
    218 
    219 PR_IMPLEMENT(PRInt32) PR_Writev(PRFileDesc *fd, const PRIOVec *iov,
    220 PRInt32 iov_size, PRIntervalTime timeout)
    221 {
    222     if (iov_size > PR_MAX_IOVECTOR_SIZE)
    223     {
    224         PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
    225         return -1;
    226     }
    227         return((fd->methods->writev)(fd,iov,iov_size,timeout));
    228 }
    229 
    230 PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
    231 {
    232         return((fd->methods->getsockname)(fd,addr));
    233 }
    234 
    235 PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
    236 {
    237         return((fd->methods->getpeername)(fd,addr));
    238 }
    239 
    240 PR_IMPLEMENT(PRStatus) PR_GetSocketOption(
    241     PRFileDesc *fd, PRSocketOptionData *data)
    242 {
    243         return((fd->methods->getsocketoption)(fd, data));
    244 }
    245 
    246 PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
    247     PRFileDesc *fd, const PRSocketOptionData *data)
    248 {
    249         return((fd->methods->setsocketoption)(fd, data));
    250 }
    251 
    252174/* priometh.c */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/io/prstdio.c

    r1 r102063  
    6060    char* msg = PR_vsmprintf(fmt, ap);
    6161    len = strlen(msg);
    62 #ifdef XP_OS2
    63     /*
    64      * OS/2 really needs a \r for every \n.
    65      * In the future we should try to use scatter-gather instead of a
    66      * succession of PR_Write.
    67      */
    68     if (isatty(PR_FileDesc2NativeHandle(fd))) {
    69         PRUint32 last = 0, idx;
    70         PRInt32 tmp;
    71         rv = 0;
    72         for (idx = 0; idx < len+1; idx++) {
    73             if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) {
    74                 tmp = PR_Write(fd, msg + last, idx - last);
    75                 if (tmp >= 0) {
    76                     rv += tmp;
    77                 }
    78                 last = idx;
    79             }
    80             /*
    81              * if current character is \n, and
    82              * previous character isn't \r, and
    83              * next character isn't \r
    84              */
    85             if (('\n' == msg[idx]) &&
    86                 ((0 == idx) || ('\r' != msg[idx-1])) &&
    87                 ('\r' != msg[idx+1])) {
    88                 /* add extra \r */
    89                 tmp = PR_Write(fd, "\r", 1);
    90                 if (tmp >= 0) {
    91                     rv += tmp;
    92                 }
    93             }
    94         }
    95     } else {
    96         rv = PR_Write(fd, msg, len);
    97     }
    98 #else
    9962    rv = PR_Write(fd, msg, len);
    100 #endif
    10163    PR_DELETE(msg);
    10264    return rv;
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptio.c

    r102003 r102063  
    7171#endif
    7272
    73 #include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
    74 #ifdef LINUX
    75 /* TCP_CORK is not defined in <netinet/tcp.h> on Red Hat Linux 6.0 */
    76 #ifndef TCP_CORK
    77 #define TCP_CORK 3
    78 #endif
    79 #endif
    80 
    8173#include <iprt/assert.h>
    8274#include <iprt/thread.h>
    8375
    84 #ifdef DARWIN
    85 static PRBool _pr_ipv6_v6only_on_by_default;
    86 /* The IPV6_V6ONLY socket option is not defined on Mac OS X 10.1. */
    87 #ifndef IPV6_V6ONLY
    88 #define IPV6_V6ONLY 27
    89 #endif
    90 #endif
    91 
    92 #if defined(SOLARIS)
    93 #define _PRSockOptVal_t char *
    94 #elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(HPUX) \
    95     || defined(LINUX) || defined(FREEBSD) || defined(BSDI) || defined(VMS) \
    96     || defined(NTO) || defined(OPENBSD) || defined(DARWIN) \
    97     || defined(UNIXWARE) || defined(NETBSD)
    98 #define _PRSockOptVal_t void *
    99 #else
    100 #error "Cannot determine architecture"
    101 #endif
    102 
    103 #if (defined(HPUX) && !defined(HPUX10_30) && !defined(HPUX11))
    104 #define _PRSelectFdSetArg_t int *
    105 #elif defined(AIX4_1)
    106 #define _PRSelectFdSetArg_t void *
    107 #elif defined(IRIX) || (defined(AIX) && !defined(AIX4_1)) \
    108     || defined(OSF1) || defined(SOLARIS) \
    109     || defined(HPUX10_30) || defined(HPUX11) || defined(LINUX) \
    110     || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
    111     || defined(BSDI) || defined(VMS) || defined(NTO) || defined(DARWIN) \
    112     || defined(UNIXWARE)
    113 #define _PRSelectFdSetArg_t fd_set *
    114 #else
    115 #error "Cannot determine architecture"
    116 #endif
    117 
    118 static PRFileDesc *pt_SetMethods(
    119     PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported);
    120 
    12176static PRLock *_pr_rename_lock;  /* For PR_Rename() */
    12277
    12378/**************************************************************************/
    124 
    125 /* These two functions are only used in assertions. */
    126 #ifdef RT_STRICT
    127 
    128 PRBool IsValidNetAddr(const PRNetAddr *addr)
    129 {
    130     if ((addr != NULL)
    131             && (addr->raw.family != AF_UNIX)
    132             && (addr->raw.family != PR_AF_INET6)
    133             && (addr->raw.family != AF_INET)) {
    134         return PR_FALSE;
    135     }
    136     return PR_TRUE;
    137 }
    138 
    139 static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
    140 {
    141     /*
    142      * The definition of the length of a Unix domain socket address
    143      * is not uniform, so we don't check it.
    144      */
    145     if ((addr != NULL)
    146             && (addr->raw.family != AF_UNIX)
    147             && (PR_NETADDR_SIZE(addr) != addr_len)) {
    148 #if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1
    149         /*
    150          * In glibc 2.1, struct sockaddr_in6 is 24 bytes.  In glibc 2.2
    151          * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id
    152          * field and is 28 bytes.  It is possible for socket functions
    153          * to return an addr_len greater than sizeof(struct sockaddr_in6).
    154          * We need to allow that.  (Bugzilla bug #77264)
    155          */
    156         if ((PR_AF_INET6 == addr->raw.family)
    157                 && (sizeof(addr->ipv6) == addr_len)) {
    158             return PR_TRUE;
    159         }
    160 #endif
    161         return PR_FALSE;
    162     }
    163     return PR_TRUE;
    164 }
    165 
    166 #endif /* DEBUG */
    16779
    16880/*****************************************************************************/
     
    17587 */
    17688#define PT_DEFAULT_POLL_MSEC 5000
    177 
    178 /*
    179  * pt_SockLen is the type for the length of a socket address
    180  * structure, used in the address length argument to bind,
    181  * connect, accept, getsockname, getpeername, etc.  Posix.1g
    182  * defines this type as socklen_t.  It is size_t or int on
    183  * most current systems.
    184  */
    185 #if defined(HAVE_SOCKLEN_T) \
    186     || (defined(LINUX) && defined(__GLIBC__) && __GLIBC__ >= 2)
    187 typedef socklen_t pt_SockLen;
    188 #elif (defined(AIX) && !defined(AIX4_1)) \
    189     || defined(VMS)
    190 typedef PRSize pt_SockLen;
    191 #else
    192 typedef PRIntn pt_SockLen;
    193 #endif
    19489
    19590typedef struct pt_Continuation pt_Continuation;
     
    210105    union {
    211106        PRSize amount;                      /* #3 - size of 'buffer', or */
    212         pt_SockLen *addr_len;                  /*    - length of address */
    213107    } arg3;
    214108    union { PRIntn flags; } arg4;           /* #4 - read/write flags */
     
    290184    fd->dtor = NULL;
    291185    fd->lower = fd->higher = NULL;
    292     fd->identity = PR_NSPR_IO_LAYER;
    293186    memset(fd->secret, 0, sizeof(PRFilePrivate));
    294187    return fd;
     
    453346/*********************** specific continuation functions *********************/
    454347/*****************************************************************************/
    455 static PRBool pt_connect_cont(pt_Continuation *op, PRInt16 revents)
    456 {
    457     op->syserrno = _MD_unix_get_nonblocking_connect_error(op->arg1.osfd);
    458     if (op->syserrno != 0) {
    459         op->result.code = -1;
    460     } else {
    461         op->result.code = 0;
    462     }
    463     return PR_TRUE; /* this one is cooked */
    464 }  /* pt_connect_cont */
    465 
    466 static PRBool pt_accept_cont(pt_Continuation *op, PRInt16 revents)
    467 {
    468     op->syserrno = 0;
    469     op->result.code = accept(
    470         op->arg1.osfd, op->arg2.buffer, op->arg3.addr_len);
    471     if (-1 == op->result.code)
    472     {
    473         op->syserrno = errno;
    474         if (EWOULDBLOCK == errno || EAGAIN == errno || ECONNABORTED == errno)
    475             return PR_FALSE;  /* do nothing - this one ain't finished */
    476     }
    477     return PR_TRUE;
    478 }  /* pt_accept_cont */
    479 
    480348static PRBool pt_read_cont(pt_Continuation *op, PRInt16 revents)
    481349{
     
    492360        PR_FALSE : PR_TRUE;
    493361}  /* pt_read_cont */
    494 
    495 static PRBool pt_recv_cont(pt_Continuation *op, PRInt16 revents)
    496 {
    497     /*
    498      * Any number of bytes will complete the operation. It need
    499      * not (and probably will not) satisfy the request. The only
    500      * error we continue is EWOULDBLOCK|EAGAIN.
    501      */
    502 #if defined(SOLARIS)
    503     if (0 == op->arg4.flags)
    504         op->result.code = read(
    505             op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
    506     else
    507         op->result.code = recv(
    508             op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
    509 #else
    510     op->result.code = recv(
    511         op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
    512 #endif
    513     op->syserrno = errno;
    514     return ((-1 == op->result.code) &&
    515             (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
    516         PR_FALSE : PR_TRUE;
    517 }  /* pt_recv_cont */
    518 
    519 static PRBool pt_send_cont(pt_Continuation *op, PRInt16 revents)
    520 {
    521     PRIntn bytes;
    522 #if defined(SOLARIS)
    523     PRInt32 tmp_amount = op->arg3.amount;
    524 #endif
    525     /*
    526      * We want to write the entire amount out, no matter how many
    527      * tries it takes. Keep advancing the buffer and the decrementing
    528      * the amount until the amount goes away. Return the total bytes
    529      * (which should be the original amount) when finished (or an
    530      * error).
    531      */
    532 #if defined(SOLARIS)
    533 retry:
    534     bytes = write(op->arg1.osfd, op->arg2.buffer, tmp_amount);
    535 #else
    536     bytes = send(
    537         op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
    538 #endif
    539     op->syserrno = errno;
    540 
    541 #if defined(SOLARIS)
    542     /*
    543      * The write system call has been reported to return the ERANGE error
    544      * on occasion. Try to write in smaller chunks to workaround this bug.
    545      */
    546     if ((bytes == -1) && (op->syserrno == ERANGE))
    547     {
    548         if (tmp_amount > 1)
    549         {
    550             tmp_amount = tmp_amount/2;  /* half the bytes */
    551             goto retry;
    552         }
    553     }
    554 #endif
    555 
    556     if (bytes >= 0)  /* this is progress */
    557     {
    558         char *bp = (char*)op->arg2.buffer;
    559         bp += bytes;  /* adjust the buffer pointer */
    560         op->arg2.buffer = bp;
    561         op->result.code += bytes;  /* accumulate the number sent */
    562         op->arg3.amount -= bytes;  /* and reduce the required count */
    563         return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
    564     }
    565     else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
    566     {
    567         op->result.code = -1;
    568         return PR_TRUE;
    569     }
    570     else return PR_FALSE;
    571 }  /* pt_send_cont */
    572362
    573363static PRBool pt_write_cont(pt_Continuation *op, PRInt16 revents)
     
    651441    _pr_rename_lock = PR_NewLock();
    652442    Assert(NULL != _pr_rename_lock);
    653 
    654     _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE, PR_TRUE);
    655     _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE, PR_TRUE);
    656     _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE, PR_TRUE);
    657     Assert(_pr_stdin && _pr_stdout && _pr_stderr);
    658 
    659 #ifdef DARWIN
    660     /* In Mac OS X v10.3 Panther Beta the IPV6_V6ONLY socket option
    661      * is turned on by default, contrary to what RFC 3493, Section
    662      * 5.3 says.  So we have to turn it off.  Find out whether we
    663      * are running on such a system.
    664      */
    665     {
    666         int osfd;
    667         osfd = socket(AF_INET6, SOCK_STREAM, 0);
    668         if (osfd != -1) {
    669             int on;
    670             int optlen = sizeof(on);
    671             if (getsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY,
    672                     &on, &optlen) == 0) {
    673                 _pr_ipv6_v6only_on_by_default = on;
    674             }
    675             close(osfd);
    676         }
    677     }
    678 #endif
    679443}  /* _PR_InitIO */
    680444
    681445void _PR_CleanupIO(void)
    682446{
    683     _PR_Putfd(_pr_stdin);
    684     _pr_stdin = NULL;
    685     _PR_Putfd(_pr_stdout);
    686     _pr_stdout = NULL;
    687     _PR_Putfd(_pr_stderr);
    688     _pr_stderr = NULL;
    689 
    690447    if (_pr_rename_lock)
    691448    {
     
    694451    }
    695452}  /* _PR_CleanupIO */
    696 
    697 PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
    698 {
    699     PRFileDesc *result = NULL;
    700     Assert(osfd >= PR_StandardInput && osfd <= PR_StandardError);
    701 
    702     if (!_pr_initialized) _PR_ImplicitInitialization();
    703 
    704     switch (osfd)
    705     {
    706         case PR_StandardInput: result = _pr_stdin; break;
    707         case PR_StandardOutput: result = _pr_stdout; break;
    708         case PR_StandardError: result = _pr_stderr; break;
    709         default:
    710             (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    711     }
    712     return result;
    713 }  /* PR_GetSpecialFD */
    714453
    715454/*****************************************************************************/
     
    852591}  /* pt_Write */
    853592
    854 static PRInt32 pt_Writev(
    855     PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_len, PRIntervalTime timeout)
    856 {
    857     PRIntn iov_index;
    858     PRBool fNeedContinue = PR_FALSE;
    859     PRInt32 syserrno, bytes, rv = -1;
    860     struct iovec osiov_local[PR_MAX_IOVECTOR_SIZE], *osiov;
    861     int osiov_len;
    862 
    863     if (pt_TestAbort()) return rv;
    864 
    865     /* Ensured by PR_Writev */
    866     Assert(iov_len <= PR_MAX_IOVECTOR_SIZE);
    867 
    868     /*
    869      * We can't pass iov to writev because PRIOVec and struct iovec
    870      * may not be binary compatible.  Make osiov a copy of iov and
    871      * pass osiov to writev.  We can modify osiov if we need to
    872      * continue the operation.
    873      */
    874     osiov = osiov_local;
    875     osiov_len = iov_len;
    876     for (iov_index = 0; iov_index < osiov_len; iov_index++)
    877     {
    878         osiov[iov_index].iov_base = iov[iov_index].iov_base;
    879         osiov[iov_index].iov_len = iov[iov_index].iov_len;
    880     }
    881 
    882     rv = bytes = writev(fd->secret->md.osfd, osiov, osiov_len);
    883     syserrno = errno;
    884 
    885     if (!fd->secret->nonblocking)
    886     {
    887         if (bytes >= 0)
    888         {
    889             /*
    890              * If we moved some bytes, how does that implicate the
    891              * i/o vector list?  In other words, exactly where are
    892              * we within that array?  What are the parameters for
    893              * resumption?  Maybe we're done!
    894              */
    895             for ( ;osiov_len > 0; osiov++, osiov_len--)
    896             {
    897                 if (bytes < osiov->iov_len)
    898                 {
    899                     /* this one's not done yet */
    900                     osiov->iov_base = (char*)osiov->iov_base + bytes;
    901                     osiov->iov_len -= bytes;
    902                     break;  /* go off and do that */
    903                 }
    904                 bytes -= osiov->iov_len;  /* this one's done cooked */
    905             }
    906             Assert(osiov_len > 0 || bytes == 0);
    907             if (osiov_len > 0)
    908             {
    909                 if (PR_INTERVAL_NO_WAIT == timeout)
    910                 {
    911                     rv = -1;
    912                     syserrno = ETIMEDOUT;
    913                 }
    914                 else fNeedContinue = PR_TRUE;
    915             }
    916         }
    917         else if (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
    918         {
    919             if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
    920             else
    921             {
    922                 rv = 0;
    923                 fNeedContinue = PR_TRUE;
    924             }
    925         }
    926     }
    927 
    928     if (fNeedContinue == PR_TRUE)
    929     {
    930         pt_Continuation op;
    931 
    932         op.arg1.osfd = fd->secret->md.osfd;
    933         op.arg2.buffer = (void*)osiov;
    934         op.arg3.amount = osiov_len;
    935         op.timeout = timeout;
    936         op.result.code = rv;
    937         op.function = pt_writev_cont;
    938         op.event = POLLOUT | POLLPRI;
    939         rv = pt_Continue(&op);
    940         syserrno = op.syserrno;
    941     }
    942     if (rv == -1) pt_MapError(_PR_MD_MAP_WRITEV_ERROR, syserrno);
    943     return rv;
    944 }  /* pt_Writev */
    945 
    946593static PRInt32 pt_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
    947594{
     
    972619    return result;
    973620}  /* pt_Available_f */
    974 
    975 static PRInt32 pt_Available_s(PRFileDesc *fd)
    976 {
    977     PRInt32 rv, bytes = -1;
    978     if (pt_TestAbort()) return bytes;
    979 
    980     rv = ioctl(fd->secret->md.osfd, FIONREAD, &bytes);
    981 
    982     if (rv == -1)
    983         pt_MapError(_PR_MD_MAP_SOCKETAVAILABLE_ERROR, errno);
    984     return bytes;
    985 }  /* pt_Available_s */
    986621
    987622static PRStatus pt_FileInfo(PRFileDesc *fd, PRFileInfo *info)
     
    996631    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
    997632}  /* pt_FileInfo64 */
    998 
    999 static PRStatus pt_Synch(PRFileDesc *fd)
    1000 {
    1001     return (NULL == fd) ? PR_FAILURE : PR_SUCCESS;
    1002 } /* pt_Synch */
    1003633
    1004634static PRStatus pt_Fsync(PRFileDesc *fd)
     
    1015645}  /* pt_Fsync */
    1016646
    1017 static PRStatus pt_Connect(
    1018     PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
    1019 {
    1020     PRIntn rv = -1, syserrno;
    1021     pt_SockLen addr_len;
    1022         const PRNetAddr *addrp = addr;
    1023 #if defined(_PR_HAVE_SOCKADDR_LEN)
    1024         PRUint16 md_af = addr->raw.family;
    1025     PRNetAddr addrCopy;
    1026 #endif
    1027 
    1028     if (pt_TestAbort()) return PR_FAILURE;
    1029 
    1030     Assert(IsValidNetAddr(addr) == PR_TRUE);
    1031     addr_len = PR_NETADDR_SIZE(addr);
    1032 
    1033 #ifdef _PR_HAVE_SOCKADDR_LEN
    1034     addrCopy = *addr;
    1035     ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
    1036     ((struct sockaddr*)&addrCopy)->sa_family = md_af;
    1037     rv = connect(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len);
    1038 #else
    1039     rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
    1040 #endif
    1041     syserrno = errno;
    1042     if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking))
    1043     {
    1044         if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
    1045         else
    1046         {
    1047             pt_Continuation op;
    1048             op.arg1.osfd = fd->secret->md.osfd;
    1049 #ifdef _PR_HAVE_SOCKADDR_LEN
    1050             op.arg2.buffer = (void*)&addrCopy;
    1051 #else
    1052             op.arg2.buffer = (void*)addr;
    1053 #endif
    1054             op.arg3.amount = addr_len;
    1055             op.timeout = timeout;
    1056             op.function = pt_connect_cont;
    1057             op.event = POLLOUT | POLLPRI;
    1058             rv = pt_Continue(&op);
    1059             syserrno = op.syserrno;
    1060         }
    1061     }
    1062     if (-1 == rv) {
    1063         pt_MapError(_PR_MD_MAP_CONNECT_ERROR, syserrno);
    1064         return PR_FAILURE;
    1065     }
    1066     return PR_SUCCESS;
    1067 }  /* pt_Connect */
    1068 
    1069 static PRStatus pt_ConnectContinue(
    1070     PRFileDesc *fd, PRInt16 out_flags)
    1071 {
    1072     int err;
    1073     PRInt32 osfd;
    1074 
    1075     if (out_flags & PR_POLL_NVAL)
    1076     {
    1077         PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
    1078         return PR_FAILURE;
    1079     }
    1080     if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0)
    1081     {
    1082         Assert(out_flags == 0);
    1083         PR_SetError(PR_IN_PROGRESS_ERROR, 0);
    1084         return PR_FAILURE;
    1085     }
    1086 
    1087     osfd = fd->secret->md.osfd;
    1088 
    1089     err = _MD_unix_get_nonblocking_connect_error(osfd);
    1090     if (err != 0)
    1091     {
    1092         _PR_MD_MAP_CONNECT_ERROR(err);
    1093         return PR_FAILURE;
    1094     }
    1095     return PR_SUCCESS;
    1096 }  /* pt_ConnectContinue */
    1097 
    1098 PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
    1099 {
    1100     /* Find the NSPR layer and invoke its connectcontinue method */
    1101     PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
    1102 
    1103     if (NULL == bottom)
    1104     {
    1105         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    1106         return PR_FAILURE;
    1107     }
    1108     return pt_ConnectContinue(bottom, pd->out_flags);
    1109 }  /* PR_GetConnectStatus */
    1110 
    1111 static PRFileDesc* pt_Accept(
    1112     PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
    1113 {
    1114     PRFileDesc *newfd = NULL;
    1115     PRIntn syserrno, osfd = -1;
    1116     pt_SockLen addr_len = sizeof(PRNetAddr);
    1117 
    1118     if (pt_TestAbort()) return newfd;
    1119 
    1120 #ifdef _PR_STRICT_ADDR_LEN
    1121     if (addr)
    1122     {
    1123         /*
    1124          * Set addr->raw.family just so that we can use the
    1125          * PR_NETADDR_SIZE macro.
    1126          */
    1127         addr->raw.family = fd->secret->af;
    1128         addr_len = PR_NETADDR_SIZE(addr);
    1129     }
    1130 #endif
    1131 
    1132     osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
    1133     syserrno = errno;
    1134 
    1135     if (osfd == -1)
    1136     {
    1137         if (fd->secret->nonblocking) goto failed;
    1138 
    1139         if (EWOULDBLOCK != syserrno && EAGAIN != syserrno
    1140         && ECONNABORTED != syserrno)
    1141             goto failed;
    1142         else
    1143         {
    1144             if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
    1145             else
    1146             {
    1147                 pt_Continuation op;
    1148                 op.arg1.osfd = fd->secret->md.osfd;
    1149                 op.arg2.buffer = addr;
    1150                 op.arg3.addr_len = &addr_len;
    1151                 op.timeout = timeout;
    1152                 op.function = pt_accept_cont;
    1153                 op.event = POLLIN | POLLPRI;
    1154                 osfd = pt_Continue(&op);
    1155                 syserrno = op.syserrno;
    1156             }
    1157             if (osfd < 0) goto failed;
    1158         }
    1159     }
    1160 #ifdef _PR_HAVE_SOCKADDR_LEN
    1161     /* ignore the sa_len field of struct sockaddr */
    1162     if (addr)
    1163     {
    1164         addr->raw.family = ((struct sockaddr*)addr)->sa_family;
    1165     }
    1166 #endif /* _PR_HAVE_SOCKADDR_LEN */
    1167     newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_TRUE, PR_FALSE);
    1168     if (newfd == NULL) close(osfd);  /* $$$ whoops! this doesn't work $$$ */
    1169     else
    1170     {
    1171         Assert(IsValidNetAddr(addr) == PR_TRUE);
    1172         Assert(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
    1173 #ifdef LINUX
    1174         /*
    1175          * On Linux, experiments showed that the accepted sockets
    1176          * inherit the TCP_NODELAY socket option of the listening
    1177          * socket.
    1178          */
    1179         newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay;
    1180 #endif
    1181     }
    1182     return newfd;
    1183 
    1184 failed:
    1185     pt_MapError(_PR_MD_MAP_ACCEPT_ERROR, syserrno);
    1186     return NULL;
    1187 }  /* pt_Accept */
    1188 
    1189 static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
    1190 {
    1191     PRIntn rv;
    1192     pt_SockLen addr_len;
    1193         const PRNetAddr *addrp = addr;
    1194 #if defined(_PR_HAVE_SOCKADDR_LEN)
    1195         PRUint16 md_af = addr->raw.family;
    1196     PRNetAddr addrCopy;
    1197 #endif
    1198 
    1199     if (pt_TestAbort()) return PR_FAILURE;
    1200 
    1201     Assert(IsValidNetAddr(addr) == PR_TRUE);
    1202     if (addr->raw.family == AF_UNIX)
    1203     {
    1204         /* Disallow relative pathnames */
    1205         if (addr->local.path[0] != '/')
    1206         {
    1207             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    1208             return PR_FAILURE;
    1209         }
    1210     }
    1211 
    1212     addr_len = PR_NETADDR_SIZE(addr);
    1213 #ifdef _PR_HAVE_SOCKADDR_LEN
    1214     addrCopy = *addr;
    1215     ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
    1216     ((struct sockaddr*)&addrCopy)->sa_family = md_af;
    1217     rv = bind(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len);
    1218 #else
    1219     rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
    1220 #endif
    1221 
    1222     if (rv == -1) {
    1223         pt_MapError(_PR_MD_MAP_BIND_ERROR, errno);
    1224         return PR_FAILURE;
    1225     }
    1226     return PR_SUCCESS;
    1227 }  /* pt_Bind */
    1228 
    1229 static PRStatus pt_Listen(PRFileDesc *fd, PRIntn backlog)
    1230 {
    1231     PRIntn rv;
    1232 
    1233     if (pt_TestAbort()) return PR_FAILURE;
    1234 
    1235     rv = listen(fd->secret->md.osfd, backlog);
    1236     if (rv == -1) {
    1237         pt_MapError(_PR_MD_MAP_LISTEN_ERROR, errno);
    1238         return PR_FAILURE;
    1239     }
    1240     return PR_SUCCESS;
    1241 }  /* pt_Listen */
    1242 
    1243 static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how)
    1244 {
    1245     PRIntn rv = -1;
    1246     if (pt_TestAbort()) return PR_FAILURE;
    1247 
    1248     rv = shutdown(fd->secret->md.osfd, how);
    1249 
    1250     if (rv == -1) {
    1251         pt_MapError(_PR_MD_MAP_SHUTDOWN_ERROR, errno);
    1252         return PR_FAILURE;
    1253     }
    1254     return PR_SUCCESS;
    1255 }  /* pt_Shutdown */
    1256 
    1257647static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
    1258648{
     
    1260650    return in_flags;
    1261651}  /* pt_Poll */
    1262 
    1263 static PRInt32 pt_Recv(
    1264     PRFileDesc *fd, void *buf, PRInt32 amount,
    1265     PRIntn flags, PRIntervalTime timeout)
    1266 {
    1267     PRInt32 syserrno, bytes = -1;
    1268     PRIntn osflags;
    1269 
    1270     if (0 == flags)
    1271         osflags = 0;
    1272     else if (PR_MSG_PEEK == flags)
    1273         osflags = MSG_PEEK;
    1274     else
    1275     {
    1276         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    1277         return bytes;
    1278     }
    1279 
    1280     if (pt_TestAbort()) return bytes;
    1281 
    1282     /* recv() is a much slower call on pre-2.6 Solaris than read(). */
    1283 #if defined(SOLARIS)
    1284     if (0 == osflags)
    1285         bytes = read(fd->secret->md.osfd, buf, amount);
    1286     else
    1287         bytes = recv(fd->secret->md.osfd, buf, amount, osflags);
    1288 #else
    1289     bytes = recv(fd->secret->md.osfd, buf, amount, osflags);
    1290 #endif
    1291     syserrno = errno;
    1292 
    1293     if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
    1294         && (!fd->secret->nonblocking))
    1295     {
    1296         if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
    1297         else
    1298         {
    1299             pt_Continuation op;
    1300             op.arg1.osfd = fd->secret->md.osfd;
    1301             op.arg2.buffer = buf;
    1302             op.arg3.amount = amount;
    1303             op.arg4.flags = osflags;
    1304             op.timeout = timeout;
    1305             op.function = pt_recv_cont;
    1306             op.event = POLLIN | POLLPRI;
    1307             bytes = pt_Continue(&op);
    1308             syserrno = op.syserrno;
    1309         }
    1310     }
    1311     if (bytes < 0)
    1312         pt_MapError(_PR_MD_MAP_RECV_ERROR, syserrno);
    1313     return bytes;
    1314 }  /* pt_Recv */
    1315 
    1316 static PRInt32 pt_SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount)
    1317 {
    1318     return pt_Recv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
    1319 }  /* pt_SocketRead */
    1320 
    1321 static PRInt32 pt_Send(
    1322     PRFileDesc *fd, const void *buf, PRInt32 amount,
    1323     PRIntn flags, PRIntervalTime timeout)
    1324 {
    1325     PRInt32 syserrno, bytes = -1;
    1326     PRBool fNeedContinue = PR_FALSE;
    1327 #if defined(SOLARIS)
    1328         PRInt32 tmp_amount = amount;
    1329 #endif
    1330 
    1331     /*
    1332      * Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h,
    1333      * which has the following:
    1334      *     #  define send        cma_send
    1335      *     extern int  cma_send (int , void *, int, int );
    1336      * So we need to cast away the 'const' of argument #2 for send().
    1337      */
    1338 #if defined (HPUX) && defined(_PR_DCETHREADS)
    1339 #define PT_SENDBUF_CAST (void *)
    1340 #else
    1341 #define PT_SENDBUF_CAST
    1342 #endif
    1343 
    1344     if (pt_TestAbort()) return bytes;
    1345 
    1346     /*
    1347      * On pre-2.6 Solaris, send() is much slower than write().
    1348      * On 2.6 and beyond, with in-kernel sockets, send() and
    1349      * write() are fairly equivalent in performance.
    1350      */
    1351 #if defined(SOLARIS)
    1352     Assert(0 == flags);
    1353 retry:
    1354     bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount);
    1355 #else
    1356     bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags);
    1357 #endif
    1358     syserrno = errno;
    1359 
    1360 #if defined(SOLARIS)
    1361     /*
    1362      * The write system call has been reported to return the ERANGE error
    1363      * on occasion. Try to write in smaller chunks to workaround this bug.
    1364      */
    1365     if ((bytes == -1) && (syserrno == ERANGE))
    1366     {
    1367         if (tmp_amount > 1)
    1368         {
    1369             tmp_amount = tmp_amount/2;  /* half the bytes */
    1370             goto retry;
    1371         }
    1372     }
    1373 #endif
    1374 
    1375     if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )
    1376     {
    1377         if (PR_INTERVAL_NO_WAIT == timeout)
    1378         {
    1379             bytes = -1;
    1380             syserrno = ETIMEDOUT;
    1381         }
    1382         else
    1383         {
    1384             buf = (char *) buf + bytes;
    1385             amount -= bytes;
    1386             fNeedContinue = PR_TRUE;
    1387         }
    1388     }
    1389     if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
    1390         && (!fd->secret->nonblocking) )
    1391     {
    1392         if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
    1393         else
    1394         {
    1395             bytes = 0;
    1396             fNeedContinue = PR_TRUE;
    1397         }
    1398     }
    1399 
    1400     if (fNeedContinue == PR_TRUE)
    1401     {
    1402         pt_Continuation op;
    1403         op.arg1.osfd = fd->secret->md.osfd;
    1404         op.arg2.buffer = (void*)buf;
    1405         op.arg3.amount = amount;
    1406         op.arg4.flags = flags;
    1407         op.timeout = timeout;
    1408         op.result.code = bytes;  /* initialize the number sent */
    1409         op.function = pt_send_cont;
    1410         op.event = POLLOUT | POLLPRI;
    1411         bytes = pt_Continue(&op);
    1412         syserrno = op.syserrno;
    1413     }
    1414     if (bytes == -1)
    1415         pt_MapError(_PR_MD_MAP_SEND_ERROR, syserrno);
    1416     return bytes;
    1417 }  /* pt_Send */
    1418 
    1419 static PRInt32 pt_SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
    1420 {
    1421     return pt_Send(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
    1422 }  /* pt_SocketWrite */
    1423 
    1424 static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
    1425 {
    1426     PRIntn rv = -1;
    1427     pt_SockLen addr_len = sizeof(PRNetAddr);
    1428 
    1429     if (pt_TestAbort()) return PR_FAILURE;
    1430 
    1431     rv = getsockname(
    1432         fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
    1433     if (rv == -1) {
    1434         pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno);
    1435         return PR_FAILURE;
    1436     } else {
    1437 #ifdef _PR_HAVE_SOCKADDR_LEN
    1438         /* ignore the sa_len field of struct sockaddr */
    1439         if (addr)
    1440         {
    1441             addr->raw.family = ((struct sockaddr*)addr)->sa_family;
    1442         }
    1443 #endif /* _PR_HAVE_SOCKADDR_LEN */
    1444 
    1445         Assert(IsValidNetAddr(addr) == PR_TRUE);
    1446         Assert(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
    1447         return PR_SUCCESS;
    1448     }
    1449 }  /* pt_GetSockName */
    1450 
    1451 static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
    1452 {
    1453     PRIntn rv = -1;
    1454     pt_SockLen addr_len = sizeof(PRNetAddr);
    1455 
    1456     if (pt_TestAbort()) return PR_FAILURE;
    1457 
    1458     rv = getpeername(
    1459         fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
    1460 
    1461     if (rv == -1) {
    1462         pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno);
    1463         return PR_FAILURE;
    1464     } else {
    1465 #ifdef _PR_HAVE_SOCKADDR_LEN
    1466         /* ignore the sa_len field of struct sockaddr */
    1467         if (addr)
    1468         {
    1469             addr->raw.family = ((struct sockaddr*)addr)->sa_family;
    1470         }
    1471 #endif /* _PR_HAVE_SOCKADDR_LEN */
    1472 
    1473         Assert(IsValidNetAddr(addr) == PR_TRUE);
    1474         Assert(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
    1475         return PR_SUCCESS;
    1476     }
    1477 }  /* pt_GetPeerName */
    1478 
    1479 static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
    1480 {
    1481     PRIntn rv;
    1482     pt_SockLen length;
    1483     PRInt32 level, name;
    1484 
    1485     /*
    1486      * PR_SockOpt_Nonblocking is a special case that does not
    1487      * translate to a getsockopt() call
    1488      */
    1489     if (PR_SockOpt_Nonblocking == data->option)
    1490     {
    1491         data->value.non_blocking = fd->secret->nonblocking;
    1492         return PR_SUCCESS;
    1493     }
    1494 
    1495     rv = _PR_MapOptionName(data->option, &level, &name);
    1496     if (PR_SUCCESS == rv)
    1497     {
    1498         switch (data->option)
    1499         {
    1500             case PR_SockOpt_Linger:
    1501             {
    1502                 struct linger linger;
    1503                 length = sizeof(linger);
    1504                 rv = getsockopt(
    1505                     fd->secret->md.osfd, level, name, (char *) &linger, &length);
    1506                 Assert((-1 == rv) || (sizeof(linger) == length));
    1507                 data->value.linger.polarity =
    1508                     (linger.l_onoff) ? PR_TRUE : PR_FALSE;
    1509                 data->value.linger.linger =
    1510                     PR_SecondsToInterval(linger.l_linger);
    1511                 break;
    1512             }
    1513             case PR_SockOpt_Reuseaddr:
    1514             case PR_SockOpt_Keepalive:
    1515             case PR_SockOpt_NoDelay:
    1516             case PR_SockOpt_Broadcast:
    1517             {
    1518                 PRIntn value;
    1519                 length = sizeof(PRIntn);
    1520                 rv = getsockopt(
    1521                     fd->secret->md.osfd, level, name, (char*)&value, &length);
    1522                 Assert((-1 == rv) || (sizeof(PRIntn) == length));
    1523                 data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
    1524                 break;
    1525             }
    1526             case PR_SockOpt_McastLoopback:
    1527             {
    1528                 PRUint8 xbool;
    1529                 length = sizeof(xbool);
    1530                 rv = getsockopt(
    1531                     fd->secret->md.osfd, level, name,
    1532                     (char*)&xbool, &length);
    1533                 Assert((-1 == rv) || (sizeof(xbool) == length));
    1534                 data->value.mcast_loopback = (0 == xbool) ? PR_FALSE : PR_TRUE;
    1535                 break;
    1536             }
    1537             case PR_SockOpt_RecvBufferSize:
    1538             case PR_SockOpt_SendBufferSize:
    1539             case PR_SockOpt_MaxSegment:
    1540             {
    1541                 PRIntn value;
    1542                 length = sizeof(PRIntn);
    1543                 rv = getsockopt(
    1544                     fd->secret->md.osfd, level, name, (char*)&value, &length);
    1545                 Assert((-1 == rv) || (sizeof(PRIntn) == length));
    1546                 data->value.recv_buffer_size = value;
    1547                 break;
    1548             }
    1549             case PR_SockOpt_IpTimeToLive:
    1550             case PR_SockOpt_IpTypeOfService:
    1551             {
    1552                 length = sizeof(PRUintn);
    1553                 rv = getsockopt(
    1554                     fd->secret->md.osfd, level, name,
    1555                     (char*)&data->value.ip_ttl, &length);
    1556                 Assert((-1 == rv) || (sizeof(PRIntn) == length));
    1557                 break;
    1558             }
    1559             case PR_SockOpt_McastTimeToLive:
    1560             {
    1561                 PRUint8 ttl;
    1562                 length = sizeof(ttl);
    1563                 rv = getsockopt(
    1564                     fd->secret->md.osfd, level, name,
    1565                     (char*)&ttl, &length);
    1566                 Assert((-1 == rv) || (sizeof(ttl) == length));
    1567                 data->value.mcast_ttl = ttl;
    1568                 break;
    1569             }
    1570             case PR_SockOpt_AddMember:
    1571             case PR_SockOpt_DropMember:
    1572             {
    1573                 struct ip_mreq mreq;
    1574                 length = sizeof(mreq);
    1575                 rv = getsockopt(
    1576                     fd->secret->md.osfd, level, name, (char*)&mreq, &length);
    1577                 Assert((-1 == rv) || (sizeof(mreq) == length));
    1578                 data->value.add_member.mcaddr.inet.ip =
    1579                     mreq.imr_multiaddr.s_addr;
    1580                 data->value.add_member.ifaddr.inet.ip =
    1581                     mreq.imr_interface.s_addr;
    1582                 break;
    1583             }
    1584             case PR_SockOpt_McastInterface:
    1585             {
    1586                 length = sizeof(data->value.mcast_if.inet.ip);
    1587                 rv = getsockopt(
    1588                     fd->secret->md.osfd, level, name,
    1589                     (char*)&data->value.mcast_if.inet.ip, &length);
    1590                 Assert((-1 == rv)
    1591                     || (sizeof(data->value.mcast_if.inet.ip) == length));
    1592                 break;
    1593             }
    1594             default:
    1595                 break;
    1596         }
    1597         if (-1 == rv) _PR_MD_MAP_GETSOCKOPT_ERROR(errno);
    1598     }
    1599     return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
    1600 }  /* pt_GetSocketOption */
    1601 
    1602 static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
    1603 {
    1604     PRIntn rv;
    1605     PRInt32 level, name;
    1606 
    1607     /*
    1608      * PR_SockOpt_Nonblocking is a special case that does not
    1609      * translate to a setsockopt call.
    1610      */
    1611     if (PR_SockOpt_Nonblocking == data->option)
    1612     {
    1613         fd->secret->nonblocking = data->value.non_blocking;
    1614         return PR_SUCCESS;
    1615     }
    1616 
    1617     rv = _PR_MapOptionName(data->option, &level, &name);
    1618     if (PR_SUCCESS == rv)
    1619     {
    1620         switch (data->option)
    1621         {
    1622             case PR_SockOpt_Linger:
    1623             {
    1624                 struct linger linger;
    1625                 linger.l_onoff = data->value.linger.polarity;
    1626                 linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
    1627                 rv = setsockopt(
    1628                     fd->secret->md.osfd, level, name, (char*)&linger, sizeof(linger));
    1629                 break;
    1630             }
    1631             case PR_SockOpt_Reuseaddr:
    1632             case PR_SockOpt_Keepalive:
    1633             case PR_SockOpt_NoDelay:
    1634             case PR_SockOpt_Broadcast:
    1635             {
    1636                 PRIntn value = (data->value.reuse_addr) ? 1 : 0;
    1637                 rv = setsockopt(
    1638                     fd->secret->md.osfd, level, name,
    1639                     (char*)&value, sizeof(PRIntn));
    1640 #ifdef LINUX
    1641                 /* for pt_Linux1 */
    1642                 if (name == TCP_NODELAY && rv == 0) {
    1643                     fd->secret->md.tcp_nodelay = value;
    1644                 }
    1645 #endif
    1646                 break;
    1647             }
    1648             case PR_SockOpt_McastLoopback:
    1649             {
    1650                 PRUint8 xbool = data->value.mcast_loopback ? 1 : 0;
    1651                 rv = setsockopt(
    1652                     fd->secret->md.osfd, level, name,
    1653                     (char*)&xbool, sizeof(xbool));
    1654                 break;
    1655             }
    1656             case PR_SockOpt_RecvBufferSize:
    1657             case PR_SockOpt_SendBufferSize:
    1658             case PR_SockOpt_MaxSegment:
    1659             {
    1660                 PRIntn value = data->value.recv_buffer_size;
    1661                 rv = setsockopt(
    1662                     fd->secret->md.osfd, level, name,
    1663                     (char*)&value, sizeof(PRIntn));
    1664                 break;
    1665             }
    1666             case PR_SockOpt_IpTimeToLive:
    1667             case PR_SockOpt_IpTypeOfService:
    1668             {
    1669                 rv = setsockopt(
    1670                     fd->secret->md.osfd, level, name,
    1671                     (char*)&data->value.ip_ttl, sizeof(PRUintn));
    1672                 break;
    1673             }
    1674             case PR_SockOpt_McastTimeToLive:
    1675             {
    1676                 PRUint8 ttl = data->value.mcast_ttl;
    1677                 rv = setsockopt(
    1678                     fd->secret->md.osfd, level, name,
    1679                     (char*)&ttl, sizeof(ttl));
    1680                 break;
    1681             }
    1682             case PR_SockOpt_AddMember:
    1683             case PR_SockOpt_DropMember:
    1684             {
    1685                 struct ip_mreq mreq;
    1686                 mreq.imr_multiaddr.s_addr =
    1687                     data->value.add_member.mcaddr.inet.ip;
    1688                 mreq.imr_interface.s_addr =
    1689                     data->value.add_member.ifaddr.inet.ip;
    1690                 rv = setsockopt(
    1691                     fd->secret->md.osfd, level, name,
    1692                     (char*)&mreq, sizeof(mreq));
    1693                 break;
    1694             }
    1695             case PR_SockOpt_McastInterface:
    1696             {
    1697                 rv = setsockopt(
    1698                     fd->secret->md.osfd, level, name,
    1699                     (char*)&data->value.mcast_if.inet.ip,
    1700                     sizeof(data->value.mcast_if.inet.ip));
    1701                 break;
    1702             }
    1703             default:
    1704                 break;
    1705         }
    1706         if (-1 == rv) _PR_MD_MAP_SETSOCKOPT_ERROR(errno);
    1707     }
    1708     return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
    1709 }  /* pt_SetSocketOption */
    1710652
    1711653/*****************************************************************************/
     
    1746688};
    1747689
    1748 static PRIOMethods _pr_pipe_methods = {
    1749     PR_DESC_PIPE,
    1750     pt_Close,
    1751     pt_Read,
    1752     pt_Write,
    1753     pt_Available_s,
    1754     pt_Synch,
    1755     (PRSeekFN)_PR_InvalidInt,
    1756     (PRSeek64FN)_PR_InvalidInt64,
    1757     (PRFileInfoFN)_PR_InvalidStatus,
    1758     (PRFileInfo64FN)_PR_InvalidStatus,
    1759     (PRWritevFN)_PR_InvalidInt,
    1760     (PRConnectFN)_PR_InvalidStatus,
    1761     (PRAcceptFN)_PR_InvalidDesc,
    1762     (PRBindFN)_PR_InvalidStatus,
    1763     (PRListenFN)_PR_InvalidStatus,
    1764     (PRShutdownFN)_PR_InvalidStatus,
    1765     (PRRecvFN)_PR_InvalidInt,
    1766     (PRSendFN)_PR_InvalidInt,
    1767     pt_Poll,
    1768     (PRGetsocknameFN)_PR_InvalidStatus,
    1769     (PRGetpeernameFN)_PR_InvalidStatus,
    1770     (PRReservedFN)_PR_InvalidInt,
    1771     (PRReservedFN)_PR_InvalidInt,
    1772     (PRGetsocketoptionFN)_PR_InvalidStatus,
    1773     (PRSetsocketoptionFN)_PR_InvalidStatus,
    1774     (PRConnectcontinueFN)_PR_InvalidStatus,
    1775     (PRReservedFN)_PR_InvalidInt,
    1776     (PRReservedFN)_PR_InvalidInt,
    1777     (PRReservedFN)_PR_InvalidInt,
    1778     (PRReservedFN)_PR_InvalidInt
    1779 };
    1780 
    1781 static PRIOMethods _pr_tcp_methods = {
    1782     PR_DESC_SOCKET_TCP,
    1783     pt_Close,
    1784     pt_SocketRead,
    1785     pt_SocketWrite,
    1786     pt_Available_s,
    1787     pt_Synch,
    1788     (PRSeekFN)_PR_InvalidInt,
    1789     (PRSeek64FN)_PR_InvalidInt64,
    1790     (PRFileInfoFN)_PR_InvalidStatus,
    1791     (PRFileInfo64FN)_PR_InvalidStatus,
    1792     pt_Writev,
    1793     pt_Connect,
    1794     pt_Accept,
    1795     pt_Bind,
    1796     pt_Listen,
    1797     pt_Shutdown,
    1798     pt_Recv,
    1799     pt_Send,
    1800     pt_Poll,
    1801     pt_GetSockName,
    1802     pt_GetPeerName,
    1803     (PRReservedFN)_PR_InvalidInt,
    1804     (PRReservedFN)_PR_InvalidInt,
    1805     pt_GetSocketOption,
    1806     pt_SetSocketOption,
    1807     pt_ConnectContinue,
    1808     (PRReservedFN)_PR_InvalidInt,
    1809     (PRReservedFN)_PR_InvalidInt,
    1810     (PRReservedFN)_PR_InvalidInt,
    1811     (PRReservedFN)_PR_InvalidInt
    1812 };
    1813 
    1814 static PRIOMethods _pr_socketpollfd_methods = {
    1815     (PRDescType) 0,
    1816     (PRCloseFN)_PR_InvalidStatus,
    1817     (PRReadFN)_PR_InvalidInt,
    1818     (PRWriteFN)_PR_InvalidInt,
    1819     (PRAvailableFN)_PR_InvalidInt,
    1820     (PRFsyncFN)_PR_InvalidStatus,
    1821     (PRSeekFN)_PR_InvalidInt,
    1822     (PRSeek64FN)_PR_InvalidInt64,
    1823     (PRFileInfoFN)_PR_InvalidStatus,
    1824     (PRFileInfo64FN)_PR_InvalidStatus,
    1825     (PRWritevFN)_PR_InvalidInt,
    1826     (PRConnectFN)_PR_InvalidStatus,
    1827     (PRAcceptFN)_PR_InvalidDesc,
    1828     (PRBindFN)_PR_InvalidStatus,
    1829     (PRListenFN)_PR_InvalidStatus,
    1830     (PRShutdownFN)_PR_InvalidStatus,
    1831     (PRRecvFN)_PR_InvalidInt,
    1832     (PRSendFN)_PR_InvalidInt,
    1833         pt_Poll,
    1834     (PRGetsocknameFN)_PR_InvalidStatus,
    1835     (PRGetpeernameFN)_PR_InvalidStatus,
    1836     (PRReservedFN)_PR_InvalidInt,
    1837     (PRReservedFN)_PR_InvalidInt,
    1838     (PRGetsocketoptionFN)_PR_InvalidStatus,
    1839     (PRSetsocketoptionFN)_PR_InvalidStatus,
    1840     (PRConnectcontinueFN)_PR_InvalidStatus,
    1841     (PRReservedFN)_PR_InvalidInt,
    1842     (PRReservedFN)_PR_InvalidInt,
    1843     (PRReservedFN)_PR_InvalidInt,
    1844     (PRReservedFN)_PR_InvalidInt
    1845 };
    1846 
    1847 #if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \
    1848     || defined(AIX) || defined(LINUX) || defined(FREEBSD) || defined(NETBSD) \
    1849     || defined(OPENBSD) || defined(BSDI) || defined(VMS) || defined(NTO) \
    1850     || defined(DARWIN) || defined(UNIXWARE)
    1851 #define _PR_FCNTL_FLAGS O_NONBLOCK
    1852 #else
    1853 #error "Can't determine architecture"
    1854 #endif
    1855 
    1856 /*
    1857  * Put a Unix file descriptor in non-blocking mode.
    1858  */
    1859 static void pt_MakeFdNonblock(PRIntn osfd)
    1860 {
    1861     PRIntn flags;
    1862     flags = fcntl(osfd, F_GETFL, 0);
    1863     flags |= _PR_FCNTL_FLAGS;
    1864     (void)fcntl(osfd, F_SETFL, flags);
    1865 }
    1866 
    1867 /*
    1868  * Put a Unix socket fd in non-blocking mode that can
    1869  * ideally be inherited by an accepted socket.
    1870  *
    1871  * Why doesn't pt_MakeFdNonblock do?  This is to deal with
    1872  * the special case of HP-UX.  HP-UX has three kinds of
    1873  * non-blocking modes for sockets: the fcntl() O_NONBLOCK
    1874  * and O_NDELAY flags and ioctl() FIOSNBIO request.  Only
    1875  * the ioctl() FIOSNBIO form of non-blocking mode is
    1876  * inherited by an accepted socket.
    1877  *
    1878  * Other platforms just use the generic pt_MakeFdNonblock
    1879  * to put a socket in non-blocking mode.
    1880  */
    1881 #ifdef HPUX
    1882 static void pt_MakeSocketNonblock(PRIntn osfd)
    1883 {
    1884     PRIntn one = 1;
    1885     (void)ioctl(osfd, FIOSNBIO, &one);
    1886 }
    1887 #else
    1888 #define pt_MakeSocketNonblock pt_MakeFdNonblock
    1889 #endif
    1890 
    1891690static PRFileDesc *pt_SetMethods(
    1892691    PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported)
     
    1910709        {
    1911710            case PR_DESC_FILE:
    1912                 fd->methods = PR_GetFileMethods();
    1913                 break;
    1914             case PR_DESC_SOCKET_TCP:
    1915                 fd->methods = PR_GetTCPMethods();
    1916 #ifdef _PR_ACCEPT_INHERIT_NONBLOCK
    1917                 if (!isAcceptedSocket) pt_MakeSocketNonblock(osfd);
    1918 #else
    1919                 pt_MakeSocketNonblock(osfd);
    1920 #endif
    1921                 break;
    1922             case PR_DESC_PIPE:
    1923                 fd->methods = PR_GetPipeMethods();
    1924                 pt_MakeFdNonblock(osfd);
     711                fd->methods = &_pr_file_methods;
    1925712                break;
    1926713            default:
     
    1930717    return fd;
    1931718}  /* pt_SetMethods */
    1932 
    1933 PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
    1934 {
    1935     return &_pr_file_methods;
    1936 }  /* PR_GetFileMethods */
    1937 
    1938 PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
    1939 {
    1940     return &_pr_pipe_methods;
    1941 }  /* PR_GetPipeMethods */
    1942 
    1943 PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods(void)
    1944 {
    1945     return &_pr_tcp_methods;
    1946 }  /* PR_GetTCPMethods */
    1947 
    1948 static const PRIOMethods* PR_GetSocketPollFdMethods(void)
    1949 {
    1950     return &_pr_socketpollfd_methods;
    1951 }  /* PR_GetSocketPollFdMethods */
    1952 
    1953 PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
    1954     PRInt32 osfd, const PRIOMethods *methods)
    1955 {
    1956     PRFileDesc *fd = _PR_Getfd();
    1957 
    1958     if (NULL == fd) goto failed;
    1959 
    1960     fd->methods = methods;
    1961     fd->secret->md.osfd = osfd;
    1962     /* Make fd non-blocking */
    1963     if (osfd > 2)
    1964     {
    1965         /* Don't mess around with stdin, stdout or stderr */
    1966         if (&_pr_tcp_methods == methods) pt_MakeSocketNonblock(osfd);
    1967         else pt_MakeFdNonblock(osfd);
    1968     }
    1969     fd->secret->state = _PR_FILEDESC_OPEN;
    1970     fd->secret->inheritable = _PR_TRI_UNKNOWN;
    1971     return fd;
    1972 
    1973 failed:
    1974     PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    1975     return fd;
    1976 }  /* PR_AllocFileDesc */
    1977 
    1978 #ifdef VBOX
    1979 PRUintn _PR_NetAddrSize(const PRNetAddr* addr)
    1980 {
    1981     PRUintn addrsize;
    1982 
    1983 #if defined(XP_UNIX) || defined(XP_OS2_EMX)
    1984     if (AF_UNIX == addr->raw.family)
    1985         addrsize = sizeof(addr->local);
    1986 #endif
    1987     else addrsize = 0;
    1988 
    1989     return addrsize;
    1990 }  /* _PR_NetAddrSize */
    1991 #endif
    1992 
    1993 PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
    1994 {
    1995     PRIntn osfd;
    1996     PRDescType ftype;
    1997     PRFileDesc *fd = NULL;
    1998         PRInt32 tmp_domain = domain;
    1999 
    2000     if (!_pr_initialized) _PR_ImplicitInitialization();
    2001 
    2002     if (pt_TestAbort()) return NULL;
    2003 
    2004     if (PF_UNIX != domain)
    2005     {
    2006         PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
    2007         return fd;
    2008     }
    2009         if (type == SOCK_STREAM) ftype = PR_DESC_SOCKET_TCP;
    2010         else if (type == SOCK_DGRAM) ftype = PR_DESC_SOCKET_UDP;
    2011         else
    2012         {
    2013                 (void)PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
    2014                 return fd;
    2015         }
    2016 
    2017     osfd = socket(domain, type, proto);
    2018     if (osfd == -1) pt_MapError(_PR_MD_MAP_SOCKET_ERROR, errno);
    2019     else
    2020     {
    2021         fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE);
    2022         if (fd == NULL) close(osfd);
    2023     }
    2024 #ifdef _PR_STRICT_ADDR_LEN
    2025     if (fd != NULL) fd->secret->af = domain;
    2026 #endif
    2027     return fd;
    2028 }  /* PR_Socket */
    2029719
    2030720/*****************************************************************************/
     
    2092782}  /* PR_Open */
    2093783
    2094 PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
    2095 {
    2096     PRIntn rv = -1;
    2097 
    2098     if (!_pr_initialized) _PR_ImplicitInitialization();
    2099 
    2100     if (pt_TestAbort()) return PR_FAILURE;
    2101 
    2102     rv = unlink(name);
    2103 
    2104     if (rv == -1) {
    2105         pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno);
    2106         return PR_FAILURE;
    2107     } else
    2108         return PR_SUCCESS;
    2109 }  /* PR_Delete */
    2110 
    2111 PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
    2112 {
    2113     PRInt32 rv = _PR_MD_GETFILEINFO(fn, info);
    2114     return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
    2115 }  /* PR_GetFileInfo */
    2116 
    2117784PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
    2118785{
     
    2124791}  /* PR_GetFileInfo64 */
    2125792
    2126 static PRInt32 _pr_poll_with_poll(
    2127     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
    2128 {
    2129     PRInt32 ready = 0;
    2130     /*
    2131      * For restarting poll() if it is interrupted by a signal.
    2132      * We use these variables to figure out how much time has
    2133      * elapsed and how much of the timeout still remains.
    2134      */
    2135     PRIntervalTime start, elapsed, remaining;
    2136 
    2137     if (pt_TestAbort()) return -1;
    2138 
    2139     if (0 == npds) RTThreadSleep(PR_IntervalToMilliseconds(timeout));
    2140     else
    2141     {
    2142 #define STACK_POLL_DESC_COUNT 64
    2143         struct pollfd stack_syspoll[STACK_POLL_DESC_COUNT];
    2144         struct pollfd *syspoll;
    2145         PRIntn index, msecs;
    2146 
    2147         if (npds <= STACK_POLL_DESC_COUNT)
    2148         {
    2149             syspoll = stack_syspoll;
    2150         }
    2151         else
    2152         {
    2153             PRThread *me = PR_GetCurrentThread();
    2154             if (npds > me->syspoll_count)
    2155             {
    2156                 PR_Free(me->syspoll_list);
    2157                 me->syspoll_list =
    2158                     (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
    2159                 if (NULL == me->syspoll_list)
    2160                 {
    2161                     me->syspoll_count = 0;
    2162                     PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    2163                     return -1;
    2164                 }
    2165                 me->syspoll_count = npds;
    2166             }
    2167             syspoll = me->syspoll_list;
    2168         }
    2169 
    2170         for (index = 0; index < npds; ++index)
    2171         {
    2172             PRInt16 in_flags_read = 0, in_flags_write = 0;
    2173             PRInt16 out_flags_read = 0, out_flags_write = 0;
    2174 
    2175             if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
    2176             {
    2177                 if (pds[index].in_flags & PR_POLL_READ)
    2178                 {
    2179                     in_flags_read = (pds[index].fd->methods->poll)(
    2180                         pds[index].fd,
    2181                         pds[index].in_flags & ~PR_POLL_WRITE,
    2182                         &out_flags_read);
    2183                 }
    2184                 if (pds[index].in_flags & PR_POLL_WRITE)
    2185                 {
    2186                     in_flags_write = (pds[index].fd->methods->poll)(
    2187                         pds[index].fd,
    2188                         pds[index].in_flags & ~PR_POLL_READ,
    2189                         &out_flags_write);
    2190                 }
    2191                 if ((0 != (in_flags_read & out_flags_read))
    2192                 || (0 != (in_flags_write & out_flags_write)))
    2193                 {
    2194                     /* this one is ready right now */
    2195                     if (0 == ready)
    2196                     {
    2197                         /*
    2198                          * We will return without calling the system
    2199                          * poll function.  So zero the out_flags
    2200                          * fields of all the poll descriptors before
    2201                          * this one.
    2202                          */
    2203                         int i;
    2204                         for (i = 0; i < index; i++)
    2205                         {
    2206                             pds[i].out_flags = 0;
    2207                         }
    2208                     }
    2209                     ready += 1;
    2210                     pds[index].out_flags = out_flags_read | out_flags_write;
    2211                 }
    2212                 else
    2213                 {
    2214                     /* now locate the NSPR layer at the bottom of the stack */
    2215                     PRFileDesc *bottom = PR_GetIdentitiesLayer(
    2216                         pds[index].fd, PR_NSPR_IO_LAYER);
    2217                     Assert(NULL != bottom);  /* what to do about that? */
    2218                     pds[index].out_flags = 0;  /* pre-condition */
    2219                     if ((NULL != bottom)
    2220                     && (_PR_FILEDESC_OPEN == bottom->secret->state))
    2221                     {
    2222                         if (0 == ready)
    2223                         {
    2224                             syspoll[index].fd = bottom->secret->md.osfd;
    2225                             syspoll[index].events = 0;
    2226                             if (in_flags_read & PR_POLL_READ)
    2227                             {
    2228                                 pds[index].out_flags |=
    2229                                     _PR_POLL_READ_SYS_READ;
    2230                                 syspoll[index].events |= POLLIN;
    2231                             }
    2232                             if (in_flags_read & PR_POLL_WRITE)
    2233                             {
    2234                                 pds[index].out_flags |=
    2235                                     _PR_POLL_READ_SYS_WRITE;
    2236                                 syspoll[index].events |= POLLOUT;
    2237                             }
    2238                             if (in_flags_write & PR_POLL_READ)
    2239                             {
    2240                                 pds[index].out_flags |=
    2241                                     _PR_POLL_WRITE_SYS_READ;
    2242                                 syspoll[index].events |= POLLIN;
    2243                             }
    2244                             if (in_flags_write & PR_POLL_WRITE)
    2245                             {
    2246                                 pds[index].out_flags |=
    2247                                     _PR_POLL_WRITE_SYS_WRITE;
    2248                                 syspoll[index].events |= POLLOUT;
    2249                             }
    2250                             if (pds[index].in_flags & PR_POLL_EXCEPT)
    2251                                 syspoll[index].events |= POLLPRI;
    2252                         }
    2253                     }
    2254                     else
    2255                     {
    2256                         if (0 == ready)
    2257                         {
    2258                             int i;
    2259                             for (i = 0; i < index; i++)
    2260                             {
    2261                                 pds[i].out_flags = 0;
    2262                             }
    2263                         }
    2264                         ready += 1;  /* this will cause an abrupt return */
    2265                         pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
    2266                     }
    2267                 }
    2268             }
    2269             else
    2270             {
    2271                 /* make poll() ignore this entry */
    2272                 syspoll[index].fd = -1;
    2273                 syspoll[index].events = 0;
    2274                 pds[index].out_flags = 0;
    2275             }
    2276         }
    2277         if (0 == ready)
    2278         {
    2279             switch (timeout)
    2280             {
    2281             case PR_INTERVAL_NO_WAIT: msecs = 0; break;
    2282             case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;
    2283             default:
    2284                 msecs = PR_IntervalToMilliseconds(timeout);
    2285                 start = PR_IntervalNow();
    2286             }
    2287 
    2288 retry:
    2289             ready = poll(syspoll, npds, msecs);
    2290             if (-1 == ready)
    2291             {
    2292                 PRIntn oserror = errno;
    2293 
    2294                 if (EINTR == oserror)
    2295                 {
    2296                     if (timeout == PR_INTERVAL_NO_TIMEOUT)
    2297                         goto retry;
    2298                     else if (timeout == PR_INTERVAL_NO_WAIT)
    2299                         ready = 0;  /* don't retry, just time out */
    2300                     else
    2301                     {
    2302                         elapsed = (PRIntervalTime) (PR_IntervalNow()
    2303                                 - start);
    2304                         if (elapsed > timeout)
    2305                             ready = 0;  /* timed out */
    2306                         else
    2307                         {
    2308                             remaining = timeout - elapsed;
    2309                             msecs = PR_IntervalToMilliseconds(remaining);
    2310                             goto retry;
    2311                         }
    2312                     }
    2313                 }
    2314                 else
    2315                 {
    2316                     _PR_MD_MAP_POLL_ERROR(oserror);
    2317                 }
    2318             }
    2319             else if (ready > 0)
    2320             {
    2321                 for (index = 0; index < npds; ++index)
    2322                 {
    2323                     PRInt16 out_flags = 0;
    2324                     if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
    2325                     {
    2326                         if (0 != syspoll[index].revents)
    2327                         {
    2328                             if (syspoll[index].revents & POLLIN)
    2329                             {
    2330                                 if (pds[index].out_flags
    2331                                 & _PR_POLL_READ_SYS_READ)
    2332                                 {
    2333                                     out_flags |= PR_POLL_READ;
    2334                                 }
    2335                                 if (pds[index].out_flags
    2336                                 & _PR_POLL_WRITE_SYS_READ)
    2337                                 {
    2338                                     out_flags |= PR_POLL_WRITE;
    2339                                 }
    2340                             }
    2341                             if (syspoll[index].revents & POLLOUT)
    2342                             {
    2343                                 if (pds[index].out_flags
    2344                                 & _PR_POLL_READ_SYS_WRITE)
    2345                                 {
    2346                                     out_flags |= PR_POLL_READ;
    2347                                 }
    2348                                 if (pds[index].out_flags
    2349                                 & _PR_POLL_WRITE_SYS_WRITE)
    2350                                 {
    2351                                     out_flags |= PR_POLL_WRITE;
    2352                                 }
    2353                             }
    2354                             if (syspoll[index].revents & POLLPRI)
    2355                                 out_flags |= PR_POLL_EXCEPT;
    2356                             if (syspoll[index].revents & POLLERR)
    2357                                 out_flags |= PR_POLL_ERR;
    2358                             if (syspoll[index].revents & POLLNVAL)
    2359                                 out_flags |= PR_POLL_NVAL;
    2360                             if (syspoll[index].revents & POLLHUP)
    2361                                 out_flags |= PR_POLL_HUP;
    2362                         }
    2363                     }
    2364                     pds[index].out_flags = out_flags;
    2365                 }
    2366             }
    2367         }
    2368     }
    2369     return ready;
    2370 
    2371 } /* _pr_poll_with_poll */
    2372 
    2373 PR_IMPLEMENT(PRInt32) PR_Poll(
    2374     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
    2375 {
    2376         return(_pr_poll_with_poll(pds, npds, timeout));
    2377 }
    2378 
    2379 PR_IMPLEMENT(PRFileDesc*) PR_OpenTCPSocket(PRIntn af)
    2380 {
    2381     return PR_Socket(af, SOCK_STREAM, 0);
    2382 }  /* PR_NewTCPSocket */
    2383 
    2384 PR_IMPLEMENT(PRStatus) PR_CreatePipe(
    2385     PRFileDesc **readPipe,
    2386     PRFileDesc **writePipe
    2387 )
    2388 {
    2389     int pipefd[2];
    2390 
    2391     if (pt_TestAbort()) return PR_FAILURE;
    2392 
    2393     if (pipe(pipefd) == -1)
    2394     {
    2395     /* XXX map pipe error */
    2396         PR_SetError(PR_UNKNOWN_ERROR, errno);
    2397         return PR_FAILURE;
    2398     }
    2399     fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
    2400     fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
    2401     *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE, PR_FALSE, PR_FALSE);
    2402     if (NULL == *readPipe)
    2403     {
    2404         close(pipefd[0]);
    2405         close(pipefd[1]);
    2406         return PR_FAILURE;
    2407     }
    2408     *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE, PR_FALSE, PR_FALSE);
    2409     if (NULL == *writePipe)
    2410     {
    2411         PR_Close(*readPipe);
    2412         close(pipefd[1]);
    2413         return PR_FAILURE;
    2414     }
    2415     return PR_SUCCESS;
    2416 }
    2417 
    2418 /*
    2419 ** Set the inheritance attribute of a file descriptor.
    2420 */
    2421 PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
    2422     PRFileDesc *fd,
    2423     PRBool inheritable)
    2424 {
    2425     /*
    2426      * Only a non-layered, NSPR file descriptor can be inherited
    2427      * by a child process.
    2428      */
    2429     if (fd->identity != PR_NSPR_IO_LAYER)
    2430     {
    2431         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    2432         return PR_FAILURE;
    2433     }
    2434     if (fd->secret->inheritable != inheritable)
    2435     {
    2436         if (fcntl(fd->secret->md.osfd, F_SETFD,
    2437         inheritable ? 0 : FD_CLOEXEC) == -1)
    2438         {
    2439             return PR_FAILURE;
    2440         }
    2441         fd->secret->inheritable = (_PRTriStateBool) inheritable;
    2442     }
    2443     return PR_SUCCESS;
    2444 }
    2445 
    2446 /*****************************************************************************/
    2447 /***************************** I/O friends methods ***************************/
    2448 /*****************************************************************************/
    2449 
    2450 PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd)
    2451 {
    2452     PRFileDesc *fd;
    2453 
    2454     if (!_pr_initialized) _PR_ImplicitInitialization();
    2455     fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_TRUE);
    2456     if (NULL == fd) close(osfd);
    2457     return fd;
    2458 }  /* PR_ImportFile */
    2459 
    2460 PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PRInt32 osfd)
    2461 {
    2462     PRFileDesc *fd;
    2463 
    2464     if (!_pr_initialized) _PR_ImplicitInitialization();
    2465     fd = pt_SetMethods(osfd, PR_DESC_PIPE, PR_FALSE, PR_TRUE);
    2466     if (NULL == fd) close(osfd);
    2467     return fd;
    2468 }  /* PR_ImportPipe */
    2469 
    2470 PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd)
    2471 {
    2472     PRFileDesc *fd;
    2473 
    2474     if (!_pr_initialized) _PR_ImplicitInitialization();
    2475     fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE);
    2476     if (NULL == fd) close(osfd);
    2477 #ifdef _PR_STRICT_ADDR_LEN
    2478     if (NULL != fd) fd->secret->af = PF_INET;
    2479 #endif
    2480     return fd;
    2481 }  /* PR_ImportTCPSocket */
    2482 
    2483 PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd)
    2484 {
    2485     PRFileDesc *fd;
    2486 
    2487     if (!_pr_initialized) _PR_ImplicitInitialization();
    2488     fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE, PR_TRUE);
    2489     if (NULL != fd) close(osfd);
    2490     return fd;
    2491 }  /* PR_ImportUDPSocket */
    2492 
    2493 PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PRInt32 osfd)
    2494 {
    2495     PRFileDesc *fd;
    2496 
    2497     if (!_pr_initialized) _PR_ImplicitInitialization();
    2498 
    2499     fd = _PR_Getfd();
    2500 
    2501     if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    2502     else
    2503     {
    2504         fd->secret->md.osfd = osfd;
    2505         fd->secret->inheritable = _PR_TRI_FALSE;
    2506         fd->secret->state = _PR_FILEDESC_OPEN;
    2507         fd->methods = PR_GetSocketPollFdMethods();
    2508     }
    2509 
    2510     return fd;
    2511 }  /* PR_CreateSocketPollFD */
    2512 
    2513 PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd)
    2514 {
    2515     if (NULL == fd)
    2516     {
    2517         PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
    2518         return PR_FAILURE;
    2519     }
    2520     fd->secret->state = _PR_FILEDESC_CLOSED;
    2521     _PR_Putfd(fd);
    2522     return PR_SUCCESS;
    2523 }  /* PR_DestroySocketPollFd */
    2524 
    2525 #ifdef VBOX
    2526 PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id)
    2527 {
    2528     PRFileDesc *layer = fd;
    2529 
    2530     if (PR_TOP_IO_LAYER == id) {
    2531         if (PR_IO_LAYER_HEAD == fd->identity)
    2532                         return fd->lower;
    2533                 else
    2534                         return fd;
    2535         }
    2536 
    2537     for (layer = fd; layer != NULL; layer = layer->lower)
    2538     {
    2539         if (id == layer->identity) return layer;
    2540     }
    2541     for (layer = fd; layer != NULL; layer = layer->higher)
    2542     {
    2543         if (id == layer->identity) return layer;
    2544     }
    2545     return NULL;
    2546 }  /* PR_GetIdentitiesLayer */
    2547 #endif
    2548 
    2549 PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *bottom)
    2550 {
    2551     PRInt32 osfd = -1;
    2552     bottom = (NULL == bottom) ?
    2553         NULL : PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER);
    2554     if (NULL == bottom) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    2555     else osfd = bottom->secret->md.osfd;
    2556     return osfd;
    2557 }  /* PR_FileDesc2NativeHandle */
    2558 
    2559 PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd,
    2560     PRInt32 handle)
    2561 {
    2562     if (fd) fd->secret->md.osfd = handle;
    2563 }  /*  PR_ChangeFileDescNativeHandle*/
    2564 
    2565793/* ptio.c */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette