/* $Id: socket.h 1154 2004-02-03 19:56:37Z bird $ */ /** @file * * Interal libsocket stuff. * * Copyright (c) 2003 knut st. osmundsen * * * This file is part of Innotek LIBC. * * Innotek LIBC is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Innotek LIBC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Innotek LIBC; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __socket_h__ #define __socket_h__ /** @group libsocket libsocket * @{ */ /******************************************************************************* * Defined Constants And Macros * *******************************************************************************/ /** The offset the OS/2 TCP/IP errno values are skewed compared to the * LIBC errno values. */ #define EOS2_TCPIP_OFFSET 10000 /** Get the low word of the ioctl request number. * Used to support ioctl request numbers from old and new _IOC macros. */ #define __IOCLW(a) ((unsigned short)(a)) #ifndef TCPV40HDRS #define V5_FD_SETSIZE 64 #define V5_FD_SET(fd, set) do { \ /* if (((v5_fd_set *)(set))->fd_count < V5_FD_SETSIZE) - calcsize fixes this */ \ ((v5_fd_set *)(set))->fd_array[((v5_fd_set *)(set))->fd_count++]=fd;\ } while(0) #define V5_FD_ISSET(fd, set) v5_isset(fd, set) #endif /******************************************************************************* * Structures and Typedefs * *******************************************************************************/ /** Socket handle.*/ typedef struct __libc_SocketHandle { /** the common fh core. */ LIBCFH core; /** OS/2 socket number. */ int iSocket; } LIBCSOCKETFH, *PLIBCSOCKETFH; #ifndef TCPV40HDRS #pragma pack(4) /** OS/2 oddities from the BSD 4.4 stack. */ typedef struct v5_fd_set { u_short fd_count; /* how many are SET? */ int fd_array[V5_FD_SETSIZE];/* an array of SOCKETs */ } v5_fd_set; #pragma pack() /** internal helper */ static inline int v5_isset(int fd, const struct v5_fd_set *set) { const int *pfd = &set->fd_array[0]; int c = set->fd_count; while (c > 0) { if (*pfd == fd) return 1; pfd++; c--; } return 0; } #endif /******************************************************************************* * Global Variables * *******************************************************************************/ extern LIBCFHOPS __libsocket_gSocketOps; /******************************************************************************* * Internal Functions * *******************************************************************************/ /** @defgroup libsocket_renamed Renamed Imports. * @{ */ int TCPCALL __libsocket_accept(int, struct sockaddr *, int *); int TCPCALL __libsocket_bind(int, __const__ struct sockaddr *, int); int TCPCALL __libsocket_connect(int, __const__ struct sockaddr *, int); int TCPCALL __libsocket_getpeername(int, struct sockaddr *, int *); int TCPCALL __libsocket_getsockname(int, struct sockaddr *, int *); int TCPCALL __libsocket_getsockopt(int, int, int, void *, int *); int TCPCALL __libsocket_ioctl(int, int, char *); int TCPCALL __libsocket_listen(int, int); int TCPCALL __libsocket_os2_ioctl(int, unsigned long, char *, int); int TCPCALL __libsocket_os2_select(int *, int, int, int, long); int TCPCALL __libsocket_recv(int, void *, int, int); int TCPCALL __libsocket_recv(int, void *, int, int); int TCPCALL __libsocket_recvfrom(int, void *, int, int, struct sockaddr *, int *); int TCPCALL __libsocket_recvmsg(int, struct msghdr *, int); int TCPCALL __libsocket_send(int, __const__ void *, int, int); int TCPCALL __libsocket_send(int, const void *, int, int); int TCPCALL __libsocket_sendmsg(int, __const__ struct msghdr *, int); int TCPCALL __libsocket_sendto(int, __const__ void *, int, int, __const__ struct sockaddr *, int); int TCPCALL __libsocket_setsockopt(int, int, int, __const__ void *, int); int TCPCALL __libsocket_shutdown(int, int); int TCPCALL __libsocket_sock_errno(void); int TCPCALL __libsocket_socket(int, int, int); int TCPCALL __libsocket_socket(int, int, int); int TCPCALL __libsocket_socketpair(int, int, int, int *); int TCPCALL __libsocket_soclose(int); int TCPCALL __libsocket_accept_and_recv(long, long*, struct sockaddr *, long*, struct sockaddr*, long*, caddr_t, size_t); void TCPCALL __libsocket_addsockettolist(int); int TCPCALL __libsocket_removesocketfromlist(int); ssize_t TCPCALL __libsocket_so_readv(int, struct iovec *, int); ssize_t TCPCALL __libsocket_so_writev(int, struct iovec *, int); int TCPCALL __libsocket_so_cancel(int); int TCPCALL __libsocket_soabort(int); int TCPCALL __libsocket_Raccept(int, struct sockaddr *, int *); struct sockaddr_in; int TCPCALL __libsocket_tcpip4_Rbind(int, struct sockaddr_in *, int, struct sockaddr_in *); int TCPCALL __libsocket_Rbind(int, struct sockaddr *, int, struct sockaddr *); int TCPCALL __libsocket_Rconnect(int, const struct sockaddr *, int); int TCPCALL __libsocket_Rgetsockname(int, struct sockaddr *, int *); int TCPCALL __libsocket_Rlisten(int, int); #ifndef TCPV40HDRS ssize_t TCPCALL __libsocket_send_file(int *, struct sf_parms *, int ); #endif char * TCPCALL __libsocket_sock_strerror(int); int TCPCALL __libsocket_pair(int af, int type, int flags, int *osfd); #ifdef TCPV40HDRS int TCPCALL __libsocket_bsdselect(int, fd_set *, fd_set *, fd_set *, struct timeval *); #else int TCPCALL __libsocket_bsdselect(int, v5_fd_set *, v5_fd_set *, v5_fd_set *, struct timeval *); #endif void TCPCALL __libsocket_set_errno(int); /** @} */ /** @defgroup libsocket_internal Internal helpers. * @{ */ /** * Sets the LIBC and socket errno variables to a given error number. */ static inline void __libsocket_setErrno(int err) { errno = err; __libsocket_set_errno(err + EOS2_TCPIP_OFFSET); } /** * Updates the LIBC errno with the latest socket error. */ static inline void __libsocket_setLibcErrno(void) { int err = __libsocket_sock_errno(); if (err >= EOS2_TCPIP_OFFSET && err < EOS2_TCPIP_OFFSET + 1000) errno = err - EOS2_TCPIP_OFFSET; } /** * Updates the socket errno with the latest LIBC error. */ static inline void __libsocket_setSocketErrno(void) { __libsocket_set_errno(errno + EOS2_TCPIP_OFFSET); } /** * Gets the socket errno translating it to a LIBC errno. */ static inline int __libsocket_getSocketErrno(void) { int err = __libsocket_sock_errno(); if (err >= EOS2_TCPIP_OFFSET && err < EOS2_TCPIP_OFFSET + 1000) return err - EOS2_TCPIP_OFFSET; return EDOOFUS; } /** * Retrieve the socket handle structure for a given handle. * @returns Pointer to socket handle structure on success. * @returns NULL on failure with errno set to the appropriate value. * @param socket Socket handle number. */ static inline PLIBCSOCKETFH __libsocket_FH(int socket) { PLIBCSOCKETFH pFHSocket = (PLIBCSOCKETFH)__libc_FH(socket); if (pFHSocket) { if ((pFHSocket->core.fFlags & F_TYPEMASK) == F_SOCKET) return pFHSocket; __libsocket_setErrno(ENOSYS); } else __libsocket_setErrno(EBADF); return NULL; } /** @} */ /** @} */ #endif