/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * The contents of this file are subject to the Netscape Public License
 * Version 1.0 (the "NPL"); you may not use this file except in
 * compliance with the NPL.  You may obtain a copy of the NPL at
 * http://www.mozilla.org/NPL/
 * 
 * Software distributed under the NPL is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
 * for the specific language governing rights and limitations under the
 * NPL.
 * 
 * The Initial Developer of this code under the NPL is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
 * Reserved.
 */

/*
 * File:     prio.h
 *
 * Description:    PR i/o related stuff, such as file system access, file
 *         i/o, socket i/o, etc.
 */

#ifndef prio_h___
#define prio_h___

#include "prlong.h"
#include "prtime.h"
#include "prinrval.h"
#include "prinet.h"

PR_BEGIN_EXTERN_C

/* Typedefs */
typedef struct PRDir            PRDir;
typedef struct PRDirEntry       PRDirEntry;
typedef struct PRFileDesc       PRFileDesc;
typedef struct PRFileInfo       PRFileInfo;
typedef struct PRFileInfo64     PRFileInfo64;
typedef union  PRNetAddr        PRNetAddr;
typedef struct PRIOMethods      PRIOMethods;
typedef struct PRPollDesc       PRPollDesc;
typedef struct PRFilePrivate    PRFilePrivate;

/*
***************************************************************************
** The file descriptor.
** This is the primary structure to represent any active open socket,
** whether it be a normal file or a network connection. Such objects
** are stackable (or layerable). Each layer may have its own set of
** method pointers and context private to that layer. All each layer
** knows about its neighbors is how to get to their method table.
***************************************************************************
*/

typedef PRIntn PRDescIdentity;          /* see: Layering file descriptors */

struct PRFileDesc {
    const PRIOMethods *methods;         /* the I/O methods table */
    PRFilePrivate *secret;              /* layer dependent data */
    PRFileDesc *lower, *higher;         /* pointers to adjacent layers */
    void (PR_CALLBACK *dtor)(PRFileDesc *fd);
                                        /* A destructor function for layer */
    PRDescIdentity identity;            /* Identity of this particular layer  */
};

/*
***************************************************************************
** PRTransmitFileFlags
**
** Flags for PR_TransmitFile.  Pass PR_TRANSMITFILE_CLOSE_SOCKET to
** PR_TransmitFile if the connection should be closed after the file
** is transmitted.
***************************************************************************
*/
typedef enum PRTransmitFileFlags {
    PR_TRANSMITFILE_KEEP_OPEN = 0,    /* socket is left open after file
                                       * is transmitted. */
    PR_TRANSMITFILE_CLOSE_SOCKET = 1  /* socket is closed after file
                                       * is transmitted. */
} PRTransmitFileFlags;

/*
**************************************************************************
** Macros for PRNetAddr
**
** Address families: PR_AF_INET, PR_AF_INET6, PR_AF_LOCAL
** IP addresses: PR_INADDR_ANY, PR_INADDR_LOOPBACK, PR_INADDR_BROADCAST
**************************************************************************
*/

#ifdef WIN32

#define PR_AF_INET 2
#define PR_AF_LOCAL 1
#define PR_INADDR_ANY (unsigned long)0x00000000
#define PR_INADDR_LOOPBACK 0x7f000001
#define PR_INADDR_BROADCAST (unsigned long)0xffffffff

#else /* WIN32 */

#define PR_AF_INET AF_INET
#define PR_AF_LOCAL AF_UNIX
#ifdef AF_INET6
#define PR_AF_INET6 AF_INET6
#endif
#define PR_INADDR_ANY INADDR_ANY
#define PR_INADDR_LOOPBACK INADDR_LOOPBACK
#define PR_INADDR_BROADCAST INADDR_BROADCAST

#endif /* WIN32 */

/*
**************************************************************************
** A network address
**
** Only Internet Protocol (IPv4 and IPv6) addresses are supported.
** The address family must always represent IPv4 (AF_INET, probably == 2)
** or IPv6 (AF_INET6).
**************************************************************************
*************************************************************************/
#if defined(_PR_INET6)

#if !defined(AF_INET6)
#error "AF_INET6 is not defined"
#endif

typedef struct in6_addr PRIPv6Addr;

#endif /* defined(_PR_INET6) */

union PRNetAddr {
    struct {
        PRUint16 family;                /* address family (0x00ff maskable) */
        char data[14];                  /* raw address data */
    } raw;
    struct {
        PRUint16 family;                /* address family (AF_INET) */
        PRUint16 port;                  /* port number */
        PRUint32 ip;                    /* The actual 32 bits of address */
        char pad[8];
    } inet;
#if defined(_PR_INET6)
    struct {
        PRUint16 family;                /* address family (AF_INET6) */
        PRUint16 port;                  /* port number */
        PRUint32 flowinfo;              /* routing information */
        PRIPv6Addr ip;                  /* the actual 128 bits of address */
    } ipv6;
#endif /* defined(_PR_INET6) */
#if defined(XP_UNIX)
    struct {                            /* Unix domain socket address */
        PRUint16 family;                /* address family (AF_UNIX) */
        char path[104];                 /* null-terminated pathname */
    } local;
#endif
};

/*
** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
** whose 'family' field is set.  It returns the size of the union
** member corresponding to the specified address family.
*/

#if defined(_PR_INET6)

#define PR_NETADDR_SIZE(_addr) PR_NetAddrSize(_addr)

#else

#if defined(XP_UNIX)
#define PR_NETADDR_SIZE(_addr) \
        ((_addr)->raw.family == AF_UNIX \
        ? sizeof((_addr)->local) \
        : sizeof((_addr)->inet))
#else
#define PR_NETADDR_SIZE(_addr) sizeof((_addr)->inet)
#endif /* defined(XP_UNIX) */

#endif /* defined(_PR_INET6) */

/*
***************************************************************************
** PRSockOption
**
** The file descriptors can have predefined options set after they file
** descriptor is created to change their behavior. Only the options in
** the following enumeration are supported.
***************************************************************************
*/
typedef enum PRSockOption
{
    PR_SockOpt_Nonblocking,     /* nonblocking io */
    PR_SockOpt_Linger,          /* linger on close if data present */
    PR_SockOpt_Reuseaddr,       /* allow local address reuse */
    PR_SockOpt_Keepalive,       /* keep connections alive */
    PR_SockOpt_RecvBufferSize,  /* send buffer size */
    PR_SockOpt_SendBufferSize,  /* receive buffer size */

    PR_SockOpt_IpTimeToLive,    /* time to live */
    PR_SockOpt_IpTypeOfService, /* type of service and precedence */

    PR_SockOpt_AddMember,       /* add an IP group membership */
    PR_SockOpt_DropMember,      /* drop an IP group membership */
    PR_SockOpt_McastInterface,  /* multicast interface address */
    PR_SockOpt_McastTimeToLive, /* multicast timetolive */
    PR_SockOpt_McastLoopback,   /* multicast loopback */

    PR_SockOpt_NoDelay,         /* don't delay send to coalesce packets */
    PR_SockOpt_MaxSegment,      /* maximum segment size */
    PR_SockOpt_Last
} PRSockOption;

typedef struct PRLinger {
	PRBool polarity;		    /* Polarity of the option's setting */
	PRIntervalTime linger;	    /* Time to linger before closing */
} PRLinger;

typedef struct PRMcastRequest {
	PRNetAddr mcaddr;			/* IP multicast address of group */
	PRNetAddr ifaddr;			/* local IP address of interface */
} PRMcastRequest;

typedef struct PRSocketOptionData
{
    PRSockOption option;
    union
    {
        PRUintn ip_ttl;             /* IP time to live */
        PRUintn mcast_ttl;          /* IP multicast time to live */
        PRUintn tos;                /* IP type of service and precedence */
        PRBool non_blocking;        /* Non-blocking (network) I/O */
        PRBool reuse_addr;          /* Allow local address reuse */
        PRBool keep_alive;          /* Keep connections alive */
        PRBool mcast_loopback;      /* IP multicast loopback */
        PRBool no_delay;            /* Don't delay send to coalesce packets */
        PRSize max_segment;         /* Maximum segment size */
        PRSize recv_buffer_size;    /* Receive buffer size */
        PRSize send_buffer_size;    /* Send buffer size */
        PRLinger linger;            /* Time to linger on close if data present */
        PRMcastRequest add_member;  /* add an IP group membership */
        PRMcastRequest drop_member; /* Drop an IP group membership */
        PRNetAddr mcast_if;         /* multicast interface address */
    } value;
} PRSocketOptionData;

/*
***************************************************************************
** PRIOVec
**
** The I/O vector is used by the write vector method to describe the areas
** that are affected by the ouput operation.
***************************************************************************
*/
typedef struct PRIOVec {
    char *iov_base;
    int iov_len;
} PRIOVec;

/*
***************************************************************************
** Discover what type of socket is being described by the file descriptor.
***************************************************************************
*/
typedef enum PRDescType
{
    PR_DESC_FILE = 1,
    PR_DESC_SOCKET_TCP = 2,
    PR_DESC_SOCKET_UDP = 3,
    PR_DESC_LAYERED = 4
} PRDescType;

typedef enum PRSeekWhence {
    PR_SEEK_SET = 0,
    PR_SEEK_CUR = 1,
    PR_SEEK_END = 2
} PRSeekWhence;

PR_EXTERN(PRDescType) PR_GetDescType(PRFileDesc *file);

/*
***************************************************************************
** PRIOMethods
**
** The I/O methods table provides procedural access to the functions of
** the file descriptor. It is the responsibility of a layer implementor
** to provide suitable functions at every entry point. If a layer provides
** no functionality, it should call the next lower(higher) function of the
** same name (e.g., return fd->lower->method->close(fd->lower));
**
** Not all functions are implemented for all types of files. In cases where
** that is true, the function will return a error indication with an error
** code of PR_INVALID_METHOD_ERROR.
***************************************************************************
*/

typedef PRStatus (PR_CALLBACK *PRCloseFN)(PRFileDesc *fd);
typedef PRInt32 (PR_CALLBACK *PRReadFN)(PRFileDesc *fd, void *buf, PRInt32 amount);
typedef PRInt32 (PR_CALLBACK *PRWriteFN)(PRFileDesc *fd, const void *buf, PRInt32 amount);
typedef PRInt32 (PR_CALLBACK *PRAvailableFN)(PRFileDesc *fd);
typedef PRInt64 (PR_CALLBACK *PRAvailable64FN)(PRFileDesc *fd);
typedef PRStatus (PR_CALLBACK *PRFsyncFN)(PRFileDesc *fd);
typedef PRInt32 (PR_CALLBACK *PRSeekFN)(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how);
typedef PRInt64 (PR_CALLBACK *PRSeek64FN)(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how);
typedef PRStatus (PR_CALLBACK *PRFileInfoFN)(PRFileDesc *fd, PRFileInfo *info);
typedef PRStatus (PR_CALLBACK *PRFileInfo64FN)(PRFileDesc *fd, PRFileInfo64 *info);
typedef PRInt32 (PR_CALLBACK *PRWritevFN)(
    PRFileDesc *fd, PRIOVec *iov, PRInt32 size, PRIntervalTime timeout);
typedef PRStatus (PR_CALLBACK *PRConnectFN)(
    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);
typedef PRFileDesc* (PR_CALLBACK *PRAcceptFN) (
    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);
typedef PRStatus (PR_CALLBACK *PRBindFN)(PRFileDesc *fd, const PRNetAddr *addr);
typedef PRStatus (PR_CALLBACK *PRListenFN)(PRFileDesc *fd, PRIntn backlog);
typedef PRStatus (PR_CALLBACK *PRShutdownFN)(PRFileDesc *fd, PRIntn how);
typedef PRInt32 (PR_CALLBACK *PRRecvFN)(
    PRFileDesc *fd, void *buf, PRInt32 amount,
    PRIntn flags, PRIntervalTime timeout);
typedef PRInt32 (PR_CALLBACK *PRSendFN) (
    PRFileDesc *fd, const void *buf, PRInt32 amount,
    PRIntn flags, PRIntervalTime timeout);
typedef PRInt32 (PR_CALLBACK *PRRecvfromFN)(
    PRFileDesc *fd, void *buf, PRInt32 amount,
    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout);
typedef PRInt32 (PR_CALLBACK *PRSendtoFN)(
    PRFileDesc *fd, const void *buf, PRInt32 amount,
    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout);
typedef PRInt16 (PR_CALLBACK *PRPollFN)(
    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)(
    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
    void *buf, PRInt32 amount, PRIntervalTime t);
typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)(
     PRFileDesc *sd, PRFileDesc *fd, const void *headers,
     PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t);
typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr);
typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr);
typedef PRStatus (PR_CALLBACK *PRGetsockoptFN)(  /* OBSOLETE */
    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32 *optlen);
typedef PRStatus (PR_CALLBACK *PRSetsockoptFN)(  /* OBSOLETE */
    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)(
    PRFileDesc *fd, PRSocketOptionData *data);
typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
    PRFileDesc *fd, const PRSocketOptionData *data);

struct PRIOMethods {
    PRDescType file_type;           /* Type of file represented (tos)           */
    PRCloseFN close;                /* close file and destroy descriptor        */
    PRReadFN read;                  /* read up to specified bytes into buffer   */
    PRWriteFN write;                /* write specified bytes from buffer        */
    PRAvailableFN available;        /* determine number of bytes available      */
    PRAvailable64FN available64;    /*          ditto, 64 bit                   */
    PRFsyncFN fsync;                /* flush all buffers to permanent store     */
    PRSeekFN seek;                  /* position the file to the desired place   */
    PRSeek64FN seek64;              /*           ditto, 64 bit                  */
    PRFileInfoFN fileInfo;          /* Get information about an open file       */
    PRFileInfo64FN fileInfo64;      /*           ditto, 64 bit                  */
    PRWritevFN writev;              /* Write segments as described by iovector  */
    PRConnectFN connect;            /* Connect to the specified (net) address   */
    PRAcceptFN accept;              /* Accept a connection for a (net) peer     */
    PRBindFN bind;                  /* Associate a (net) address with the fd    */
    PRListenFN listen;              /* Prepare to listen for (net) connections  */
    PRShutdownFN shutdown;          /* Shutdown a (net) connection              */
    PRRecvFN recv;                  /* Solicit up the the specified bytes       */
    PRSendFN send;                  /* Send all the bytes specified             */
    PRRecvfromFN recvfrom;          /* Solicit (net) bytes and report source    */
    PRSendtoFN sendto;              /* Send bytes to (net) address specified    */
    PRPollFN poll;                  /* Test the fd to see if it is ready        */
    PRAcceptreadFN acceptread;      /* Accept and read on a new (net) fd        */
    PRTransmitfileFN transmitfile;  /* Transmit at entire file                  */
    PRGetsocknameFN getsockname;    /* Get (net) address associated with fd     */
    PRGetpeernameFN getpeername;    /* Get peer's (net) address                 */
    PRGetsockoptFN getsockopt;      /*             OBSOLETE                     */
    PRSetsockoptFN setsockopt;      /*             OBSOLETE                     */
    PRGetsocketoptionFN getsocketoption;
                                    /* Get current setting of specified option  */
    PRSetsocketoptionFN setsocketoption;
                                    /* Set value of specified option            */
};

/*
 **************************************************************************
 * FUNCTION: PR_GetSpecialFD
 * DESCRIPTION: Get the file descriptor that represents the standard input,
 *              output, or error stream.
 * INPUTS:
 *     PRSpecialFD id
 *         A value indicating the type of stream desired:
 *             PR_StandardInput: standard input
 *             PR_StandardOuput: standard output
 *             PR_StandardError: standard error
 * OUTPUTS: none
 * RETURNS: PRFileDesc *
 *     If the argument is valid, PR_GetSpecialFD returns a file descriptor
 *     that represents the corresponding standard I/O stream.  Otherwise,
 *     PR_GetSpecialFD returns NULL and sets error PR_INVALID_ARGUMENT_ERROR.
 **************************************************************************
 */

typedef enum PRSpecialFD
{
    PR_StandardInput,          /* standard input */
    PR_StandardOutput,         /* standard output */
    PR_StandardError           /* standard error */
} PRSpecialFD;

PR_EXTERN(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id);

#define PR_STDIN	PR_GetSpecialFD(PR_StandardInput)
#define PR_STDOUT	PR_GetSpecialFD(PR_StandardOutput)
#define PR_STDERR	PR_GetSpecialFD(PR_StandardError)

/*
 **************************************************************************
 * Layering file descriptors
 *
 * File descriptors may be layered. Each layer has it's own identity.
 * Identities are allocated by the runtime and are to be associated
 * (by the layer implementor) with all layers that are of that type.
 * It is then possible to scan the chain of layers and find a layer
 * that one recongizes and therefore predict that it will implement
 * a desired protocol.
 *
 * There are three well-known identities:
 *      PR_INVALID_IO_LAYER => an invalid layer identity, for error return
 *      PR_TOP_IO_LAYER     => the identity of the top of the stack
 *      PR_NSPR_IO_LAYER    => the identity used by NSPR proper
 * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost
 * layer of an existing stack. Ie., the following two constructs are
 * equivalent.
 *
 *      rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer);
 *      rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer)
 *
 * A string may be associated with the creation of the identity. It
 * will be copied by the runtime. If queried the runtime will return
 * a reference to that copied string (not yet another copy). There
 * is no facility for deleting an identity.
 **************************************************************************
 */

#define PR_INVALID_IO_LAYER (PRDescIdentity)-1
#define PR_TOP_IO_LAYER (PRDescIdentity)-2
#define PR_NSPR_IO_LAYER (PRDescIdentity)0

PR_EXTERN(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name);
PR_EXTERN(const char*) PR_GetNameForIdentity(PRDescIdentity ident);
PR_EXTERN(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd);
PR_EXTERN(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* stack, PRDescIdentity id);

/*
 **************************************************************************
 * PR_GetDefaultIOMethods: Accessing the default methods table.
 * You may get a pointer to the default methods table by calling this function.
 * You may then select any elements from that table with which to build your
 * layer's methods table. You may NOT modify the table directly.
 **************************************************************************
 */
PR_EXTERN(const PRIOMethods *) PR_GetDefaultIOMethods(void);

/*
 **************************************************************************
 * Creating a layer
 *
 * A new layer may be allocated by calling PR_CreateIOLayerStub(). The
 * file descriptor returned will contain the pointer to the methods table
 * provided. The runtime will not modify the table nor test its correctness.
 **************************************************************************
 */
PR_EXTERN(PRFileDesc*) PR_CreateIOLayerStub(
    PRDescIdentity ident, const PRIOMethods *methods);

/*
 **************************************************************************
 * Pushing a layer
 *
 * A file descriptor (perhaps allocated using PR_CreateIOLayerStub()) may
 * be pushed into an existing stack of file descriptors at any point the
 * caller deems appropriate. The new layer will be inserted into the stack
 * just above the layer with the indicated identity.
 *
 * Note: Even if the identity parameter indicates the top-most layer of
 * the stack, the value of the file descriptor describing the original
 * stack will not change.
 **************************************************************************
 */
PR_EXTERN(PRStatus) PR_PushIOLayer(
    PRFileDesc *stack, PRDescIdentity id, PRFileDesc *layer);

/*
 **************************************************************************
 * Popping a layer
 *
 * A layer may be popped from a stack by indicating the identity of the
 * layer to be removed. If found, a pointer to the removed object will
 * be returned to the caller. The object then becomes the responsibility
 * of the caller.
 *
 * Note: Even if the identity indicates the top layer of the stack, the
 * reference returned will not be the file descriptor for the stack and
 * that file descriptor will remain valid.
 **************************************************************************
 */
PR_EXTERN(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id);

/*
 **************************************************************************
 * FUNCTION:    PR_Open
 * DESCRIPTION:    Open a file for reading, writing, or both.
 * INPUTS:
 *     const char *name
 *         The path name of the file to be opened
 *     PRIntn flags
 *         The file status flags.
 *         It is a bitwise OR of the following bit flags (only one of
 *         the first three flags below may be used):
 *		PR_RDONLY        Open for reading only.
 *		PR_WRONLY        Open for writing only.
 *		PR_RDWR          Open for reading and writing.
 *		PR_CREATE_FILE   If the file does not exist, the file is created
 *                              If the file exists, this flag has no effect.
 *      PR_SYNC          If set, each write will wait for both the file data
 *                              and file status to be physically updated.
 *		PR_APPEND        The file pointer is set to the end of
 *                              the file prior to each write.
 *		PR_TRUNCATE      If the file exists, its length is truncated to 0.
 *
 *     PRIntn mode
 *         The access permission bits of the file mode, if the file is
 *         created when PR_CREATE_FILE is on.
 * OUTPUTS:    None
 * RETURNS:    PRFileDesc *
 *     If the file is successfully opened,
 *     returns a pointer to the PRFileDesc
 *     created for the newly opened file.
 *     Returns a NULL pointer if the open
 *     failed.
 * SIDE EFFECTS:
 * RESTRICTIONS:
 * MEMORY:
 *     The return value, if not NULL, points to a dynamically allocated
 *     PRFileDesc object.
 * ALGORITHM:
 **************************************************************************
 */

PR_EXTERN(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
/* Open flags */
#define PR_RDONLY       0x01
#define PR_WRONLY       0x02
#define PR_RDWR         0x04
#define PR_CREATE_FILE  0x08
#define PR_APPEND       0x10
#define PR_TRUNCATE     0x20
#define PR_SYNC         0x40

/*
** File modes ....
**
** CAVEAT: 'mode' is currently only applicable on UNIX platforms. We are
** still in the process of seeing how these apply to other file systems.
**
**   00400   Read by owner.
**   00200   Write by owner.
**   00100   Execute (search if a directory) by owner.
**   00040   Read by group.
**   00020   Write by group.
**   00010   Execute by group.
**   00004   Read by others.
**   00002   Write by others
**   00001   Execute by others.
**
*/

/*
 **************************************************************************
 * FUNCTION: PR_Close
 * DESCRIPTION:
 *     Close a file or socket.
 * INPUTS:
 *     PRFileDesc *fd
 *         a pointer to a PRFileDesc.
 * OUTPUTS:
 *     None.
 * RETURN:
 *     PRStatus
 * SIDE EFFECTS:
 * RESTRICTIONS:
 *     None.
 * MEMORY:
 *     The dynamic memory pointed to by the argument fd is freed.
 **************************************************************************
 */

PR_EXTERN(PRStatus)    PR_Close(PRFileDesc *fd);

/*
 **************************************************************************
 * FUNCTION: PR_Read
 * DESCRIPTION:
 *     Read bytes from a file or socket.
 *     The operation will block until either an end of stream indication is
 *     encountered, some positive number of bytes are transferred, or there
 *     is an error. No more than 'amount' bytes will be transferred.
 * INPUTS:
 *     PRFileDesc *fd
 *         pointer to the PRFileDesc object for the file or socket
 *     void *buf
 *         pointer to a buffer to hold the data read in.
 *     PRInt32 amount
 *         the size of 'buf' (in bytes)
 * OUTPUTS:
 * RETURN:
 *     PRInt32
 *         a positive number indicates the number of bytes actually read in.
 *         0 means end of file is reached or the network connection is closed.
 *         -1 indicates a failure. The reason for the failure is obtained
 *         by calling PR_GetError().
 * SIDE EFFECTS:
 *     data is written into the buffer pointed to by 'buf'.
 * RESTRICTIONS:
 *     None.
 * MEMORY:
 *     N/A
 * ALGORITHM:
 *     N/A
 **************************************************************************
 */

PR_EXTERN(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount);

/*
 ***************************************************************************
 * FUNCTION: PR_Write
 * DESCRIPTION:
 *     Write a specified number of bytes to a file or socket.  The thread
 *     invoking this function blocks until all the data is written.
 * INPUTS:
 *     PRFileDesc *fd
 *         pointer to a PRFileDesc object that refers to a file or socket
 *     const void *buf
 *         pointer to the buffer holding the data
 *     PRInt32 amount
 *         amount of data in bytes to be written from the buffer
 * OUTPUTS:
 *     None.
 * RETURN: PRInt32
 *     A positive number indicates the number of bytes successfully written.
 *     A -1 is an indication that the operation failed. The reason
 *     for the failure is obtained by calling PR_GetError().
 ***************************************************************************
 */

PR_EXTERN(PRInt32) PR_Write(PRFileDesc *fd,const void *buf,PRInt32 amount);

/*
 ***************************************************************************
 * FUNCTION: PR_Writev
 * DESCRIPTION:
 *     Write data to a socket.  The data is organized in a PRIOVec array. The
 *     operation will block until all the data is written or the operation
 *     fails.
 * INPUTS:
 *     PRFileDesc *fd
 *         Pointer that points to a PRFileDesc object for a socket.
 *     PRIOVec *iov
 *         An array of PRIOVec.  PRIOVec is a struct with the following
 *         two fields:
 *             char *iov_base;
 *             int iov_len;
 *     PRInt32 iov_size
 *         Number of elements in the iov array. The value of this
 *         argument must not be greater than PR_MAX_IOVECTOR_SIZE.
 *         If it is, the method will fail (PR_BUFFER_OVERFLOW_ERROR).
 *     PRIntervalTime timeout
 *       Time limit for completion of the entire write operation.
 * OUTPUTS:
 *     None
 * RETURN:
 *     A positive number indicates the number of bytes successfully written.
 *     A -1 is an indication that the operation failed. The reason
 *     for the failure is obtained by calling PR_GetError().
 ***************************************************************************
 */

#define PR_MAX_IOVECTOR_SIZE 16   /* 'size' must be <= */

PR_EXTERN(PRInt32) PR_Writev(
    PRFileDesc *fd, PRIOVec *iov, PRInt32 size, PRIntervalTime timeout);

/*
 ***************************************************************************
 * FUNCTION: PR_Delete
 * DESCRIPTION:
 *     Delete a file from the filesystem. The operation may fail if the
 *     file is open.
 * INPUTS:
 *     const char *name
 *         Path name of the file to be deleted.
 * OUTPUTS:
 *     None.
 * RETURN: PRStatus
 *     The function returns PR_SUCCESS if the file is successfully
 *     deleted, otherwise it returns PR_FAILURE.
 ***************************************************************************
 */

PR_EXTERN(PRStatus) PR_Delete(const char *name);

/**************************************************************************/

typedef enum PRFileType
{
    PR_FILE_FILE = 1,
    PR_FILE_DIRECTORY = 2,
    PR_FILE_OTHER = 3
} PRFileType;

struct PRFileInfo {
    PRFileType type;        /* Type of file */
    PRUint32 size;          /* Size, in bytes, of file's contents */
    PRTime creationTime;    /* Creation time per definition of PRTime */
    PRTime modifyTime;      /* Last modification time per definition of PRTime */
};

struct PRFileInfo64 {
    PRFileType type;        /* Type of file */
    PRUint64 size;          /* Size, in bytes, of file's contents */
    PRTime creationTime;    /* Creation time per definition of PRTime */
    PRTime modifyTime;      /* Last modification time per definition of PRTime */
};

/****************************************************************************
 * FUNCTION: PR_GetFileInfo, PR_GetFileInfo64
 * DESCRIPTION:
 *     Get the information about the file with the given path name. This is
 *     applicable only to NSFileDesc describing 'file' types (see
 * INPUTS:
 *     const char *fn
 *         path name of the file
 * OUTPUTS:
 *     PRFileInfo *info
 *         Information about the given file is written into the file
 *         information object pointer to by 'info'.
 * RETURN: PRStatus
 *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
 *     obtained, otherwise it returns PR_FAILURE.
 ***************************************************************************
 */

PR_EXTERN(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info);
PR_EXTERN(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info);

/*
 **************************************************************************
 * FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64
 * DESCRIPTION:
 *     Get information about an open file referred to by the
 *     given PRFileDesc object.
 * INPUTS:
 *     const PRFileDesc *fd
 *          A reference to a valid, open file.
 * OUTPUTS:
 *     Same as PR_GetFileInfo, PR_GetFileInfo64
 * RETURN: PRStatus
 *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
 *     obtained, otherwise it returns PR_FAILURE.
 ***************************************************************************
 */

PR_EXTERN(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info);
PR_EXTERN(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info);

/*
 **************************************************************************
 * FUNCTION: PR_Rename
 * DESCRIPTION:
 *     Rename a file from the old name 'from' to the new name 'to'.
 * INPUTS:
 *     const char *from
 *         The old name of the file to be renamed.
 *     const char *to
 *         The new name of the file.
 * OUTPUTS:
 *     None.
 * RETURN: PRStatus
 **************************************************************************
 */

PR_EXTERN(PRStatus)    PR_Rename(const char *from, const char *to);

/*
 *************************************************************************
 * FUNCTION: PR_Access
 * DESCRIPTION:
 *     Determine accessibility of a file.
 * INPUTS:
 *     const char *name
 *         path name of the file
 *     PRAccessHow how
 *         specifies which access permission to check for.
 *         It can be one of the following values:
 *             PR_ACCESS_READ_OK       Test for read permission
 *             PR_ACCESS_WRITE_OK      Test for write permission
 *             PR_ACCESS_EXISTS        Check existence of file
 * OUTPUTS:
 *     None.
 * RETURN: PRStatus
 *     PR_SUCCESS is returned if the requested access is permitted.
 *     Otherwise, PR_FAILURE is returned. Additional information
 *     regarding the reason for the failure may be retrieved from
 *     PR_GetError().
 *************************************************************************
 */

typedef enum PRAccessHow {
    PR_ACCESS_EXISTS = 1,
    PR_ACCESS_WRITE_OK = 2,
    PR_ACCESS_READ_OK = 3
} PRAccessHow;

PR_EXTERN(PRStatus) PR_Access(const char *name, PRAccessHow how);

/*
 *************************************************************************
 * FUNCTION: PR_Seek, PR_Seek64
 * DESCRIPTION:
 *     Moves read-write file offset
 * INPUTS:
 *     PRFileDesc *fd
 *         Pointer to a PRFileDesc object.
 *     PRInt32, PRInt64 offset
 *         Specifies a value, in bytes, that is used in conjunction
 *         with the 'whence' parameter to set the file pointer.  A
 *         negative value causes seeking in the reverse direction.
 *     PRSeekWhence whence
 *         Specifies how to interpret the 'offset' parameter in setting
 *         the file pointer associated with the 'fd' parameter.
 *         Values for the 'whence' parameter are:
 *             PR_SEEK_SET  Sets the file pointer to the value of the
 *                          'offset' parameter
 *             PR_SEEK_CUR  Sets the file pointer to its current location
 *                          plus the value of the offset parameter.
 *             PR_SEEK_END  Sets the file pointer to the size of the
 *                          file plus the value of the offset parameter.
 * OUTPUTS:
 *     None.
 * RETURN: PRInt32, PRInt64
 *     Upon successful completion, the resulting pointer location,
 *     measured in bytes from the beginning of the file, is returned.
 *     If the PR_Seek() function fails, the file offset remains
 *     unchanged, and the returned value is -1. The error code can
 *     then be retrieved via PR_GetError().
 *************************************************************************
 */

PR_EXTERN(PRInt32) PR_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence);
PR_EXTERN(PRInt64) PR_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence);

/*
 ************************************************************************
 * FUNCTION: PR_Available
 * DESCRIPTION:
 *     Determine the amount of data in bytes available for reading
 *     in the given file or socket.
 * INPUTS:
 *     PRFileDesc *fd
 *         Pointer to a PRFileDesc object that refers to a file or
 *         socket.
 * OUTPUTS:
 *     None
 * RETURN: PRInt32, PRInt64
 *     Upon successful completion, PR_Available returns the number of
 *     bytes beyond the current read pointer that is available for
 *     reading.  Otherwise, it returns a -1 and the reason for the
 *     failure can be retrieved via PR_GetError().
 ************************************************************************
 */

PR_EXTERN(PRInt32) PR_Available(PRFileDesc *fd);
PR_EXTERN(PRInt64) PR_Available64(PRFileDesc *fd);

/*
 ************************************************************************
 * FUNCTION: PR_Sync
 * DESCRIPTION:
 *     Sync any buffered data for a fd to its backing device (disk).
 * INPUTS:
 *     PRFileDesc *fd
 *         Pointer to a PRFileDesc object that refers to a file or
 *         socket
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *     PR_SUCCESS is returned if the requested access is permitted.
 *     Otherwise, PR_FAILURE is returned.
 ************************************************************************
 */

PR_EXTERN(PRStatus)	PR_Sync(PRFileDesc *fd);

/************************************************************************/

struct PRDirEntry {
    const char *name;        /* name of entry, relative to directory name */
};

#if !defined(NO_NSPR_10_SUPPORT)
#define PR_DirName(dirEntry)	(dirEntry->name)
#endif

/*
 *************************************************************************
 * FUNCTION: PR_OpenDir
 * DESCRIPTION:
 *     Open the directory by the given name
 * INPUTS:
 *     const char *name
 *         path name of the directory to be opened
 * OUTPUTS:
 *     None
 * RETURN: PRDir *
 *     If the directory is sucessfully opened, a PRDir object is
 *     dynamically allocated and a pointer to it is returned.
 *     If the directory cannot be opened, a NULL pointer is returned.
 * MEMORY:
 *     Upon successful completion, the return value points to
 *     dynamically allocated memory.
 *************************************************************************
 */

PR_EXTERN(PRDir*) PR_OpenDir(const char *name);

/*
 *************************************************************************
 * FUNCTION: PR_ReadDir
 * DESCRIPTION:
 * INPUTS:
 *     PRDir *dir
 *         pointer to a PRDir object that designates an open directory
 *     PRDirFlags flags
 *           PR_SKIP_NONE     Do not skip any files
 *           PR_SKIP_DOT      Skip the directory entry "." that
 *                            represents the current directory
 *           PR_SKIP_DOT_DOT  Skip the directory entry ".." that
 *                            represents the parent directory.
 *           PR_SKIP_BOTH     Skip both '.' and '..'
 *           PR_SKIP_HIDDEN   Skip hidden files
 * OUTPUTS:
 * RETURN: PRDirEntry*
 *     Returns a pointer to the next entry in the directory.  Returns
 *     a NULL pointer upon reaching the end of the directory or when an
 *     error occurs. The actual reason can be retrieved via PR_GetError().
 *************************************************************************
 */

typedef enum PRDirFlags {
    PR_SKIP_NONE = 0x0,
    PR_SKIP_DOT = 0x1,
    PR_SKIP_DOT_DOT = 0x2,
    PR_SKIP_BOTH = 0x3,
    PR_SKIP_HIDDEN = 0x4
} PRDirFlags;

PR_EXTERN(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags);

/*
 *************************************************************************
 * FUNCTION: PR_CloseDir
 * DESCRIPTION:
 *     Close the specified directory.
 * INPUTS:
 *     PRDir *dir
 *        The directory to be closed.
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *        If successful, will return a status of PR_SUCCESS. Otherwise
 *        a value of PR_FAILURE. The reason for the failure may be re-
 *        trieved using PR_GetError().
 *************************************************************************
 */

PR_EXTERN(PRStatus) PR_CloseDir(PRDir *dir);

/*
 *************************************************************************
 * FUNCTION: PR_MkDir
 * DESCRIPTION:
 *     Create a new directory with the given name and access mode.
 * INPUTS:
 *     const char *name
 *        The name of the directory to be created. All the path components
 *        up to but not including the leaf component must already exist.
 *     PRIntn mode
 *        See 'mode' definiton in PR_Open().
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *        If successful, will return a status of PR_SUCCESS. Otherwise
 *        a value of PR_FAILURE. The reason for the failure may be re-
 *        trieved using PR_GetError().
 *************************************************************************
 */

PR_EXTERN(PRStatus) PR_MkDir(const char *name, PRIntn mode);

/*
 *************************************************************************
 * FUNCTION: PR_RmDir
 * DESCRIPTION:
 *     Remove a directory by the given name.
 * INPUTS:
 *     const char *name
 *        The name of the directory to be removed. All the path components
 *        must already exist. Only the leaf component will be removed.
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *        If successful, will return a status of PR_SUCCESS. Otherwise
 *        a value of PR_FAILURE. The reason for the failure may be re-
 *        trieved using PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRStatus) PR_RmDir(const char *name);

PR_EXTERN(PRUintn) PR_NetAddrSize(const PRNetAddr* addr);

/*
 *************************************************************************
 * FUNCTION: PR_NewUDPSocket
 * DESCRIPTION:
 *     Create a new UDP network connection.
 * INPUTS:
 *     None
 * OUTPUTS:
 *     None
 * RETURN: PRFileDesc*
 *     Upon successful completion, PR_NewUDPSocket returns a pointer
 *     to the PRFileDesc created for the newly opened UDP socket.
 *     Returns a NULL pointer if the create of a new UDP connection failed.
 *
 **************************************************************************
 */

PR_EXTERN(PRFileDesc*)    PR_NewUDPSocket(void);

/*
 *************************************************************************
 * FUNCTION: PR_NewTCPSocket
 * DESCRIPTION:
 *     Create a new TCP network connection.
 * INPUTS:
 *     None
 * OUTPUTS:
 *     None
 * RETURN: PRFileDesc*
 *     Upon successful completion, PR_NewTCPSocket returns a pointer
 *     to the PRFileDesc created for the newly opened TCP socket.
 *     Returns a NULL pointer if the create of a new TCP connection failed.
 *
 **************************************************************************
 */

PR_EXTERN(PRFileDesc*)    PR_NewTCPSocket(void);

/*
 *************************************************************************
 * FUNCTION: PR_Connect
 * DESCRIPTION:
 *     Initiate a connection on a socket.
 * INPUTS:
 *     PRFileDesc *fd
 *       Points to a PRFileDesc object representing a socket
 *     PRNetAddr *addr
 *       Specifies the address of the socket in its own communication
 *       space.
 *     PRIntervalTime timeout
 *       Time limit for completion of the connect operation.
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *     Upon successful completion of connection initiation, PR_Connect
 *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
 *     failure information can be obtained by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRStatus) PR_Connect(
    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);

/*
 *************************************************************************
 * FUNCTION: PR_GetConnectStatus
 * DESCRIPTION:
 *     Get the completion status of a nonblocking connect.  After
 *     a nonblocking connect is initiated with PR_Connect() (which
 *     fails with PR_IN_PROGRESS_ERROR), one should call PR_Poll()
 *     on the socket, with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.
 *     When PR_Poll() returns, one calls PR_GetConnectStatus on the
 *     PRPollDesc structure to determine whether the nonblocking
 *     connect has succeeded or failed.
 * INPUTS:
 *     const PRPollDesc *pd
 *         Pointer to a PRPollDesc whose fd member is the socket,
 *         and in_flags must contain PR_POLL_WRITE and PR_POLL_EXCEPT.
 *         PR_Poll() should have been called and set the out_flags.
 * RETURN: PRStatus
 *     If the nonblocking connect has successfully completed,
 *     PR_GetConnectStatus returns PR_SUCCESS.  If PR_GetConnectStatus()
 *     returns PR_FAILURE, call PR_GetError():
 *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
 *       progress and has not completed yet.
 *     - Other errors: the nonblocking connect has failed with this
 *       error code.
 */

PR_EXTERN(PRStatus)    PR_GetConnectStatus(const PRPollDesc *pd);

/*
 *************************************************************************
 * FUNCTION: PR_Accept
 * DESCRIPTION:
 *     Accept a connection on a socket.
 * INPUTS:
 *     PRFileDesc *fd
 *       Points to a PRFileDesc object representing the rendezvous socket
 *       on which the caller is willing to accept new connections.
 *     PRIntervalTime timeout
 *       Time limit for completion of the accept operation.
 * OUTPUTS:
 *     PRNetAddr *addr
 *       Returns the address of the connecting entity in its own
 *       communication space. It may be NULL.
 * RETURN: PRFileDesc*
 *     Upon successful acceptance of a connection, PR_Accept
 *     returns a valid file descriptor. Otherwise, it returns NULL.
 *     Further failure information can be obtained by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRFileDesc*) PR_Accept(
    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);

/*
 *************************************************************************
 * FUNCTION: PR_Bind
 * DESCRIPTION:
 *    Bind an address to a socket.
 * INPUTS:
 *     PRFileDesc *fd
 *       Points to a PRFileDesc object representing a socket.
 *     PRNetAddr *addr
 *       Specifies the address to which the socket will be bound.
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *     Upon successful binding of an address to a socket, PR_Bind
 *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
 *     failure information can be obtained by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr);

/*
 *************************************************************************
 * FUNCTION: PR_Listen
 * DESCRIPTION:
 *    Listen for connections on a socket.
 * INPUTS:
 *     PRFileDesc *fd
 *       Points to a PRFileDesc object representing a socket that will be
 *       used to listen for new connections.
 *     PRIntn backlog
 *       Specifies the maximum length of the queue of pending connections.
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *     Upon successful completion of listen request, PR_Listen
 *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
 *     failure information can be obtained by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog);

/*
 *************************************************************************
 * FUNCTION: PR_Shutdown
 * DESCRIPTION:
 *    Shut down part of a full-duplex connection on a socket.
 * INPUTS:
 *     PRFileDesc *fd
 *       Points to a PRFileDesc object representing a connected socket.
 *     PRIntn how
 *       Specifies the kind of disallowed operations on the socket.
 *           PR_SHUTDOWN_RCV - Further receives will be disallowed
 *           PR_SHUTDOWN_SEND - Further sends will be disallowed
 *           PR_SHUTDOWN_BOTH - Further sends and receives will be disallowed
 * OUTPUTS:
 *     None
 * RETURN: PRStatus
 *     Upon successful completion of shutdown request, PR_Shutdown
 *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
 *     failure information can be obtained by calling PR_GetError().
 **************************************************************************
 */

typedef enum PRShutdownHow
{
    PR_SHUTDOWN_RCV = 0,      /* disallow further receives */
    PR_SHUTDOWN_SEND = 1,     /* disallow further sends */
    PR_SHUTDOWN_BOTH = 2      /* disallow further receives and sends */
} PRShutdownHow;

PR_EXTERN(PRStatus)    PR_Shutdown(PRFileDesc *fd, PRShutdownHow how);

/*
 *************************************************************************
 * FUNCTION: PR_Recv
 * DESCRIPTION:
 *    Receive a specified number of bytes from a connected socket.
 *     The operation will block until some positive number of bytes are 
 *     transferred, a time out has occurred, or there is an error. 
 *     No more than 'amount' bytes will be transferred.
 * INPUTS:
 *     PRFileDesc *fd
 *       points to a PRFileDesc object representing a socket.
 *     void *buf
 *       pointer to a buffer to hold the data received.
 *     PRInt32 amount
 *       the size of 'buf' (in bytes)
 *     PRIntn flags
 *        (OBSOLETE - must always be zero)
 *     PRIntervalTime timeout
 *       Time limit for completion of the receive operation.
 * OUTPUTS:
 *     None
 * RETURN: PRInt32
 *         a positive number indicates the number of bytes actually received.
 *         0 means the network connection is closed.
 *         -1 indicates a failure. The reason for the failure is obtained
 *         by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRInt32)    PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
                PRIntn flags, PRIntervalTime timeout);

/*
 *************************************************************************
 * FUNCTION: PR_Send
 * DESCRIPTION:
 *    Send a specified number of bytes from a connected socket.
 *     The operation will block until all bytes are 
 *     processed, a time out has occurred, or there is an error. 
 * INPUTS:
 *     PRFileDesc *fd
 *       points to a PRFileDesc object representing a socket.
 *     void *buf
 *       pointer to a buffer from where the data is sent.
 *     PRInt32 amount
 *       the size of 'buf' (in bytes)
 *     PRIntn flags
 *        (OBSOLETE - must always be zero)
 *     PRIntervalTime timeout
 *       Time limit for completion of the send operation.
 * OUTPUTS:
 *     None
 * RETURN: PRInt32
 *     A positive number indicates the number of bytes successfully processed.
 *     This number must always equal 'amount'. A -1 is an indication that the
 *     operation failed. The reason for the failure is obtained by calling
 *     PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRInt32)    PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
                                PRIntn flags, PRIntervalTime timeout);

/*
 *************************************************************************
 * FUNCTION: PR_RecvFrom
 * DESCRIPTION:
 *     Receive up to a specified number of bytes from socket which may
 *     or may not be connected.
 *     The operation will block until one or more bytes are 
 *     transferred, a time out has occurred, or there is an error. 
 *     No more than 'amount' bytes will be transferred.
 * INPUTS:
 *     PRFileDesc *fd
 *       points to a PRFileDesc object representing a socket.
 *     void *buf
 *       pointer to a buffer to hold the data received.
 *     PRInt32 amount
 *       the size of 'buf' (in bytes)
 *     PRIntn flags
 *        (OBSOLETE - must always be zero)
 *     PRNetAddr *addr
 *       Specifies the address of the sending peer. It may be NULL.
 *     PRIntervalTime timeout
 *       Time limit for completion of the receive operation.
 * OUTPUTS:
 *     None
 * RETURN: PRInt32
 *         a positive number indicates the number of bytes actually received.
 *         0 means the network connection is closed.
 *         -1 indicates a failure. The reason for the failure is obtained
 *         by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRInt32) PR_RecvFrom(
    PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
    PRNetAddr *addr, PRIntervalTime timeout);

/*
 *************************************************************************
 * FUNCTION: PR_SendTo
 * DESCRIPTION:
 *    Send a specified number of bytes from an unconnected socket.
 *    The operation will block until all bytes are 
 *    sent, a time out has occurred, or there is an error. 
 * INPUTS:
 *     PRFileDesc *fd
 *       points to a PRFileDesc object representing an unconnected socket.
 *     void *buf
 *       pointer to a buffer from where the data is sent.
 *     PRInt32 amount
 *       the size of 'buf' (in bytes)
 *     PRIntn flags
 *        (OBSOLETE - must always be zero)
 *     PRNetAddr *addr
 *       Specifies the address of the peer.
.*     PRIntervalTime timeout
 *       Time limit for completion of the send operation.
 * OUTPUTS:
 *     None
 * RETURN: PRInt32
 *     A positive number indicates the number of bytes successfully sent.
 *     -1 indicates a failure. The reason for the failure is obtained
 *     by calling PR_GetError().
 **************************************************************************
 */

PR_EXTERN(PRInt32) PR_SendTo(
    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
    const PRNetAddr *addr, PRIntervalTime timeout);

/*
*************************************************************************
** FUNCTION: PR_TransmitFile
** DESCRIPTION:
**    Transmitfile sends a complete file (sourceFile) across a socket 
**    (networkSocket).  If headers is non-NULL, the headers will be sent across
**    the socket prior to sending the file.
** 
**    Optionally, the PR_TRANSMITFILE_CLOSE_SOCKET flag may be passed to
**    transmitfile.  This flag specifies that transmitfile should close the
**    socket after sending the data.
**
** INPUTS:
**    PRFileDesc *networkSocket
**        The socket to send data over
**    PRFileDesc *sourceFile
**        The file to send
**    const void *headers
**        A pointer to headers to be sent before sending data
**    PRInt32       hlen
**        length of header buffers in bytes.
**    PRTransmitFileFlags       flags
**        If the flags indicate that the connection should be closed,
**        it will be done immediately after transferring the file, unless
**        the operation is unsuccessful. 
.*     PRIntervalTime timeout
 *        Time limit for completion of the transmit operation.
**
** RETURNS:
**    Returns the number of bytes written or -1 if the operation failed.
**    If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_
**    SOCKET flag is ignored. The reason for the failure is obtained
**    by calling PR_GetError().
**************************************************************************
*/

PR_EXTERN(PRInt32) PR_TransmitFile(
    PRFileDesc *networkSocket, PRFileDesc *sourceFile,
    const void *headers, PRInt32 hlen, PRTransmitFileFlags flags,
    PRIntervalTime timeout);
/*
*************************************************************************
** FUNCTION: PR_AcceptRead
** DESCRIPTION:
**    AcceptRead accepts a new connection, returns the newly created
**    socket's descriptor and also returns the connecting peer's address.
**    AcceptRead, as its name suggests, also receives the first block of data 
**    sent by the peer.
**
** INPUTS:
**    PRFileDesc *listenSock
**        A socket descriptor that has been called with the PR_Listen() 
**        function, also known as the rendezvous socket.
**    void *buf
**        A pointer to a buffer to receive data sent by the client.  This 
**        buffer must be large enough to receive <amount> bytes of data
**        and two PRNetAddr structures, plus an extra 32 bytes.
**    PRInt32 amount
**        The number of bytes of client data to receive.  Does not include
**        the size of the PRNetAddr structures.  If 0, no data will be read
**        from the client.
**    PRIntervalTime timeout
**        The timeout interval only applies to the read portion of the 
**        operation.  PR_AcceptRead will block indefinitely until the 
**        connection is accepted; the read will timeout after the timeout 
**        interval elapses.
** OUTPUTS:
**    PRFileDesc **acceptedSock
**        The file descriptor for the newly connected socket.  This parameter
**        will only be valid if the function return does not indicate failure.
**    PRNetAddr  **peerAddr,
**        The address of the remote socket.  This parameter will only be
**        valid if the function return does not indicate failure.  The
**        returned address is not guaranteed to be properly aligned.
** 
** RETURNS:
**     The number of bytes read from the client or -1 on failure.  The reason 
**     for the failure is obtained by calling PR_GetError().
**************************************************************************
**/
PR_EXTERN(PRInt32) PR_AcceptRead(
    PRFileDesc *listenSock, PRFileDesc **acceptedSock,
    PRNetAddr **peerAddr, void *buf, PRInt32 amount, PRIntervalTime timeout);

/*
*************************************************************************
** FUNCTION: PR_NewTCPSocketPair
** DESCRIPTION:
**    Create a new TCP socket pair. The returned descriptors can be used
**    interchangeably; they are interconnected full-duplex descriptors: data
**    written to one can be read from the other and vice-versa.
**
** INPUTS:
**    None
** OUTPUTS:
**    PRFileDesc *fds[2]
**        The file descriptor pair for the newly created TCP sockets.
** RETURN: PRStatus
**     Upon successful completion of TCP socket pair, PR_NewTCPSocketPair 
**     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
**     failure information can be obtained by calling PR_GetError().
** XXX can we implement this on windoze and mac?
**************************************************************************
**/
PR_EXTERN(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]);

/*
*************************************************************************
** FUNCTION: PR_GetSockName
** DESCRIPTION:
**    Get socket name.  Return the network address for this socket.
**
** INPUTS:
**     PRFileDesc *fd
**       Points to a PRFileDesc object representing the socket.
** OUTPUTS:
**     PRNetAddr *addr
**       Returns the address of the socket in its own communication space.
** RETURN: PRStatus
**     Upon successful completion, PR_GetSockName returns PR_SUCCESS.  
**     Otherwise, it returns PR_FAILURE.  Further failure information can 
**     be obtained by calling PR_GetError().
**************************************************************************
**/
PR_EXTERN(PRStatus)	PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr);

/*
*************************************************************************
** FUNCTION: PR_GetPeerName
** DESCRIPTION:
**    Get name of the connected peer.  Return the network address for the 
**    connected peer socket.
**
** INPUTS:
**     PRFileDesc *fd
**       Points to a PRFileDesc object representing the connected peer.
** OUTPUTS:
**     PRNetAddr *addr
**       Returns the address of the connected peer in its own communication
**       space.
** RETURN: PRStatus
**     Upon successful completion, PR_GetPeerName returns PR_SUCCESS.  
**     Otherwise, it returns PR_FAILURE.  Further failure information can 
**     be obtained by calling PR_GetError().
**************************************************************************
**/
PR_EXTERN(PRStatus)	PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr);

PR_EXTERN(PRStatus)	PR_GetSocketOption(
    PRFileDesc *fd, PRSocketOptionData *data);

PR_EXTERN(PRStatus)	PR_SetSocketOption(
    PRFileDesc *fd, const PRSocketOptionData *data);

/*
 *********************************************************************
 *
 * Memory-mapped files
 *
 *********************************************************************
 */

typedef struct PRFileMap PRFileMap;

/*
 * protection options for read and write accesses of a file mapping
 */
typedef enum PRFileMapProtect {
    PR_PROT_READONLY,     /* read only */
    PR_PROT_READWRITE,    /* readable, and write is shared */
    PR_PROT_WRITECOPY     /* readable, and write is private (copy-on-write) */
} PRFileMapProtect;

PR_EXTERN(PRFileMap *) PR_CreateFileMap(
    PRFileDesc *fd,
    PRInt64 size,
    PRFileMapProtect prot);

PR_EXTERN(void *) PR_MemMap(
    PRFileMap *fmap,
    PRInt64 offset,  /* must be aligned and sized to whole pages */
    PRUint32 len);

PR_EXTERN(PRStatus) PR_MemUnmap(void *addr, PRUint32 len);

PR_EXTERN(PRStatus) PR_CloseFileMap(PRFileMap *fmap);

/*
 ******************************************************************
 *
 * Interprocess communication
 *
 ******************************************************************
 */

/*
 * Creates an anonymous pipe and returns file descriptors for the
 * read and write ends of the pipe.
 */

PR_EXTERN(PRStatus) PR_CreatePipe(
    PRFileDesc **readPipe,
    PRFileDesc **writePipe
);

/************************************************************************/
/************** The following definitions are for poll ******************/
/************************************************************************/

struct PRPollDesc {
    PRFileDesc* fd;
    PRInt16 in_flags;
    PRInt16 out_flags;
};

/*
** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or
** these together to produce the desired poll request.
*/

#if defined(_PR_POLL_BACKCOMPAT)

#include <poll.h>
#define PR_POLL_READ    POLLIN
#define PR_POLL_WRITE   POLLOUT
#define PR_POLL_EXCEPT  POLLPRI
#define PR_POLL_ERR     POLLERR     /* only in out_flags */
#define PR_POLL_NVAL    POLLNVAL    /* only in out_flags when fd is bad */
#define PR_POLL_HUP     POLLHUP     /* only in out_flags */

#else  /* _PR_POLL_BACKCOMPAT */

#define PR_POLL_READ    0x1
#define PR_POLL_WRITE   0x2
#define PR_POLL_EXCEPT  0x4
#define PR_POLL_ERR     0x8         /* only in out_flags */
#define PR_POLL_NVAL    0x10        /* only in out_flags when fd is bad */
#define PR_POLL_HUP     0x20        /* only in out_flags */

#endif  /* _PR_POLL_BACKCOMPAT */

/*
*************************************************************************
** FUNCTION:    PR_Poll
** DESCRIPTION:
**
** The call returns as soon as I/O is ready on one or more of the underlying
** file/socket objects. A count of the number of ready descriptors is
** returned unless a timeout occurs in which case zero is returned.
**
** PRPollDesc.in_flags should be set to the desired request
** (read/write/except or some combination). Upon return from this call
** PRPollDesc.out_flags will be set to indicate what kind of i/o can be
** performed on the respective descriptor.
**
** INPUTS:
**      PRPollDesc *pds         A pointer to an array of PRPollDesc
**
**      PRIntn npds             The number of elements in the array
**                              If this argument is zero PR_Poll is
**                              equivalent to a PR_Sleep(timeout).
**
**      PRIntervalTime timeout  Amount of time the call will block waiting
**                              for I/O to become ready. If this time expires
**                              w/o any I/O becoming ready, the result will
**                              be zero.
**
** OUTPUTS:    None
** RETURN:
**      PRInt32                 Number of PRPollDesc's with events or zero
**                              if the function timed out or -1 on failure.
**                              The reason for the failure is obtained by calling 
**                              PR_GetError().
** XXX can we implement this on windoze and mac?
**************************************************************************
*/
PR_EXTERN(PRInt32) PR_Poll(
    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout);

/*
**************************************************************************
**
** Pollable events
**
** A pollable event is a special kind of file descriptor.
** The only I/O operation you can perform on a pollable event
** is to poll it with the PR_POLL_READ flag.  You can't
** read from or write to a pollable event.
**
** The purpose of a pollable event is to combine event waiting
** with I/O waiting in a single PR_Poll call.  Pollable events
** are implemented using a pipe or a pair of TCP sockets
** connected via the loopback address, therefore setting and
** waiting for pollable events are expensive operating system
** calls.  Do not use pollable events for general thread
** synchronization. Use condition variables instead.
**
** A pollable event has two states: set and unset.  Events
** are not queued, so there is no notion of an event count.
** A pollable event is either set or unset.
**
** A new pollable event is created by a PR_NewPollableEvent
** call and is initially in the unset state.
**
** PR_WaitForPollableEvent blocks the calling thread until
** the pollable event is set, and then it atomically unsets
** the pollable event before it returns.
**
** To set a pollable event, call PR_SetPollableEvent.
**
** One can call PR_Poll with the PR_POLL_READ flag on a pollable
** event.  When the pollable event is set, PR_Poll returns with
** the PR_POLL_READ flag set in the out_flags.
**
** To close a pollable event, call PR_DestroyPollableEvent
** (not PR_Close).
**
**************************************************************************
*/

PR_EXTERN(PRFileDesc *) PR_NewPollableEvent(void);

PR_EXTERN(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event);

PR_EXTERN(PRStatus) PR_SetPollableEvent(PRFileDesc *event);

PR_EXTERN(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event);

PR_END_EXTERN_C

#endif /* prio_h___ */


syntax highlighted by Code2HTML, v. 0.9.1