while ((fd = accept((int)sockfd, (struct sockaddr *)peer, (int *)addrlen)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid descriptor";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Address not in writeable part of user address space";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Descriptor not a socket";
- break;
- case GHC_EOPNOTSUPP:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Socket not of type that supports listen";
- break;
- case GHC_EWOULDBLOCK:
- ghc_errtype = ERR_OTHERERROR;
- ghc_errstr = "No sockets are present to be accepted";
- break;
- }
+ stdErrno();
return -1;
}
}
while ((rc = bind((int)sockfd, (struct sockaddr *)myaddr, (int)addrlen)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EACCES:
- ghc_errtype = ERR_PERMISSIONDENIED;
- if (isUnixDomain != 0)
- ghc_errstr = "For a component of path prefix of path name";
- else
- ghc_errstr = "Requested address protected, cannot bind socket";
- break;
- case GHC_EISCONN:
- case GHC_EADDRINUSE:
- ghc_errtype = ERR_RESOURCEBUSY;
- ghc_errstr = "Address already in use";
- break;
- case GHC_EADDRNOTAVAIL:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "Address not available from local machine";
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid socket file descriptor";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Address not in valid part of user address space";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Specified size of structure not equal valid address for family";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "Descriptor for file, not a socket";
- break;
- case GHC_EIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Could not make directory entry or alloc inode";
- break;
- case GHC_EISDIR:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "A null path name was given";
- break;
- case GHC_ELOOP:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Too many symbolic links encountered";
- break;
- case GHC_ENAMETOOLONG:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Max length of path name exceeded";
- break;
- case GHC_ENOENT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Component in path prefix does not exist";
- break;
- case GHC_ENOTDIR:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Component in path prefix is not a directory";
- break;
- case GHC_EROFS:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "The inode would reside on read only file system";
- break;
- }
+ stdErrno();
return -1;
}
}
#include "ghcSockets.h"
StgInt
-connectSocket(I_ sockfd, A_ servaddr, I_ addrlen, I_ isUnixDomain)
+connectSocket(sockfd, servaddr, addrlen, isUnixDomain)
+StgInt sockfd;
+StgAddr servaddr;
+StgInt addrlen;
+StgInt isUnixDomain;
{
int rc;
while ((rc = connect((int)sockfd, (struct sockaddr *)servaddr, (int)addrlen)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EACCES:
- ghc_errtype = ERR_PERMISSIONDENIED;
- if (isUnixDomain != 0)
- ghc_errstr = "For a component of path prefix of path name";
- else
- ghc_errstr = "Requested address protected, cannot bind socket";
- break;
- case GHC_EISCONN:
- case GHC_EADDRINUSE:
- ghc_errtype = ERR_RESOURCEBUSY;
- ghc_errstr = "Address already in use";
- break;
- case GHC_EADDRNOTAVAIL:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "Address not available from local machine";
- break;
- case GHC_EAFNOSUPPORT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Address cannot be used with socket";
- break;
- case GHC_EINPROGRESS:
- case GHC_EALREADY:
- ghc_errtype = ERR_RESOURCEBUSY;
- ghc_errstr = "Non-blocking socket, previous connection attempt not completed";
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid socket file descriptor";
- break;
- case GHC_ECONNREFUSED:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "Connection rejected";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Address not in valid part of process address space";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Specified size of structure not equal valid address for family";
- break;
- break;
- case GHC_ENETUNREACH:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "Network not reachable from host";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "Descriptor for file, not a socket";
- break;
- case GHC_ETIMEDOUT:
- ghc_errtype = ERR_TIMEEXPIRED;
- ghc_errstr = "Connection attempt timed out";
- break;
- case GHC_EIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Could not make directory entry or alloc inode";
- break;
- case GHC_EISDIR:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "A null path name was given";
- break;
- case GHC_ELOOP:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Too many symbolic links encountered";
- break;
- case GHC_ENAMETOOLONG:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Max length of path name exceeded";
- break;
- case GHC_ENOENT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Component in path prefix does not exist";
- break;
- case GHC_ENOTDIR:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Component in path prefix is not a directory";
- break;
- case GHC_EPROTOTYPE:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "File referred to is a socket of differing type";
- break;
- }
+ stdErrno();
return -1;
}
}
if ((fd = socket((int)family, (int)type, (int)protocol)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EACCES:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "cannot create socket";
- break;
- case GHC_EMFILE:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "Too many open files";
- break;
- case GHC_ENFILE:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "System file table overflow";
- break;
- case GHC_EPROTONOSUPPORT:
- ghc_errtype = ERR_UNSUPPORTEDOPERATION;
- ghc_errstr = "Protocol type not supported";
- break;
- case GHC_EPROTOTYPE:
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "Protocol wrong type for socket";
- break;
- }
- return (StgInt)-1;
+ stdErrno();
+ return -1;
}
}
- return (StgInt)fd;
+ return fd;
}
while ((name = getpeername((int) sockfd, (struct sockaddr *) peer, (int *) namelen)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid write descriptor";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Data not in writeable part of user address space";
- break;
- case GHC_ENOBUFS:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "Insuffcient resources";
- break;
- case GHC_ENOTCONN:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Socket not connected";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Descriptor is not a socket";
- break;
- }
+ stdErrno();
return -1;
}
}
while ((name = getsockname((int) sockfd, (struct sockaddr *) peer, (int *) namelen)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid write descriptor";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Data not in writeable part of user address space";
- break;
- case GHC_ENOBUFS:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "Insuffcient resources";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Descriptor is not a socket";
- break;
- }
+ stdErrno();
return -1;
}
}
/* sendTo.c */
StgInt sendTo__ PROTO((StgInt, StgAddr, StgInt, StgAddr, StgInt));
+/* socketOpt.c */
+StgInt getSocketOption__ PROTO((StgInt, StgInt));
+StgInt setSocketOption__ PROTO((StgInt, StgInt, StgInt));
+
/* writeDescriptor.lc */
StgInt writeDescriptor PROTO((StgInt, StgAddr, StgInt));
while ((rc = listen((int) sockfd, (int) backlog)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid descriptor";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Descriptor not a socket";
- break;
- case GHC_EOPNOTSUPP:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Socket not of type that supports listen";
- break;
- }
+ stdErrno();
return -1;
}
}
while ((sucked = read((int) fd, (char *) buf, (int) nbytes)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid read descriptor";
- break;
- case GHC_EBADMSG:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Message waiting to be read is not a data message";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Data buffer not in readable part of user address space";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Seek pointer associated with descriptor negative";
- break;
- case GHC_EIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "I/O error occurred while reading";
- break;
- case GHC_EISDIR:
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "Descriptor refers to a directory";
- break;
- case GHC_EAGAIN:
- case GHC_EWOULDBLOCK:
- ghc_errtype = ERR_OTHERERROR;
- ghc_errstr = "No data could be read immediately";
- break;
- default:
- stdErrno();
- break;
- }
+ stdErrno();
return -1;
}
}
while ( (count = recvfrom((int)fd, (void*)buf, (int)nbytes, flags, (struct sockaddr*)from, &sz)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid read descriptor";
- break;
- case GHC_EBADMSG:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Message waiting to be read is not a data message";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Data buffer not in readable part of user address space";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Seek pointer associated with descriptor negative";
- break;
- case GHC_EIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "I/O error occurred while reading";
- break;
- case GHC_EISDIR:
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "Descriptor refers to a directory";
- break;
- case GHC_EAGAIN:
- case GHC_EWOULDBLOCK:
- ghc_errtype = ERR_OTHERERROR;
- ghc_errstr = "No data could be read immediately";
- break;
- default:
- stdErrno();
- break;
- }
+ stdErrno();
return -1;
}
- }
- return count;
+ }
+ return count;
}
while ( (count = sendto((int)fd, (void*)buf, (int)nbytes, flags, (struct sockaddr*)to, sz)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid read descriptor";
- break;
- case GHC_EBADMSG:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Message waiting to be read is not a data message";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Data buffer not in readable part of user address space";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Seek pointer associated with descriptor negative";
- break;
- case GHC_EIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "I/O error occurred while reading";
- break;
- case GHC_EISDIR:
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "Descriptor refers to a directory";
- break;
- case GHC_EAGAIN:
- case GHC_EWOULDBLOCK:
- ghc_errtype = ERR_OTHERERROR;
- ghc_errstr = "No data could be read immediately";
- break;
- default:
- stdErrno();
- break;
- }
+ stdErrno();
return -1;
}
- }
- return count;
+ }
+ return count;
}
while ((rc = shutdown((int) sockfd, (int) how)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid write descriptor";
- break;
- case GHC_ENOTCONN:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Socket not connected";
- break;
- case GHC_ENOTSOCK:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Descriptor is not a socket";
- break;
- }
+ stdErrno();
return -1;
}
}
--- /dev/null
+#if 0
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1998
+%
+\subsection[socketOpt.lc]{Setting/Getting socket opts}
+
+\begin{code}
+#endif
+
+#define NON_POSIX_SOURCE
+#include "rtsdefs.h"
+#include "ghcSockets.h"
+
+StgInt
+getSocketOption__ (fd, opt)
+StgInt fd;
+StgInt opt;
+{
+ int level,optval, sz_optval,rc;
+
+ if ( opt == TCP_MAXSEG || opt == TCP_NODELAY ) {
+ level = IPPROTO_TCP;
+ } else {
+ level = SOL_SOCKET;
+ }
+
+ sz_optval = sizeof(int);
+
+ while ( (rc = getsockopt((int)fd, level, opt, &optval, &sz_optval)) < 0 ) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return -1;
+ }
+ }
+ return optval;
+}
+
+StgInt
+setSocketOption__ (fd, opt, val)
+StgInt fd;
+StgInt opt;
+StgInt val;
+{
+ int level, optval,rc;
+
+ if ( opt == TCP_MAXSEG || opt == TCP_NODELAY ) {
+ level = IPPROTO_TCP;
+ } else {
+ level = SOL_SOCKET;
+ }
+
+ optval = val;
+
+ while ( (rc = setsockopt((int)fd, level, opt, &optval, sizeof(optval))) < 0 ) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return -1;
+ }
+ }
+ return 0;
+}
while ((dumped = write((int) fd, (char *) buf, (int) nbytes)) < 0) {
if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_EBADF:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Not a valid write descriptor";
- break;
- case GHC_EDQUOT:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "Disk quota exhausted";
- break;
- case GHC_EFAULT:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Data not in writeable part of user address space";
- break;
- case GHC_EFBIG:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "Maximum process or system file size exceeded";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Seek pointer associated with descriptor negative";
- break;
- case GHC_EIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "I/O error occurred while writing to file system";
- break;
- case GHC_ENOSPC:
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "No space left on device";
- break;
- case GHC_ENXIO:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Hangup occurred";
- break;
- case GHC_EPIPE:
- ghc_errtype = ERR_SYSTEMERROR;
- ghc_errstr = "Write to not read pipe/unconnected socket caught";
- break;
- case GHC_ERANGE:
- ghc_errtype = ERR_INVALIDARGUMENT;
- ghc_errstr = "Too much or too little written to descriptor";
- break;
- case GHC_EAGAIN:
- case GHC_EWOULDBLOCK:
- ghc_errtype = ERR_OTHERERROR;
- ghc_errstr = "No data could be written immediately";
- break;
- }
+ stdErrno();
return -1;
}
}