socket_un.c 3.31 KB
/*
 * some basic berkley socket stuff....far from beeing complete
 */
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <stdlib.h>
#include <errno.h>

#define USE_STRUCT_SCOT_SOCKET

#include <scot/exception.h>
#include <scot/memory.h>
#include <scot/socket.h>
#include <scot_common.h>
#include <scot/scot_types.h>

struct scot_socket * 
scot_socket_un_new (const char* path)
{
	struct scot_socket * sock = NULL;
	excenv_t *           ee;
	SOCKET               handle;

	TRY
	{
		handle = socket (PF_UNIX, SOCK_STREAM, 0);

		if (handle == -1)
			THROW (EXC (EXC_ERROR, errno, strerror (errno)));

		if (SCOT_STR_LENGTH (path) > UNIX_PATH_MAX)
			THROW (EXC (EXC_ERROR, 
						SCOT_UNX_PATH_TO_LONG, 
						scot_common_errmsg [SCOT_UNX_PATH_TO_LONG]));

		sock = SCOT_MEM_GET (sizeof (struct scot_socket));
		SCOT_MEM_ZERO (sock, sizeof (struct scot_socket));
		sock->sa = SCOT_MEM_GET (sizeof (struct sockaddr_un));
		SCOT_MEM_ZERO (sock->sa, sizeof (struct sockaddr_un));

		((struct sockaddr_un *) sock->sa)->sun_family = AF_UNIX;
		SCOT_STRN_COPY (
				((struct sockaddr_un *) sock->sa)->sun_path, 
				path, 
				UNIX_PATH_MAX);

		sock->socket.handle.sock = handle; 
		sock->socket.s_type = SCOT_STREAM_TYPE_SOCKET;
		sock->addr_len = 
			sizeof (((struct sockaddr_un *) sock->sa)->sun_family) +
			SCOT_STR_LENGTH (((struct sockaddr_un *) sock->sa)->sun_path);
	}
	CATCH (ee)
	{
		forward_all_exceptions (ee);

		if (sock != NULL)
		{
			if (sock->socket.handle.sock <= 0)
				SCOT_SOCK_CLOSE (sock->socket.handle.sock);

			if (sock->sa != NULL)
				SCOT_MEM_FREE (sock->sa);

			SCOT_MEM_FREE (sock);
		}

		THROW (EXC (EXC_ERROR, 
					SCOT_SOCKET_NEW_FAIL, 
					scot_socket_errmsg [SCOT_SOCKET_NEW_FAIL]));
	}

	return sock;
}

const
char *
scot_socket_un_get_path (const struct scot_socket* s)
{
	return ((struct sockaddr_un *) s->sa)->sun_path;
}

struct scot_socket *
scot_socket_un_accept (const struct scot_socket* s)
{
	struct scot_socket * sock = NULL;
	excenv_t *           ee;
	SOCKET               handle;
	struct sockaddr      sa;
	SIZE_T               addr_len;

	TRY
	{
		addr_len = s->addr_len;

		handle = accept (s->socket.handle.sock, &sa, &addr_len);
		if (handle == -1)
			THROW (EXC (EXC_ERROR, errno, strerror (errno)));

		sock = SCOT_MEM_GET (sizeof (struct scot_socket));
		SCOT_MEM_ZERO (sock, sizeof (struct scot_socket));
		sock->sa = SCOT_MEM_GET (sizeof (struct sockaddr_un));
		SCOT_MEM_ZERO (sock->sa, sizeof (struct sockaddr_un));

		sock->addr_len      = addr_len;
		sock->socket.handle.sock = handle;
		sock->socket.s_type = SCOT_STREAM_TYPE_SOCKET;
		SCOT_MEM_COPY (sock->sa, &sa, sizeof (struct sockaddr_un));
	}
	CATCH (ee)
	{
		forward_all_exceptions (ee);

		if (sock != NULL)
		{
			if (sock->socket.handle.sock <= 0)
				SCOT_SOCK_CLOSE (sock->socket.handle.sock);

			if (sock->sa != NULL)
				SCOT_MEM_FREE (sock->sa);

			SCOT_MEM_FREE (sock);
		}

		THROW (EXC (EXC_ERROR, 
					SCOT_SOCKET_ACCEPT_FAIL, 
					scot_socket_errmsg [SCOT_SOCKET_ACCEPT_FAIL]));
	}

	return sock;
}

void
scot_socket_un_prep_con (struct scot_socket * s, const char * adr)
{
	if (adr)
	{
		SCOT_STRN_COPY (
				((struct sockaddr_un *) s->sa)->sun_path, 
				adr, 
				UNIX_PATH_MAX);

		s->addr_len = 
			sizeof (((struct sockaddr_un *) s->sa)->sun_family) +
			SCOT_STR_LENGTH (((struct sockaddr_un *) s->sa)->sun_path);
	}
}