From: Álvaro Neira Ayuso <[email protected]>

Added some function for adding socket unix support.

Signed-off-by: Alvaro Neira Ayuso <[email protected]>
---
 include/osmocom/core/socket.h |    6 +++
 src/socket.c                  |   92 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index f15a03a..cb1b7a8 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -30,6 +30,12 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
 
 int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen);
 
+int osmo_sock_unix_init(uint16_t type, uint8_t proto,
+                       const char *socket_path, unsigned int flags);
+
+int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
+                           const char *socket_path, unsigned int flags);
+
 /*! @} */
 
 #endif /* _OSMOCORE_SOCKET_H */
diff --git a/src/socket.c b/src/socket.c
index 6ff00f0..6d4eddf 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -17,6 +17,7 @@
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/un.h>
 
 #include <netinet/in.h>
 
@@ -257,6 +258,97 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned 
int addrlen)
        return 0;
 }
 
+/*! \brief Initialize a socket unix(including bind/connect)
+ *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ *  \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ *  \param[in] socket_path path to identify the socket
+ *  \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates a new socket unix, \a
+ * type and \a proto and optionally binds or connects it, depending on
+ * the value of \a flags parameter.
+ */
+int osmo_sock_unix_init(uint16_t type, uint8_t proto,
+                       const char *socket_path, unsigned int flags)
+{
+       struct sockaddr_un addr;
+       int sfd, rc, on = 1;
+
+       if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) ==
+                    (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT))
+               return -EINVAL;
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
+
+       if (type == SOCK_RAW) {
+               sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
+       } else {
+               sfd = socket(AF_UNIX, type, proto);
+       }
+
+       if (sfd < 0)
+               return -1;
+
+       if (flags & OSMO_SOCK_F_NONBLOCK) {
+               if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) {
+                       perror("cannot set this socket unblocking");
+                       close(sfd);
+                       return -EINVAL;
+               }
+       }
+       if (flags & OSMO_SOCK_F_CONNECT) {
+               rc = connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
+               if (rc < 0) {
+                       close(sfd);
+                       return -1;
+               }
+       } else {
+               rc = bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
+               if  (rc < 0) {
+                       close(sfd);
+                       return -1;
+               }
+       }
+
+       if (flags & OSMO_SOCK_F_BIND)
+               listen(sfd, 10);
+
+       return sfd;
+}
+
+/*! \brief Initialize a socket unix and fill \ref osmo_fd
+ *  \param[out] ofd file descriptor (will be filled in)
+ *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ *  \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ *  \param[in] socket_path path to identify the socket
+ *  \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates (and optionall binds/connects) a socket using
+ * \ref osmo_sock_unix_init, but also fills the \a ofd structure.
+ */
+int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
+                           const char *socket_path, unsigned int flags)
+{
+       int sfd, rc;
+
+       sfd = osmo_sock_unix_init(type, proto, socket_path, flags);
+       if (sfd < 0)
+               return sfd;
+
+       ofd->fd = sfd;
+       ofd->when = BSC_FD_READ;
+
+       rc = osmo_fd_register(ofd);
+       if (rc < 0) {
+               close(sfd);
+               return rc;
+       }
+
+       return sfd;
+}
+
 #endif /* HAVE_SYS_SOCKET_H */
 
 /*! @} */


Reply via email to