ftp.nice.ch/pub/next/text/tex/apps/texview.3.a9.s.tar.gz#/texview/ipc.c

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() ;

#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 getcurstat() ;
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() ;
}

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) {
      if (dummy[0] != 0) { /* got a file name!  close the current. */
         dviOpenFile(dummy) ;
      }
      getcurstat() ;
      fakeeof = msg.eof ;
#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.