diff --git a/Common/Context.h b/Common/Context.h index 9a39c2b09d94611428d5f5f0d47bfc4e5c4da5d8..56497de530aa74cfef385bfe687b7d5f97d82cec 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -206,6 +206,7 @@ public : // solver options struct{ int max_delay, plugins ; + char *socket_name ; }solver; // print options diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 2dbc76443f2c08a5b36ca6608b01fc290727e895..8cc6cb3e02fc18fcc0207f821d4755a42a6ee7f3 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -99,6 +99,9 @@ StringXString MeshOptions_String[] = { } ; StringXString SolverOptions_String[] = { + { F|O, "SocketName" , opt_solver_socket_name , ".gmshsock" , + "Name of socket (TCP/IP if it contains the `:' character, UNIX otherwise)" }, + { F|O, "Name0" , opt_solver_name0 , "GetDP" , "Name of solver 0" }, { F|O, "Help0" , opt_solver_help0 , diff --git a/Common/Options.cpp b/Common/Options.cpp index 82b8317d1f80165fd4fef3daf2601575982db60d..2adab0081f3616dbdd31e37b7d07c931f50101ae 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.207 2004-11-25 02:10:30 geuzaine Exp $ +// $Id: Options.cpp,v 1.208 2004-12-06 06:54:32 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -926,6 +926,17 @@ char *opt_mesh_triangle_options(OPT_ARGS_STR){ return CTX.mesh.triangle_options; } +char *opt_solver_socket_name(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX.solver.socket_name = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->solver_input[0]->value(CTX.solver.socket_name); +#endif + return CTX.solver.socket_name; +} + char *opt_solver_name(OPT_ARGS_STR) { #if defined(HAVE_FLTK) diff --git a/Common/Options.h b/Common/Options.h index be42c9ae9ee5777a58e5c586e1e15a0564ba73c6..743cdfb2663f3e2731bba5ceb940156ced1accab 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -47,6 +47,7 @@ char * opt_general_web_browser(OPT_ARGS_STR); char * opt_general_scheme(OPT_ARGS_STR); char * opt_general_graphics_font(OPT_ARGS_STR); char * opt_mesh_triangle_options(OPT_ARGS_STR); +char * opt_solver_socket_name(OPT_ARGS_STR); char * opt_solver_name(OPT_ARGS_STR); char * opt_solver_name0(OPT_ARGS_STR); char * opt_solver_name1(OPT_ARGS_STR); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 99d29b07bef55ca3bf3724d647dfb9b0cfbf1115..b8f8322ec91d6b4d45c5b3656b5f76a63d8ae5e7 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.300 2004-11-25 02:10:31 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.301 2004-12-06 06:54:32 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -1087,6 +1087,8 @@ void solver_options_cb(CALLBACK_ARGS) void solver_options_ok_cb(CALLBACK_ARGS) { opt_solver_max_delay(0, GMSH_SET, WID->solver_value[0]->value()); + + opt_solver_socket_name(0, GMSH_SET, (char *)WID->solver_input[0]->value()); } // Post options diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index f83a434ec997f89f026d104287111e61dc862f12..5f300b427220f628eb0418797b052f72d857cb16 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.385 2004-11-25 02:10:31 geuzaine Exp $ +// $Id: GUI.cpp,v 1.386 2004-12-06 06:54:32 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -2285,6 +2285,9 @@ void GUI::create_option_window() solver_value[0]->maximum(10); solver_value[0]->step(1); solver_value[0]->align(FL_ALIGN_RIGHT); + + solver_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Socket name"); + solver_input[0]->align(FL_ALIGN_RIGHT); o->end(); } diff --git a/Fltk/GUI.h b/Fltk/GUI.h index 954c1e4c426bed0b55668c3574394eef5dd5f842..29b6c2f35f5fd4df184261e1555d96fa61ee7d3f 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -187,6 +187,7 @@ public: Fl_Group *solver_group ; Fl_Check_Button *solver_butt[20] ; Fl_Value_Input *solver_value[20] ; + Fl_Input *solver_input[20] ; // post-processing options Fl_Group *post_group ; diff --git a/Fltk/GmshServer.cpp b/Fltk/GmshServer.cpp index 66b36c45cd63b8b93ba76f393a400a33cd978b3b..d7b21ad8be39e0d544139a15ce588a8aa8abbb40 100644 --- a/Fltk/GmshServer.cpp +++ b/Fltk/GmshServer.cpp @@ -1,4 +1,4 @@ -/* $Id: GmshServer.cpp,v 1.18 2004-10-16 22:15:17 geuzaine Exp $ */ +/* $Id: GmshServer.cpp,v 1.19 2004-12-06 06:54:32 geuzaine Exp $ */ /* * Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle * @@ -45,6 +45,7 @@ void SystemCall(char *str); #include <sys/un.h> #include <sys/time.h> #include <unistd.h> +#include <netinet/in.h> /* private functions */ @@ -83,16 +84,20 @@ static int Socket_UnlinkName(char *name) int Gmsh_StartClient(char *command, char *sockname) { - int s, sock; + static int init = 0; + static int s; + int sock; #if defined(linux) || defined(_AIX) || defined(__FreeBSD__) socklen_t len; #else int len; #endif - struct sockaddr_un addr, from; + struct sockaddr_un addr_un, from_un; + struct sockaddr_in addr_in, from_in; fd_set rfds; struct timeval tv; - int retval; + int retval, portno; + char *port; /* no socket? launch the command! */ if(!sockname) { @@ -101,23 +106,52 @@ int Gmsh_StartClient(char *command, char *sockname) return 1; } - /* first delete the socket's name if it exists */ - Socket_UnlinkName(sockname); + if((port = strstr(sockname, ":"))){ /* INET socket */ + portno = atoi(port+1); + } + else{ + portno = -1; + } + + if(portno < 0){ /* UNIX socket */ + /* delete the file if it already exists */ + Socket_UnlinkName(sockname); - /* make the socket */ - s = socket(PF_UNIX, SOCK_STREAM, 0); - if(s < 0) - return -1; /* Error: Couldn't create socket */ + /* 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 */ + /* bind the socket to its name */ + strcpy(addr_un.sun_path, sockname); + addr_un.sun_family = AF_UNIX; + if(bind(s, (struct sockaddr *)&addr_un, + strlen(addr_un.sun_path) + sizeof(addr_un.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); + /* change permissions on the socket name in case it has to be rm'd later */ + chmod(sockname, 0666); + } + else{ /* INET socket */ + if(init != portno){ /* FIXME: need a better solution to deal with + addresses that have already been bound! */ + init = portno; + + /* make the socket */ + s = socket(AF_INET, SOCK_STREAM, 0); + if(s < 0) + return -1; /* Error: Couldn't create socket */ + + /* bind the socket to its name */ + bzero((char *) &addr_in, sizeof(addr_in)); + addr_in.sin_family = AF_INET; + addr_in.sin_addr.s_addr = INADDR_ANY; + addr_in.sin_port = htons(portno); + + if(bind(s, (struct sockaddr *)&addr_in, sizeof(addr_in)) < 0) + return -2; /* Error: Couldn't bind socket to name */ + } + } /* Start the external function via system() call */ //system(command); @@ -127,8 +161,7 @@ int Gmsh_StartClient(char *command, char *sockname) if(listen(s, 20)) return -3; /* Error: Socket listen failed */ - /* Watch s to see when it has input. */ - /* Wait up to 4 seconds */ + /* Watch s to see when it has input; wait up to N seconds */ //tv.tv_sec = 4; tv.tv_sec = CTX.solver.max_delay; tv.tv_usec = 0; @@ -139,11 +172,16 @@ int Gmsh_StartClient(char *command, char *sockname) 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 */ + if(portno < 0){ + len = sizeof(from_un); + if((sock = accept(s, (struct sockaddr *)&from_un, &len)) < 0) + return -5; /* Error: Socket accept failed */ + } + else{ + len = sizeof(from_in); + if((sock = accept(s, (struct sockaddr *)&from_in, &len)) < 0) + return -5; /* Error: Socket accept failed */ + } return sock; } @@ -164,8 +202,10 @@ int Gmsh_ReceiveString(int socket, int *type, char str[]) int Gmsh_StopClient(char *sockname, int sock) { - if(Socket_UnlinkName(sockname) == -1) - return -1; /* Impossible to unlink the socket */ + if(!strstr(sockname, ":")) + if(Socket_UnlinkName(sockname) == -1) + return -1; /* Impossible to unlink the socket */ + close(sock); return 0; } diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp index 1c160fbc050ed39b8071a7ed002b8ae00e60b6de..17a9f1374dbc1bbb46c1a1f6cc23e5d1d0250665 100644 --- a/Fltk/Solvers.cpp +++ b/Fltk/Solvers.cpp @@ -1,4 +1,4 @@ -// $Id: Solvers.cpp,v 1.29 2004-10-25 18:48:37 geuzaine Exp $ +// $Id: Solvers.cpp,v 1.30 2004-12-06 06:54:32 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -59,9 +59,14 @@ int Solver(int num, char *args) return 1; } - sprintf(str, "%s.gmshsock-%d", CTX.home_dir, num); - FixWindowsPath(str, socket_name); - + if(!strstr(CTX.solver.socket_name, ":")){ + // file socket + sprintf(str, "%s%s-%d", CTX.home_dir, CTX.solver.socket_name, num); + FixWindowsPath(str, socket_name); + } + else + strcpy(socket_name, CTX.solver.socket_name); + sprintf(str, "\"%s\"", socket_name); sprintf(buffer, SINFO[num].socket_command, str); diff --git a/utils/solvers/GmshClient.c b/utils/solvers/GmshClient.c index 6f32c893a00519caa69096bc76edcc533b530487..57092b086bb0738886c0a7417c96369162fb5362 100644 --- a/utils/solvers/GmshClient.c +++ b/utils/solvers/GmshClient.c @@ -1,4 +1,4 @@ -/* $Id: GmshClient.c,v 1.5 2004-05-22 01:24:19 geuzaine Exp $ */ +/* $Id: GmshClient.c,v 1.6 2004-12-06 06:54:32 geuzaine Exp $ */ /* * Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle * @@ -39,6 +39,8 @@ #include <sys/un.h> #include <sys/time.h> #include <unistd.h> +#include <netinet/in.h> +#include <netdb.h> /* private functions */ @@ -76,27 +78,63 @@ static void Socket_Idle(double delay) int Gmsh_Connect(char *sockname) { - struct sockaddr_un addr; + struct sockaddr_un addr_un; + struct sockaddr_in addr_in; int len, sock; int tries; + struct hostent *server; + int portno, remotelen; + char remote[256], *port; /* slight delay to be sure that the socket is bound by the server before we attempt to connect to it... */ Socket_Idle(0.1); + if((port = strstr(sockname, ":"))){ + /* we have an INET socket */ + portno = atoi(port+1); + remotelen = strlen(sockname) - strlen(port); + if(remotelen > 0) + strncpy(remote, sockname, remotelen); + remote[remotelen] = '\0'; + } + else{ + portno = -1; + } + /* create socket */ - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if(sock < 0) - return -1; /* Error: Couldn't create socket */ - /* try to connect socket to given name */ - strcpy(addr.sun_path, sockname); - addr.sun_family = AF_UNIX; - len = strlen(addr.sun_path) + sizeof(addr.sun_family); - for(tries = 0; tries < 5; tries++) { - if(connect(sock, (struct sockaddr *)&addr, len) >= 0) - return sock; - Socket_Idle(0.1); + if(portno < 0){ /* UNIX socket */ + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if(sock < 0) + return -1; /* Error: Couldn't create socket */ + /* try to connect socket to given name */ + strcpy(addr_un.sun_path, sockname); + addr_un.sun_family = AF_UNIX; + len = strlen(addr_un.sun_path) + sizeof(addr_un.sun_family); + for(tries = 0; tries < 5; tries++) { + if(connect(sock, (struct sockaddr *)&addr_un, len) >= 0) + return sock; + Socket_Idle(0.1); + } + } + else{ /* TCP/IP socket */ + /* try to connect socket to given name */ + sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) + return -1; /* Error: Couldn't create socket */ + if(!(server = gethostbyname(remote))) + return -3; /* Error: No such host */ + bzero((char *) &addr_in, sizeof(addr_in)); + addr_in.sin_family = AF_INET; + bcopy((char *)server->h_addr, (char *)&addr_in.sin_addr.s_addr, server->h_length); + addr_in.sin_port = htons(portno); + addr_in.sin_addr.s_addr = INADDR_ANY; + for(tries = 0; tries < 5; tries++) { + if(connect(sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) >= 0) + return sock; + Socket_Idle(0.1); + } } return -2; /* Error: Couldn't connect */