diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2005-10-03 13:43:40 +0000 |
---|---|---|
committer | <> | 2014-09-25 11:25:48 +0000 |
commit | 10de491ef0bc43827ab8631a4c02860134e620a9 (patch) | |
tree | 22e734337cc9aa5d9b1d7c71261d160b6a60634d /os2/porttcp.c | |
download | cvs-tarball-master.tar.gz |
Imported from /home/lorry/working-area/delta_cvs-tarball/cvs-1.12.13.tar.bz2.HEADcvs-1.12.13master
Diffstat (limited to 'os2/porttcp.c')
-rw-r--r-- | os2/porttcp.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/os2/porttcp.c b/os2/porttcp.c new file mode 100644 index 0000000..a64b511 --- /dev/null +++ b/os2/porttcp.c @@ -0,0 +1,227 @@ +/**************************************************************** +** +** PORTTCP.C - Support for portable TCP/IP +** +****************************************************************/ + +#define TCPIP_IBM_NOHIDE +#include <stdio.h> +#include "tcpip.h" + +/* + * Common unknown error buffer + */ +static char ErrUnknownBuf[36]; + +#ifndef SockStrError + +/**************************************************************** + * Routine: SockStrError + * Returns: Pointer to static buffer + * Action : Convert SOCK_ERRNO into error text + ****************************************************************/ + +const char * +SockStrError(int SockErrno) +{ +#if defined (TCPIP_IBM) && defined (IBM_CPP) + switch (SockErrno) + { + case SOCEPERM: return "Not owner"; + case SOCESRCH: return "No such process"; + case SOCEINTR: return "Interrupted system call"; + case SOCENXIO: return "No such device or address"; + case SOCEBADF: return "Bad file number"; + case SOCEACCES: return "Permission denied"; + case SOCEFAULT: return "Bad address"; + case SOCEINVAL: return "Invalid argument"; + case SOCEMFILE: return "Too many open files"; + case SOCEPIPE: return "Broken pipe"; + case SOCEOS2ERR: return "OS/2 Error"; + case SOCEWOULDBLOCK: return "Operation would block"; + case SOCEINPROGRESS: return "Operation now in progress"; + case SOCEALREADY: return "Operation already in progress"; + case SOCENOTSOCK: return "Socket operation on non-socket"; + case SOCEDESTADDRREQ: return "Destination address required"; + case SOCEMSGSIZE: return "Message too long"; + case SOCEPROTOTYPE: return "Protocol wrong type for socket"; + case SOCENOPROTOOPT: return "Protocol not available"; + case SOCEPROTONOSUPPORT: return "Protocol not supported"; + case SOCESOCKTNOSUPPORT: return "Socket type not supported"; + case SOCEOPNOTSUPP: return "Operation not supported on socket"; + case SOCEPFNOSUPPORT: return "Protocol family not supported"; + case SOCEAFNOSUPPORT: + return "Address family not supported by protocol family"; + case SOCEADDRINUSE: return "Address already in use"; + case SOCEADDRNOTAVAIL: return "Can't assign requested address"; + case SOCENETDOWN: return "Network is down"; + case SOCENETUNREACH: return "Network is unreachable"; + case SOCENETRESET: return "Network dropped connection on reset"; + case SOCECONNABORTED: return "Software caused connection abort"; + case SOCECONNRESET: return "Connection reset by peer"; + case SOCENOBUFS: return "No buffer space available"; + case SOCEISCONN: return "Socket is already connected"; + case SOCENOTCONN: return "Socket is not connected"; + case SOCESHUTDOWN: return "Can't send after socket shutdown"; + case SOCETOOMANYREFS: return "Too many references: can't splice"; + case SOCETIMEDOUT: return "Connection timed out"; + case SOCECONNREFUSED: return "Connection refused"; + case SOCELOOP: return "Too many levels of symbolic links"; + case SOCENAMETOOLONG: return "File name too long"; + case SOCEHOSTDOWN: return "Host is down"; + case SOCEHOSTUNREACH: return "No route to host"; + case SOCENOTEMPTY: return "Directory not empty"; + + default: + sprintf( ErrUnknownBuf, "SockStrErrno( %d ) unknown", SockErrno ); + return ErrUnknownBuf; + } +#else +#error SockStrError not supported for this OS +#endif +} + +#endif /* SockStrError */ + + +/**************************************************************** + * Routine: HostStrError + * Returns: Pointer to static buffer + * Action : Convert HOST_ERRNO into error text + ****************************************************************/ + +const char * +HostStrError(int HostErrno) +{ + switch (HostErrno) + { + case HOST_NOT_FOUND: + return "Host not found"; + case TRY_AGAIN: + return "Host not found (suggest try again)"; + case NO_RECOVERY: + return "Non-recoverable error: FORMERR, REFUSED, NOTIMP"; + case NO_DATA: + return "No Data (valid name, but no record of requested type)"; + + default: + sprintf( ErrUnknownBuf, "HostStrErrno( %d ) unknown", HostErrno ); + return ErrUnknownBuf; + } +} + + +#if defined( TCPIP_IBM ) +/**************************************************************** + * Routine: IbmSockSend + * Returns: same as send + * Action : Do the right thing for IBM TCP/IP which includes + * the following two stupidities: + * 1) Never try to send more than 32K + * 2) Never pass a buffer that crosses a 64K boundary + * If Flags is non-zero, this function only attempts + * to deal with condition (1) above. + ****************************************************************/ + +int +IbmSockSend (int Socket, const void *Buffer, int Len, int Flags) +{ + int Sent, ToSend, TotalSent = 0; + + const char *Tmp = Buffer; + + /* + * If Flags have been passed in, the 64K boundary optimization + * can not be performed. For example, MSG_PEEK would not work + * correctly. + */ + if (Flags) + return send (Socket, (char *) Buffer, min (0x7FFF, Len), Flags); + + do + { + /* Never send across a 64K boundary */ + ToSend = min (Len, (int) (0x10000 - (0xFFFF & (long) Tmp))); + + /* Never send more than 32K */ + if (ToSend > 0x7FFF) + ToSend = 0x7FFF; + + Sent = send (Socket, (char *) Tmp, ToSend, 0); + if (Sent < 0) + { + if ((TotalSent > 0) && (SOCK_ERRNO == EWOULDBLOCK)) + return TotalSent; + if (SOCK_ERRNO == EINTR) + continue; + return Sent; + } + if (Sent < ToSend) + return TotalSent + Sent; + + Tmp += Sent; + TotalSent += Sent; + Len -= Sent; + } while (Len > 0); + + return TotalSent; +} + + + +/**************************************************************** + * Routine: IbmSockRecv + * Returns: same as recv + * Action : Do the right thing for IBM TCP/IP which includes + * the following two stupidities: + * 1) Never try to recv more than 32K + * 2) Never pass a buffer that crosses a 64K boundary + * If Flags is non-zero, this function only attempts + * to deal with condition (1) above. + ****************************************************************/ + +int +IbmSockRecv (int Socket, const void *Buffer, int Len, int Flags) +{ + int Recvd, ToRecv, TotalRecvd = 0; + + char *Tmp = Buffer; + + /* If Flags have been passed in, the 64K boundary optimization + probably can not be performed. */ + + if (Flags) + return recv (Socket, Buffer, min (0x7FFF, Len), Flags); + + do + { + /* Never send across a 64K boundary */ + ToRecv = min( Len, (int)( 0x10000 - ( 0xFFFF & (long)Tmp ))); + + /* Never send more than 32K */ + if( ToRecv > 0x7FFF ) + ToRecv = 0x7FFF; + + Recvd = recv (Socket, Tmp, ToRecv, 0); + if (Recvd <= 0) + { + if ((TotalRecvd > 0) + && (Recvd == 0 || (SOCK_ERRNO == EWOULDBLOCK ))) + return TotalRecvd; + if (SOCK_ERRNO == EINTR) + continue; + + return Recvd; + } + if (Recvd < ToRecv) + return TotalRecvd + Recvd; + + Tmp += Recvd; + TotalRecvd += Recvd; + Len -= Recvd; + } while (Len > 0); + + return TotalRecvd; +} +#endif /* defined( TCPIP_IBM ) */ + |