This is ipc.c in view mode; [Download] [Up]
/* ipc for TeX->TeXview communications. */ #define TEXVIEW #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <fcntl.h> #include <strings.h> extern int unlink(), fcntl(), close(), read() ; extern void checkmatch() ; #define IPC_PIPE_NAME "/.TeXview_Pipe" struct msg { short namelength ; /* length of auxilliary data */ int eof ; /* new eof for dvi file */ char more_data[0] ; /* where the rest of the stuff goes */ } ; /* common routines */ extern char *getenv(), *malloc() ; static char *ipc_name ; static struct sockaddr *ipc_addr ; static int ipc_addr_len ; static int ipc_make_name() { char *s ; if (ipc_addr_len == 0) { if ((s = getenv("HOME")) && (ipc_addr = (struct sockaddr *)malloc(strlen(s) + 40))) { ipc_addr->sa_family = 0 ; ipc_name = ipc_addr->sa_data ; strcpy(ipc_name, s) ; strcat(ipc_name, IPC_PIPE_NAME) ; ipc_addr_len = strlen(ipc_name) + 3 ; } } return ipc_addr_len ; } static int sock = -1 ; int ipc_is_open() { return sock >= 0 ; } #ifdef TEXVIEW extern void add_fd(), delete_fd() ; /* routines for input (for TeXview) */ #include "errno.h" extern int dviOpenFile() ; extern void openfilename() ; extern int fakeeof ; static int ns = -1 ; void ipc_open_in() { #ifdef IPCDEBUG printf("Starting up ipc.\n") ; #endif if (ipc_make_name()) { unlink(ipc_name) ; if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) >= 0) { if ((bind(sock, ipc_addr, ipc_addr_len) >= 0) && (listen(sock, 1) >= 0) && (fcntl(sock, F_SETFL, FNDELAY) != -1)) { add_fd(sock) ; #ifdef IPCDEBUG printf("IPC successfully started.\n") ; #endif } else { close(sock) ; sock = -1 ; } } } } void ipc_shutdown() { #ifdef IPCDEBUG printf("Shutting down ipc\n") ; #endif if (ipc_is_open()) { if (ns >= 0) { delete_fd(ns) ; close(ns) ; ns = -1 ; } else delete_fd(sock) ; close(sock) ; sock = -1 ; } } static void ipc_tryagain() { ipc_shutdown() ; ipc_open_in() ; } int fromipc ; void ipc_msg_handler() { struct msg msg ; int stuff_to_do = 0 ; int dmyint ; char dummy[1024] ; char other_dummy[1024] ; #ifdef IPCDEBUG printf("Entered message handler.\n") ; #endif dummy[0] = 0 ; if (! ipc_is_open()) return ; while (1) { #ifdef IPCDEBUG printf("Top of the loop; sock=%d ns=%d\n", sock, ns) ; #endif if (ns >= 0) { while ((dmyint = read(ns, &msg, sizeof(struct msg))) == sizeof(struct msg)) { #ifdef IPCDEBUG printf("Read a message; length=%d\n", msg.namelength) ; #endif if (msg.namelength > 0) { if ((dmyint = read(ns, &dummy, msg.namelength)) != msg.namelength) break ; dummy[msg.namelength] = 0 ; /* end the string */ #ifdef IPCDEBUG printf("Successfully read a name: <%s>\n", dummy) ; #endif } stuff_to_do = 1 ; } if (dmyint == 0) { /* read eof */ #ifdef IPCDEBUG printf("Read EOF on input stream.\n") ; #endif close(ns) ; delete_fd(ns) ; ns = -1 ; add_fd(sock) ; /* we need to return here, to get around a bug in DPS. */ break ; } else if (dmyint > 0 || errno != EWOULDBLOCK) { #ifdef IPCDEBUG printf("Error? dmyint=%d errno=%d\n", dmyint, errno) ; #endif ipc_tryagain() ; return ; } else { #ifdef IPCDEBUG printf("Assuming wouldblock: dmyint=%d errno=%d\n", dmyint, errno) ; #endif break ; } } else { dmyint = sizeof(other_dummy) ; #ifdef IPCDEBUG printf("Trying to accept a connection.\n") ; #endif if ((ns = accept(sock, (struct sockaddr *)other_dummy, &dmyint)) > 0) { #ifdef IPCDEBUG printf("Got a connection!\n") ; #endif delete_fd(sock) ; if (fcntl(ns, F_SETFL, FNDELAY) == -1) { ipc_tryagain() ; return ; } else { #ifdef IPCDEBUG printf("Got a new socket under fcntl\n") ; #endif add_fd(ns) ; } /* we need to return here, to get around a bug in DPS. */ break ; } else if (errno == EWOULDBLOCK) { #ifdef IPCDEBUG printf("Got a would block on accept; continuing\n") ; #endif ns = -1 ; break ; } else { ipc_tryagain() ; return ; } } } if (stuff_to_do) { fakeeof = msg.eof ; if (dummy[0] != 0) { /* got a file name! close the current. */ fromipc = 1 ; openfilename(dummy) ; fromipc = 0 ; } fakeeof = msg.eof ; checkmatch() ; #ifdef IPCDEBUG printf("name=<%s> fakeeof=%d\n", dummy, fakeeof) ; #endif } #ifdef IPCDEBUG printf("Returning from message handler.\n") ; #endif } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.