From 2fb642685fe2ea16d9e6cc6114416ac656728554 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Tue, 6 Mar 2001 20:33:26 +0000 Subject: [PATCH] add ipc :) SVN revision: 4336 --- legacy/ecore/AUTHORS | 1 + legacy/ecore/src/Ecore.h | 13 ++++ legacy/ecore/src/Makefile.am | 1 + legacy/ecore/src/e_events.c | 61 +++++++++++---- legacy/ecore/src/e_ipc.c | 144 +++++++++++++++++++++++++++++++++++ 5 files changed, 204 insertions(+), 16 deletions(-) create mode 100644 legacy/ecore/src/e_ipc.c diff --git a/legacy/ecore/AUTHORS b/legacy/ecore/AUTHORS index d3fe787a6d..f3ef950513 100644 --- a/legacy/ecore/AUTHORS +++ b/legacy/ecore/AUTHORS @@ -1,2 +1,3 @@ The Rasterman Tom Gilbert +Burra diff --git a/legacy/ecore/src/Ecore.h b/legacy/ecore/src/Ecore.h index 07381d7dfe..457a552ae3 100644 --- a/legacy/ecore/src/Ecore.h +++ b/legacy/ecore/src/Ecore.h @@ -272,6 +272,11 @@ char *e_window_get_title(Window win); void e_keyboard_grab(Window win); void e_keyboard_ungrab(void); +void e_ev_ipc_init(char *path); +void e_ev_ipc_cleanup(void); +void e_add_ipc_service(int service, char *(*func) (char *argv)); +void e_del_ipc_service(int service); + char *e_selection_get_data(Window win, Atom prop); Window e_selection_request(void); @@ -322,6 +327,7 @@ typedef struct _ev_dnd_drop_status Ev_Dnd_Drop_Status; typedef struct _ev_dnd_data_request Ev_Dnd_Data_Request; typedef struct _ev_paste_request Ev_Paste_Request; typedef struct _ev_clear_selection Ev_Clear_Selection; +typedef struct _ev_ipc_service Ev_Ipc_Service; enum _eev_stack_detail { @@ -694,6 +700,13 @@ struct _ev_user int hup; }; +struct _ev_ipc_service +{ + int service; + char *(*func) (char *argv); + Ev_Ipc_Service *next; +}; + void e_add_event(Eevent_Type type, void *event, void (*ev_free) (void *event)); void e_del_event(void *event); diff --git a/legacy/ecore/src/Makefile.am b/legacy/ecore/src/Makefile.am index 284a0e2493..c35ccdabb9 100644 --- a/legacy/ecore/src/Makefile.am +++ b/legacy/ecore/src/Makefile.am @@ -11,6 +11,7 @@ libecore_la_SOURCES = \ e_ev_signal.c \ e_ev_x.c \ e_events.c \ + e_ipc.c \ e_util.c \ e_x.c diff --git a/legacy/ecore/src/e_events.c b/legacy/ecore/src/e_events.c index 2deb2e003d..dd3339fb01 100644 --- a/legacy/ecore/src/e_events.c +++ b/legacy/ecore/src/e_events.c @@ -163,10 +163,11 @@ e_del_event_ipc(int ipc) void e_event_loop(void) { - int count, fdsize, timed_out, were_events; + int fdcount, fdsize, ipccount, ipcsize; + int timed_out, were_events; double time1, time2, prev_time = 0.0; struct timeval tval; - fd_set fdset; + fd_set fdset, ipcset; Ev_Fd_Handler *fd_h; Ev_Pid_Handler *pid_h; Ev_Ipc_Handler *ipc_h; @@ -191,7 +192,17 @@ e_event_loop(void) if (fd_h->fd > fdsize) fdsize = fd_h->fd; } - count = 1; + fdcount = 1; + ipcsize = 0; + FD_ZERO(&ipcset); + /* for ever fd handler add the fd to the array and incriment fdsize */ + for (ipc_h = ipc_handlers; ipc_h; ipc_h = ipc_h->next) + { + FD_SET(ipc_h->ipc, &ipcset); + if (ipc_h->ipc > ipcsize) + ipcsize = ipc_h->ipc; + } + ipccount = 1; /* if there are timers setup adjust timeout value and select */ if (timers) { @@ -214,23 +225,27 @@ e_event_loop(void) if (tval.tv_usec <= 1000) tval.tv_usec = 1000; e_handle_zero_event_timer(); - if ((!e_events_pending()) && + if ((!e_events_pending()) && (!e_ev_signal_events_pending())) - count = select(fdsize + 1, &fdset, NULL, NULL, &tval); + fdcount = select(fdsize + 1, &fdset, NULL, NULL, &tval); } /* no timers - just sit and block */ else { - if ((!e_events_pending()) && - (!e_ev_signal_events_pending())) - count = select(fdsize + 1, &fdset, NULL, NULL, NULL); + if ((!e_events_pending()) && + (!e_ev_signal_events_pending())) + fdcount = select(fdsize + 1, &fdset, NULL, NULL, NULL); } for (pid_h = pid_handlers; pid_h; pid_h = pid_h->next) pid_h->func(pid_h->pid); - for (ipc_h = ipc_handlers; ipc_h; ipc_h = ipc_h->next) - ipc_h->func(ipc_h->ipc); + + /* see if we have any new ipc connections */ + tval.tv_sec = 0; + tval.tv_usec = 0; + ipccount =+ select(ipcsize + 1, &ipcset, NULL, NULL, &tval); + /* return < 0 - error or signal interrupt */ - if (count < 0) + if (fdcount < 0) { /* error */ if ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF)) @@ -240,20 +255,20 @@ e_event_loop(void) } } /* timers are available and its a timeout */ - if ((timers) && (count == 0)) + if ((timers) && (fdcount == 0)) { e_handle_event_timer(); timed_out = 1; } - if (count < 0) - count = 0; + if (fdcount < 0) + fdcount = 0; if (e_events_pending()) { - count++; + fdcount++; FD_SET(e_x_get_fd(), &fdset); } /* fd's are active */ - if (count > 0) + if (fdcount > 0) { /* for every fd handler - if its fd is set - call the func */ for (fd_h = fd_handlers; fd_h;) @@ -265,6 +280,20 @@ e_event_loop(void) if (FD_ISSET(fdh->fd, &fdset)) fdh->func(fdh->fd); } + } + + /* ipc clients are active */ + if (ipccount > 0) + { + for (ipc_h = ipc_handlers; ipc_h;) + { + Ev_Ipc_Handler *ipch; + + ipch = ipc_h; + ipc_h = ipc_h->next; + if (FD_ISSET(ipch->ipc, &ipcset)) + ipch->func(ipch->ipc); + } } if (events) e_event_filter(events); diff --git a/legacy/ecore/src/e_ipc.c b/legacy/ecore/src/e_ipc.c new file mode 100644 index 0000000000..8e67c5bb05 --- /dev/null +++ b/legacy/ecore/src/e_ipc.c @@ -0,0 +1,144 @@ +#include "Ecore.h" +#include +#include +#include +#include +#include + +void e_ipc_init(char *path); +void e_ipc_cleanup(void); +static void e_ipc_connect_handler(int fd); +static void e_ipc_client_handler(int fd); +void e_add_ipc_service(int service, char *(*func) (char *argv)); +void e_del_ipc_service(int service); + +Ev_Ipc_Service *ipc_services = NULL; + +void +e_ev_ipc_init(char *path) +{ + int fd, len; + struct sockaddr_un saun; + + if(path == NULL) + return; + + /* a UNIX domain, stream socket */ + if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + printf("Cannot create ipc socket... disabling ipc.\n"); + return; + } + + /* create the address we will be binding to */ + saun.sun_family = AF_UNIX; + strcpy(saun.sun_path, path); + + /* unlink the address so the bind won't fail */ + unlink(path); + len = sizeof(saun.sun_family) + strlen(saun.sun_path); + + if(bind(fd, &saun, len) < 0) { + printf("Cannot bind ipc socket... disabling ipc.\n"); + return; + } + + /* listen on the socket */ + if (listen(fd, 5) < 0) { + printf("Cannot listen on ipc socket... disabling ipc.\n"); + return; + } + + /* add ipc listener */ + e_add_event_ipc(fd, e_ipc_connect_handler); +} + +void +e_ev_ipc_cleanup(void) +{ + Ev_Ipc_Service *ipc_s; + + /* cleanup services list */ + for (ipc_s = ipc_services; ipc_s; ipc_s = ipc_s->next) + { + e_del_ipc_service(ipc_s->service); + } +} + +static void +e_ipc_connect_handler(int fd) +{ + struct sockaddr_un fsaun; + int fromlen, nfd; + + /* accept ipc connection */ + fromlen = sizeof(fsaun); + + if ((nfd = accept(fd, &fsaun, &fromlen)) < 0) { + printf("Cannot accept ipc connection... ignoring connection attempt.\n"); + return; + } + + /* set nonblocking */ + if (fcntl(nfd, F_SETFL, O_NONBLOCK) < 0) { + printf("Cannot fcntl ipc connection... ignoring connection attempt.\n"); + return; + } + + /* add ipc client */ + e_add_event_ipc(nfd, e_ipc_client_handler); +} + +static void +e_ipc_client_handler(int fd) +{ + int nread, service; + char ptr[4096]; + Ev_Ipc_Service *ipc_s; + + /* in no way done here yet, lots to do */ + if ((nread = read(fd, ptr, sizeof(ptr))) == 0) + { + close(fd); + e_del_event_ipc(fd); + } + else if (nread > 0) + { + printf("IPC Client sent %d bytes\n", nread); fflush(stdout); + service = atoi(&ptr[0]); + + for (ipc_s = ipc_services; ipc_s; ipc_s = ipc_s->next) + { + if (ipc_s->service == service) + { + ipc_s->func("TESTING"); + break; + } + } + } + else + { + printf("error\n"); fflush(stdout); + } +} + +void +e_add_ipc_service(int service, char *(*func) (char *argv)) +{ + Ev_Ipc_Service *ipc_s; + + /* delete the old service */ + e_del_ipc_service(service); + /* new service struct */ + ipc_s = NEW(Ev_Ipc_Service, 1); + ipc_s->next = ipc_services; + ipc_s->service = service; + ipc_s->func = func; + ipc_services = ipc_s; +} + +void e_del_ipc_service(int service) +{ + START_LIST_DEL(Ev_Ipc_Service, ipc_services, (_p->service == service)); + FREE(_p); + END_LIST_DEL; +}