Skip to content
Snippets Groups Projects
Forked from gmsh / gmsh
Loading
GmshServer.cpp 2.83 KiB
/* $Id: GmshServer.cpp,v 1.4 2002-04-13 05:44:37 geuzaine Exp $ */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _AIX
#include <strings.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/time.h>
#include <unistd.h>

/* private functions */

static int Socket_ReceiveData(int socket, void *buffer, int bytes){
  int sofar, remaining, len;
  char *buf;

  buf = (char*)buffer;
  sofar = 0;
  remaining = bytes;
  do {
    len = read(socket, buf + sofar, remaining);
    if (len<=0) return 0;
    sofar += len;
    remaining -= len;
  } while (remaining>0);
  return bytes;
}

static int Socket_UnlinkName(char *name){
#ifdef _AIX
   char name2[1000];
   strcpy(name2,name);
   name2[strlen(name2)-1] = '\0';
   return unlink(name2);
#else
   return unlink(name);
#endif
}


/* public interface */

int Gmsh_StartClient(char *command, char *sockname){
  int s, sock;
#if defined(linux) || defined(_AIX)
  socklen_t len ;
#else
  int len;
#endif
  struct sockaddr_un addr, from;
  fd_set rfds;
  struct timeval tv;
  int retval;

  /* no socket? launch the command! */
  if(!sockname){
    system(command);
    return 1;
  }

  /* first delete the socket's name if it exists */
  Socket_UnlinkName(sockname);
  
  /* make the socket */
  s = socket(PF_UNIX, SOCK_STREAM, 0);
  if (s<0) return -1; /* Error: Couldn't create socket */
  
  /* bind the socket to its name */
  strcpy(addr.sun_path, sockname);
  addr.sun_family = AF_UNIX;
  if(bind(s, (struct sockaddr *)&addr, 
	  strlen(addr.sun_path)+sizeof(addr.sun_family)) < 0)
    return -2; /* Error: Couldn't bind socket to name */
  
  /* change permissions on the socket name in case it has to be rm'd later */
  chmod(sockname, 0666);
  
  /* Start the external function via system() call */
  system(command);
  
  /* wait for external function to connect */
  if(listen(s, 20)) return -3; /* Error: Socket listen failed */
  
  /* Watch s to see when it has input. */
  /* Wait up to 2 seconds */
  tv.tv_sec = 2;
  tv.tv_usec = 0;
  FD_ZERO(&rfds);
  FD_SET(s, &rfds);
  retval = select(s+1, &rfds, NULL, NULL, &tv);
  
  if(!retval) return -4; /* Error: Socket listening timeout */
  
  len = sizeof(from);
  if ((sock = accept(s, (struct sockaddr *)&from, &len)) < 0)
    return -5; /* Error: Socket accept failed */
  
  close(s); /* don't need this socket anymore */
  
  return sock;
}

int Gmsh_ReceiveString(int socket, int *type, char str[]){
   int len;

   Socket_ReceiveData(socket, type, sizeof(int));
   if (Socket_ReceiveData(socket, &len, sizeof(int))) {
     if (Socket_ReceiveData(socket, str, len)==len) {
       str[len] = '\0';
       return 1;
     }
   }
   return 0;
}

int Gmsh_StopClient(char *sockname, int sock){
  if(Socket_UnlinkName(sockname)==-1)
    return -1; /* Impossible to unlink the socket */
  close(sock);
  return 0;
}