diff options
| author | Álvaro Neira Ayuso <anayuso@sysmocom.de> | 2014-03-24 13:02:00 +0100 | 
|---|---|---|
| committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-03-26 19:50:46 +0100 | 
| commit | 5ade61a4f49bbc5bdff271b3eaff0fc4ffd2fb60 (patch) | |
| tree | 5315e16dffbc9adde0d9a65a6f5a8647c2c0afbd /src | |
| parent | cc0645b26df92b007e7f4f397607ee235c58172e (diff) | |
src/socket: Adding unix domain socket support
Added some function for adding the unix domain socket support.
Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
Diffstat (limited to 'src')
| -rw-r--r-- | src/socket.c | 102 | 
1 files changed, 102 insertions, 0 deletions
| diff --git a/src/socket.c b/src/socket.c index 6ff00f0d..c93224af 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,107 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen)  	return 0;  } +/*! \brief Initialize a unix domain socket (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 unix domain socket, \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 local; +	int sfd, rc, on = 1; +	unsigned int namelen; + +	if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == +		     (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) +		return -EINVAL; + +	local.sun_family = AF_UNIX; +	strncpy(local.sun_path, socket_path, sizeof(local.sun_path)); +	local.sun_path[sizeof(local.sun_path) - 1] = '\0'; + +#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) +	local.sun_len = strlen(local.sun_path); +#endif +#if defined(BSD44SOCKETS) || defined(SUN_LEN) +	namelen = SUN_LEN(&local); +#else +	namelen = strlen(local.sun_path) + +		  offsetof(struct sockaddr_un, sun_path); +#endif + +	sfd = socket(AF_UNIX, type, proto); +	if (sfd < 0) +		return -1; + +	if (flags & OSMO_SOCK_F_CONNECT) { +		rc = connect(sfd, (struct sockaddr *)&local, namelen); +		if (rc < 0) +			goto err; +	} else { +		unlink(local.sun_path); +		rc = bind(sfd, (struct sockaddr *)&local, namelen); +		if  (rc < 0) +			goto err; +	} + +	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_BIND) { +		rc = listen(sfd, 10); +		if (rc < 0) +			goto err; +	} + +	return sfd; +err: +	close(sfd); +	return -1; +} + +/*! \brief Initialize a unix domain socket 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 */  /*! @} */ | 
