/* * symsocket.c: * * Copyright (c) 2008 James McKenzie , * All rights reserved. * */ static char rcsid[] = "$Id$"; /* * $Log$ * Revision 1.1 2008/02/13 18:05:06 james * *** empty log message *** * */ #include "project.h" #include #include #define BUF_SIZE 16384 #define MAX_TXN 4096 void socket_free(Socket *s) { if (!s) return; if (s->read_buf) slide_free(s->read_buf); if (s->write_buf) slide_free(s->write_buf); close(s->fd); } Socket * socket_listen (char *path) { int fd; struct sockaddr_un *sun; Socket *ret; int n; unlink (path); fd = socket (PF_UNIX, SOCK_STREAM, 0); if (fd < 0) return NULL; n = strlen (path) + sizeof (struct sockaddr_un); sun = (struct sockaddr_un *) malloc (n); memset (sun, 0, n); sun->sun_family = AF_UNIX; strcpy (sun->sun_path, path); if (bind (fd, (struct sockaddr *) sun, SUN_LEN (sun)) < 0) { free (sun); close (fd); return NULL; } free (sun); if (listen (fd, 5) < 0) { close (fd); return NULL; } set_nonblocking (fd); ret = (Socket *) malloc (sizeof (Socket)); memset (ret, 0, sizeof (Socket)); ret->read_buf = NULL; ret->write_buf = NULL; ret->fd = fd; return ret; } Socket * socket_accept (Socket * l) { Socket *ret; int len; int fd; struct sockaddr_un sun; len = sizeof (struct sockaddr_un); fd = accept (l->fd, (struct sockaddr *) &sun, &len); if (fd < 0) return NULL; ret = (Socket *) malloc (sizeof (Socket)); memset (ret, 0, sizeof (Socket)); set_nonblocking (fd); ret->fd = fd; ret->read_buf = slide_new (BUF_SIZE); ret->write_buf = slide_new (BUF_SIZE); ret->msg = 0; return ret; } /*Blocking for now*/ Socket * socket_connect (char *path) { int n; int fd; struct sockaddr_un *sun; Socket *ret; unlink (path); fd = socket (PF_UNIX, SOCK_STREAM, 0); if (fd < 0) return NULL; n = strlen (path) + sizeof (struct sockaddr_un); sun = (struct sockaddr_un *) malloc (n); memset (sun, 0, n); sun->sun_family = AF_UNIX; strcpy (sun->sun_path, path); if (connect (fd, (struct sockaddr *) sun, SUN_LEN (sun))) { free (sun); close (fd); return NULL; } free (sun); set_nonblocking (fd); ret = (Socket *) malloc (sizeof (Socket)); memset (ret, 0, sizeof (Socket)); ret->fd = fd; ret->read_buf = slide_new (BUF_SIZE); ret->write_buf = slide_new (BUF_SIZE); ret->msg = 0; return ret; } Socket * socket_post_select (Socket * s, fd_set * rfds, fd_set * wfds) { char buf[1024]; int n; if (SOCKET_IS_LISTENER (s)) { if (!FD_ISSET (s->fd, rfds)) return NULL; return socket_accept (s); } if ((!SLIDE_EMPTY (s->write_buf)) && FD_ISSET (s->fd, wfds)) { n = (SLIDE_BYTES (s->write_buf) > MAX_TXN) ? MAX_TXN : SLIDE_BYTES (s->write_buf); n = write (s->fd, SLIDE_RPTR (s->write_buf), n); if (n > 0) slide_consume (s->write_buf, n); } if (!SLIDE_FULL (s->read_buf) && FD_ISSET (s->fd, rfds)) { n = (SLIDE_SPACE (s->read_buf) > MAX_TXN) ? MAX_TXN : SLIDE_SPACE (s->read_buf); n = read (s->fd, SLIDE_RPTR (s->read_buf), n); if (n > 0) slide_added (s->read_buf, n); } if (SLIDE_BYTES (s->read_buf) >= sizeof (IPC_Msg)) { s->msg = ipc_check_for_message_in_slide(s->read_buf); } else { s->msg=NULL; } return NULL; } void socket_consume_msg(Socket *s) { int n; if (!s->msg) return; n=s->msg->size; slide_consume(s->read_buf,n); if (SLIDE_BYTES (s->read_buf) >= sizeof (IPC_Msg)) { s->msg = ipc_check_for_message_in_slide(s->read_buf); } else { s->msg=NULL; } } void socket_pre_select (Socket * s, fd_set * rfds, fd_set * wfds) { char buf[1024]; int n; /*Server socket */ if (SOCKET_IS_LISTENER (s)) { FD_SET (s->fd, rfds); return; } if (!SLIDE_EMPTY (s->write_buf)) FD_SET (s->fd, wfds); if (!SLIDE_FULL (s->read_buf)) FD_SET (s->fd, rfds); }