summaryrefslogtreecommitdiff
path: root/comm/Socket.cc
diff options
context:
space:
mode:
authorchatty1993-04-07 11:50:31 +0000
committerchatty1993-04-07 11:50:31 +0000
commitba066c34dde204aa192d03a23a81356374d93731 (patch)
tree39391f6235d2cf8a59a0634ac5ea430cdd21f5d4 /comm/Socket.cc
parent05ab076e1c2a9ca16472f9a6b47b8d22914b3783 (diff)
downloadivy-league-ba066c34dde204aa192d03a23a81356374d93731.zip
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.gz
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.bz2
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.xz
Initial revision
Diffstat (limited to 'comm/Socket.cc')
-rw-r--r--comm/Socket.cc274
1 files changed, 274 insertions, 0 deletions
diff --git a/comm/Socket.cc b/comm/Socket.cc
new file mode 100644
index 0000000..1d5a542
--- /dev/null
+++ b/comm/Socket.cc
@@ -0,0 +1,274 @@
+/*
+ * The Unix Channel
+ *
+ * by Michel Beaudouin-Lafon
+ *
+ * Copyright 1990-1993
+ * Laboratoire de Recherche en Informatique (LRI)
+ *
+ * Sockets
+ *
+ * $Id$
+ * $CurLog$
+ */
+
+#include "Socket.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+
+extern int errno;
+
+/*?class UchSocket
+The class \typ{UchSocket} derives from \typ{UchChannel}.
+It is a virtual base class: no objects of class \typ{UchSocket} are ever created.
+It implements a Unix socket, that is a file descriptor and two addresses:
+the address the socket is bound to, and the address it is connected to.
+An address needs to be bound to a socket only if another process wants to connect to this socket;
+a socket needs to be connected to an address only for streams or connected datagrams.
+Thus, none of the addresses is mandatory.
+
+Addresses are always referenced by pointers.
+Smart pointers to addresses (\typ{^{pUchAddress}}) can be used anywhere a pointer is used.
+?*/
+
+/*?
+Construct a closed socket.
+?*/
+UchSocket :: UchSocket ()
+: UchChannel (),
+ BAddr (0),
+ CAddr (0),
+ AddrFamily (AF_UNSPEC)
+{
+}
+
+/*?
+Construct a closed socket bound to address \var{bound} and connected to address \var{connected}.
+Each or both arguments may be 0.
+?*/
+UchSocket :: UchSocket (UchAddress* bound, UchAddress* connected)
+: UchChannel (),
+ BAddr (bound),
+ CAddr (connected),
+ AddrFamily (AF_UNSPEC)
+{
+}
+
+/*?nodoc?*/
+UchSocket :: UchSocket (const UchSocket& s)
+: UchChannel (s),
+ BAddr (s.BAddr),
+ CAddr (s.CAddr)
+{
+}
+
+/*?nodoc?*/
+UchSocket :: ~UchSocket ()
+{
+ // will unreference addresses and destroy them if necessary
+ BAddr = 0;
+ CAddr = 0;
+}
+
+/*?nodoc?*/
+UchChannel*
+UchSocket :: Copy () const
+{
+ return new UchSocket (*this);
+}
+
+/*?
+This virtual function returns the type of the socket:
+one of \var{SOCK_UNSPEC}, \var{SOCK_STREAM}, \var{SOCK_DGRAM},
+depending on the class.
+?*/
+int
+UchSocket :: SockType ()
+{
+ return SOCK_UNSPEC;
+}
+
+/*?nextdoc?*/
+void
+UchSocket :: BindTo (UchAddress* a)
+{
+ BAddr = a;
+}
+
+/*?
+Set the address a socket is to be bound to or connected to.
+?*/
+void
+UchSocket :: ConnectTo (UchAddress* a)
+{
+ CAddr = a;
+}
+
+/*?
+Open the socket (with the \fun{socket} system call) if it is not already open.
+The socket must have an address bound or connected to get the protocol family,
+or its family must have been defined with \fun{SetFamily}.
+Return FALSE if the family is undefined or if a system error occurred.
+?*/
+bool
+UchSocket :: Open ()
+{
+ errno = 0;
+ if (FilDes () >= 0)
+ return TRUE;
+ if (AddrFamily == AF_UNSPEC) {
+ if (BAddr)
+ AddrFamily = BAddr->Family ();
+ else if (CAddr)
+ AddrFamily = CAddr->Family ();
+ else
+ return FALSE;
+ }
+ int fd = socket (AddrFamily, SockType (), 0);
+ if (fd < 0)
+ return FALSE;
+ UchChannel::Open (fd);
+ return TRUE;
+}
+
+/*?nextdoc?*/
+int
+UchSocket :: Bind ()
+{
+ if (! BAddr || ! BAddr->IsValid ())
+ return -1;
+ if (! Open ())
+ return -1;
+ int ret = bind (FilDes (), BAddr->GetSockAddr (), BAddr->Length ());
+ if (ret < 0)
+ return ret;
+
+ GEN_ADDR addr;
+ int alen = sizeof (addr);
+ if (getsockname (FilDes (), &addr.sa, &alen) < 0)
+ return -1;
+ BAddr = UchAddress::Decode (&addr, alen);
+ return ret;
+}
+
+/*?nextdoc?*/
+int
+UchSocket :: Bind (UchAddress* addr)
+{
+ if (addr)
+ BAddr = addr;
+ return Bind ();
+}
+
+/*?nextdoc?*/
+int
+UchSocket :: Connect ()
+{
+ if (! CAddr || ! CAddr->IsValid ())
+ return -1;
+ if (! Open ())
+ return -1;
+ int ret = connect (FilDes (), CAddr->GetSockAddr (), CAddr->Length ());
+ if (ret < 0)
+ return ret;
+
+ GEN_ADDR addr;
+ int alen = sizeof (addr);
+ if (getpeername (FilDes (), &addr.sa, &alen) < 0)
+ return -1;
+ CAddr = UchAddress::Decode (&addr, alen);
+ return ret;
+}
+
+/*?
+These two functions implement the Unix system calls \fun{bind} and \fun{connect}.
+If \var{addr} is given, it is first associated to the socket.
+Then the socket is opened, and finally the system call is performed.
+The returned value is that of the system call, unless opening failed in which case
+-1 is returned.
+?*/
+int
+UchSocket :: Connect (UchAddress* addr)
+{
+ if (addr)
+ CAddr = addr;
+ return Connect ();
+}
+
+/*?
+Open the socket if it is not already open.
+Bind and connect it depending on the addresses that are defined.
+You should use this function instead of calling \fun{Open}, \fun{Bind} and
+\fun{Connect}, for it is simpler.
+This function returns FALSE if a system error occurred. In this case, the caller can
+call \fun{SysError} to report the error.
+?*/
+bool
+UchSocket :: Setup ()
+{
+ if (! Open ())
+ return FALSE;
+ if (BAddr)
+ if (BAddr->IsValid ())
+ if (Bind () < 0)
+ return FALSE;
+ if (CAddr)
+ if (CAddr->IsValid ())
+ if (Connect () < 0)
+ return FALSE;
+ return TRUE;
+}
+
+/*?nodoc?*/
+char*
+UchSocket :: StrRepr (char* buf)
+{
+ UchChannel :: StrRepr (buf);
+ strcat (buf, " / ");
+ if (BAddr)
+ BAddr -> StrRepr (buf + strlen (buf));
+ else
+ strcat (buf, "null");
+ strcat (buf, " / ");
+ if (CAddr)
+ CAddr -> StrRepr (buf + strlen (buf));
+ else
+ strcat (buf, "null");
+ return buf;
+}
+
+#ifdef DOC
+
+/*?nextdoc?*/
+int
+UchSocket :: Family ()
+{ }
+
+/*?
+These function get and set the family.
+The possible values currently are \var{AF_UNSPEC}, \var{AF_UNIX} and \var{AF_INET}.
+Other values may be defined if supported by the system.
+The family must be defined for \fun{Open} (and thus \fun{Setup}) to succeed.
+If an address is bound or connected to the socket, its family is used.
+Thus, an application seldom needs to call \fun{SetFamily}.
+?*/
+void
+UchSocket :: SetFamily (int f)
+{ }
+
+/*?nextdoc?*/
+UchAddress*
+UchSocket :: BoundTo ()
+{ }
+
+/*?
+Return the address currently bound or connected to the socket.
+?*/
+UchAddress*
+UchSocket :: ConnectedTo ()
+{ }
+
+#endif /* DOC */
+