Forked from
gmsh / gmsh
-
Christophe Geuzaine authoredChristophe Geuzaine authored
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;
}