diff --git a/Common/GmshSocket.h b/Common/GmshSocket.h index 22d41a1a4d6dfff9f69543a571d13fd92697466b..7743db7b0341c35c69fbb0b5234a66011811748c 100644 --- a/Common/GmshSocket.h +++ b/Common/GmshSocket.h @@ -1,7 +1,28 @@ // Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle // -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, and/or sell copies of the +// Software, and to permit persons to whom the Software is furnished +// to do so, provided that the above copyright notice(s) and this +// permission notice appear in all copies of the Software and that +// both the above copyright notice(s) and this permission notice +// appear in supporting documentation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR +// ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY +// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +// OF THIS SOFTWARE. +// +// Please report all bugs and problems to <gmsh@geuz.org>. #ifndef _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_ diff --git a/utils/solvers/c++/GmshSocket.h b/utils/solvers/c++/GmshSocket.h index 13481760ee58b5c294fc7715650cbdd7bf9af405..6f8951da02cf830f9fa8b833fd4a26047b6c4918 100644 --- a/utils/solvers/c++/GmshSocket.h +++ b/utils/solvers/c++/GmshSocket.h @@ -1,7 +1,28 @@ // Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle // -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, and/or sell copies of the +// Software, and to permit persons to whom the Software is furnished +// to do so, provided that the above copyright notice(s) and this +// permission notice appear in all copies of the Software and that +// both the above copyright notice(s) and this permission notice +// appear in supporting documentation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR +// ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY +// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +// OF THIS SOFTWARE. +// +// Please report all bugs and problems to <gmsh@geuz.org>. #ifndef _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_ diff --git a/utils/solvers/c/GmshClient.c b/utils/solvers/c/GmshClient.c index 63a132ee01309ea82f51998828ed22c6a7225bf5..51b8b6f08646f65726777c20ab866182a5bd9acb 100644 --- a/utils/solvers/c/GmshClient.c +++ b/utils/solvers/c/GmshClient.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle + * Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -32,12 +32,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#ifdef _AIX +#if defined(_AIX) #include <strings.h> #endif #if !defined(WIN32) || defined(__CYGWIN__) - #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> @@ -46,22 +45,19 @@ #include <sys/time.h> #include <netinet/in.h> #include <netdb.h> - -#else /* pure windows */ - +#else #include <winsock.h> #include <process.h> - #endif /* private functions */ -static void Socket_SendData(int socket, void *buffer, int bytes) +static void Socket_SendData(int socket, const void *buffer, int bytes) { ssize_t len; int sofar, remaining; - char *buf; - buf = (char *)buffer; + const char *buf; + buf = (const char *)buffer; sofar = 0; remaining = bytes; do { @@ -71,7 +67,7 @@ static void Socket_SendData(int socket, void *buffer, int bytes) } while(remaining > 0); } -static void Socket_Idle(int ms) +static void Socket_Sleep(int ms) { #if !defined(WIN32) || defined(__CYGWIN__) usleep(1000 * ms); @@ -80,9 +76,18 @@ static void Socket_Idle(int ms) #endif } +static void Socket_Close(int s) +{ +#if !defined(WIN32) || defined(__CYGWIN__) + close(s); +#else + closesocket(s); +#endif +} + /* public interface */ -int Gmsh_Connect(char *sockname) +int Gmsh_Connect(const char *sockname) { #if !defined(WIN32) || defined(__CYGWIN__) struct sockaddr_un addr_un; @@ -106,25 +111,10 @@ int Gmsh_Connect(char *sockname) /* slight delay to be sure that the socket is bound by the server before we attempt to connect to it... */ - Socket_Idle(100); + Socket_Sleep(100); if(strstr(sockname, "/") || strstr(sockname, "\\") || !strstr(sockname, ":")){ /* UNIX socket (testing ":" is not enough with Windows paths) */ - portno = -1; - } - else{ - /* INET socket */ - port = strstr(sockname, ":"); - portno = atoi(port+1); - remotelen = strlen(sockname) - strlen(port); - if(remotelen > 0) - strncpy(remote, sockname, remotelen); - remote[remotelen] = '\0'; - } - - /* create socket */ - - if(portno < 0){ #if !defined(WIN32) || defined(__CYGWIN__) sock = socket(PF_UNIX, SOCK_STREAM, 0); if(sock < 0) @@ -136,7 +126,7 @@ int Gmsh_Connect(char *sockname) for(tries = 0; tries < 5; tries++) { if(connect(sock, (struct sockaddr *)&addr_un, sizeof(addr_un)) >= 0) return sock; - Socket_Idle(100); + Socket_Sleep(100); } #else /* Unix sockets are not available on Windows without Cygwin */ @@ -144,11 +134,20 @@ int Gmsh_Connect(char *sockname) #endif } else{ + /* TCP/IP socket */ sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) return -1; /* Error: Couldn't create socket */ - if(!(server = gethostbyname(remote))) + port = strstr(sockname, ":"); + portno = atoi(port+1); + remotelen = strlen(sockname) - strlen(port); + if(remotelen > 0) + strncpy(remote, sockname, remotelen); + remote[remotelen] = '\0'; + if(!(server = gethostbyname(remote))){ + Socket_Close(sock); return -3; /* Error: No such host */ + } /* try to connect socket to given name */ memset((char *) &addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; @@ -157,14 +156,14 @@ int Gmsh_Connect(char *sockname) for(tries = 0; tries < 5; tries++) { if(connect(sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) >= 0) return sock; - Socket_Idle(100); + Socket_Sleep(100); } } - + Socket_Close(sock); return -2; /* Error: Couldn't connect */ } -void Gmsh_SendString(int socket, int type, char str[]) +void Gmsh_SendString(int socket, int type, const char *str) { int len = strlen(str); Socket_SendData(socket, &type, sizeof(int)); @@ -174,10 +173,8 @@ void Gmsh_SendString(int socket, int type, char str[]) void Gmsh_Disconnect(int sock) { -#if !defined(WIN32) || defined(__CYGWIN__) - close(sock); -#else - closesocket(sock); + Socket_Close(sock); +#if defined(WIN32) && !defined(__CYGWIN__) WSACleanup(); #endif } diff --git a/utils/solvers/c/GmshClient.h b/utils/solvers/c/GmshClient.h index d7566c6e5b7660c9de4a83568790a04e2c713c1d..da277357c3af78e2bf4c64351d17412a51ffd66f 100644 --- a/utils/solvers/c/GmshClient.h +++ b/utils/solvers/c/GmshClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle + * Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -35,9 +35,10 @@ #define GMSH_CLIENT_WARNING 11 #define GMSH_CLIENT_ERROR 12 #define GMSH_CLIENT_PROGRESS 13 -#define GMSH_CLIENT_VIEW 20 /* deprecated: use MERGE_FILE instead */ #define GMSH_CLIENT_MERGE_FILE 20 #define GMSH_CLIENT_PARSE_STRING 21 +#define GMSH_CLIENT_VERTEX_ARRAY 22 +#define GMSH_CLIENT_SPEED_TEST 30 #define GMSH_CLIENT_OPTION 100 #define GMSH_CLIENT_OPTION_1 (GMSH_CLIENT_OPTION+0) #define GMSH_CLIENT_OPTION_2 (GMSH_CLIENT_OPTION+1) @@ -45,8 +46,8 @@ #define GMSH_CLIENT_OPTION_4 (GMSH_CLIENT_OPTION+3) #define GMSH_CLIENT_OPTION_5 (GMSH_CLIENT_OPTION+4) -int Gmsh_Connect(char *sockname); -void Gmsh_SendString(int socket, int type, char str[]); +int Gmsh_Connect(const char *sockname); +void Gmsh_SendString(int socket, int type, const char *str); void Gmsh_Disconnect(int sock); #endif diff --git a/utils/solvers/c/solver.c b/utils/solvers/c/solver.c index 44fd73c7e3a0a2444c72aebbb99ac4b99d25ca26..97cf1f890df8520b057eea4d73e3b92be0908835 100644 --- a/utils/solvers/c/solver.c +++ b/utils/solvers/c/solver.c @@ -82,6 +82,9 @@ int main(int argc, char *argv[]) if(argv[i]) option = argv[i++]; } + else{ + i++; + } } else name = argv[i++]; @@ -99,81 +102,73 @@ int main(int argc, char *argv[]) line option: */ s = Gmsh_Connect(socket); - switch (s) { - - /* 3.1. If the socket is <0, issue an error... */ - case -1: - printf("Couldn't create socket %s\n", socket); - break; - case -2: + if(s < 0) { printf("Couldn't connect to socket %s\n", socket); + exit(1); + } + + /* 4. Send the GMSH_CLIENT_START command (together with the process + ID of the solver), check if a problem name was specified, and + decide what to do according to the 'what' variable: */ + + sprintf(tmp, "%d", getpid()); + Gmsh_SendString(s, GMSH_CLIENT_START, tmp); + + if(!name) { + Gmsh_SendString(s, GMSH_CLIENT_ERROR, "Missing file name"); + Gmsh_Disconnect(s); + exit(1); + } + + switch (what) { + + /* 4.1. If what==options, the solver sends the valid options (here + for the first option): */ + + case options: + Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val1"); + Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val2"); + Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val3"); break; - default: - - /* 3.2. ...otherwise, send the GMSH_CLIENT_START command (together - with the process ID of the solver), check if a problem name was - specified, and decide what to do according to the 'what' - variable: */ - - sprintf(tmp, "%d", getpid()); - Gmsh_SendString(s, GMSH_CLIENT_START, tmp); - if(!name) { - Gmsh_SendString(s, GMSH_CLIENT_ERROR, "Missing file name"); - Gmsh_Disconnect(s); - exit(1); - } - switch (what) { - - /* 3.2.1. If what==options, the solver sends the valid options - (here for the first option): */ - - case options: - Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val1"); - Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val2"); - Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val3"); - break; - - /* 3.2.2. If what==run, the solver runs the chosen option, - updates the progress message, issues some information data, - produces a post-processing map and asks Gmsh to merge it: */ - - case run: - sprintf(tmp, "Running %s with option %s...", name, option); - Gmsh_SendString(s, GMSH_CLIENT_INFO, tmp); - for(i = 0; i < 10; i++) { - sprintf(tmp, "%d %% complete", 10*i); - Gmsh_SendString(s, GMSH_CLIENT_PROGRESS, tmp); - /* Fake some cpu-intensive calculation during 100ms: */ + + /* 4.2. If what==run, the solver runs the chosen option, updates + the progress message, issues some information data, produces a + post-processing map and asks Gmsh to merge it: */ + + case run: + sprintf(tmp, "Running %s with option %s...", name, option); + Gmsh_SendString(s, GMSH_CLIENT_INFO, tmp); + for(i = 0; i < 10; i++) { + sprintf(tmp, "%d %% complete", 10 * i); + Gmsh_SendString(s, GMSH_CLIENT_PROGRESS, tmp); + /* Fake some cpu-intensive calculation during 100ms: */ #if !defined(WIN32) || defined(__CYGWIN__) - usleep(100 * 1000); + usleep(100 * 1000); #else - Sleep(100); + Sleep(100); #endif - } - sprintf(tmp, "Done with %s!", name); - Gmsh_SendString(s, GMSH_CLIENT_INFO, tmp); - file = fopen("solver.pos", "wb"); - if(!file) { - Gmsh_SendString(s, GMSH_CLIENT_ERROR, "Unable to open output file"); - } - else { - fprintf(file, "View \"%s\"{\n", option); - fprintf(file, "ST(0,0,0,1,0,0,0,1,0){0,1,2};\n"); - fprintf(file, "};\n"); - fclose(file); - Gmsh_SendString(s, GMSH_CLIENT_MERGE_FILE, "solver.pos"); - } - break; } - - /* 3.3. We can now disconnect the solver from Gmsh: */ - - Gmsh_SendString(s, GMSH_CLIENT_STOP, "Goodbye!"); - Gmsh_Disconnect(s); + sprintf(tmp, "Done with %s!", name); + Gmsh_SendString(s, GMSH_CLIENT_INFO, tmp); + file = fopen("solver.pos", "wb"); + if(!file) { + Gmsh_SendString(s, GMSH_CLIENT_ERROR, "Unable to open output file"); + } + else { + fprintf(file, "View \"%s\"{\n", option); + fprintf(file, "ST(0,0,0,1,0,0,0,1,0){0,1,2};\n"); + fprintf(file, "};\n"); + fclose(file); + Gmsh_SendString(s, GMSH_CLIENT_MERGE_FILE, "solver.pos"); + } break; } - - /* 4. That's it! */ + + /* 5. We can now disconnect the solver from Gmsh: */ + + Gmsh_SendString(s, GMSH_CLIENT_STOP, "Goodbye!"); + Gmsh_Disconnect(s); + return 0; } diff --git a/utils/solvers/c/solver.opt b/utils/solvers/c/solver.opt index bb035e8164cee44013ef5fd52c20ba430d3cb8aa..52973bbf8e1173d5f9fac03a3580ebe8f28c78d3 100644 --- a/utils/solvers/c/solver.opt +++ b/utils/solvers/c/solver.opt @@ -4,6 +4,7 @@ Solver.Name1 = "My C solver"; Solver.Help1 = "A simple example of the client/server solver implementation in Gmsh..."; Solver.Executable1 = "./solver.exe"; +Solver.InputName1 = "dummy"; Solver.SocketCommand1 = "-socket %s"; Solver.NameCommand1 = "%s"; Solver.OptionCommand1 = "-options";