Skip to content
Snippets Groups Projects
Commit 1393af16 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

update C client example + fix GmshSsocket license

parent 635fbafd
No related branches found
No related tags found
No related merge requests found
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle // Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
// //
// See the LICENSE.txt file for license information. Please report all // Permission is hereby granted, free of charge, to any person
// bugs and problems to <gmsh@geuz.org>. // 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_ #ifndef _GMSH_SOCKET_H_
#define _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_
......
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle // Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
// //
// See the LICENSE.txt file for license information. Please report all // Permission is hereby granted, free of charge, to any person
// bugs and problems to <gmsh@geuz.org>. // 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_ #ifndef _GMSH_SOCKET_H_
#define _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_
......
/* /*
* 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 * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
...@@ -32,12 +32,11 @@ ...@@ -32,12 +32,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef _AIX #if defined(_AIX)
#include <strings.h> #include <strings.h>
#endif #endif
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
...@@ -46,22 +45,19 @@ ...@@ -46,22 +45,19 @@
#include <sys/time.h> #include <sys/time.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#else
#else /* pure windows */
#include <winsock.h> #include <winsock.h>
#include <process.h> #include <process.h>
#endif #endif
/* private functions */ /* 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; ssize_t len;
int sofar, remaining; int sofar, remaining;
char *buf; const char *buf;
buf = (char *)buffer; buf = (const char *)buffer;
sofar = 0; sofar = 0;
remaining = bytes; remaining = bytes;
do { do {
...@@ -71,7 +67,7 @@ static void Socket_SendData(int socket, void *buffer, int bytes) ...@@ -71,7 +67,7 @@ static void Socket_SendData(int socket, void *buffer, int bytes)
} while(remaining > 0); } while(remaining > 0);
} }
static void Socket_Idle(int ms) static void Socket_Sleep(int ms)
{ {
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
usleep(1000 * ms); usleep(1000 * ms);
...@@ -80,9 +76,18 @@ static void Socket_Idle(int ms) ...@@ -80,9 +76,18 @@ static void Socket_Idle(int ms)
#endif #endif
} }
static void Socket_Close(int s)
{
#if !defined(WIN32) || defined(__CYGWIN__)
close(s);
#else
closesocket(s);
#endif
}
/* public interface */ /* public interface */
int Gmsh_Connect(char *sockname) int Gmsh_Connect(const char *sockname)
{ {
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
struct sockaddr_un addr_un; struct sockaddr_un addr_un;
...@@ -106,25 +111,10 @@ int Gmsh_Connect(char *sockname) ...@@ -106,25 +111,10 @@ int Gmsh_Connect(char *sockname)
/* slight delay to be sure that the socket is bound by the /* slight delay to be sure that the socket is bound by the
server before we attempt to connect to it... */ server before we attempt to connect to it... */
Socket_Idle(100); Socket_Sleep(100);
if(strstr(sockname, "/") || strstr(sockname, "\\") || !strstr(sockname, ":")){ if(strstr(sockname, "/") || strstr(sockname, "\\") || !strstr(sockname, ":")){
/* UNIX socket (testing ":" is not enough with Windows paths) */ /* 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__) #if !defined(WIN32) || defined(__CYGWIN__)
sock = socket(PF_UNIX, SOCK_STREAM, 0); sock = socket(PF_UNIX, SOCK_STREAM, 0);
if(sock < 0) if(sock < 0)
...@@ -136,7 +126,7 @@ int Gmsh_Connect(char *sockname) ...@@ -136,7 +126,7 @@ int Gmsh_Connect(char *sockname)
for(tries = 0; tries < 5; tries++) { for(tries = 0; tries < 5; tries++) {
if(connect(sock, (struct sockaddr *)&addr_un, sizeof(addr_un)) >= 0) if(connect(sock, (struct sockaddr *)&addr_un, sizeof(addr_un)) >= 0)
return sock; return sock;
Socket_Idle(100); Socket_Sleep(100);
} }
#else #else
/* Unix sockets are not available on Windows without Cygwin */ /* Unix sockets are not available on Windows without Cygwin */
...@@ -144,11 +134,20 @@ int Gmsh_Connect(char *sockname) ...@@ -144,11 +134,20 @@ int Gmsh_Connect(char *sockname)
#endif #endif
} }
else{ else{
/* TCP/IP socket */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0) if(sock < 0)
return -1; /* Error: Couldn't create socket */ 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 */ return -3; /* Error: No such host */
}
/* try to connect socket to given name */ /* try to connect socket to given name */
memset((char *) &addr_in, 0, sizeof(addr_in)); memset((char *) &addr_in, 0, sizeof(addr_in));
addr_in.sin_family = AF_INET; addr_in.sin_family = AF_INET;
...@@ -157,14 +156,14 @@ int Gmsh_Connect(char *sockname) ...@@ -157,14 +156,14 @@ int Gmsh_Connect(char *sockname)
for(tries = 0; tries < 5; tries++) { for(tries = 0; tries < 5; tries++) {
if(connect(sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) >= 0) if(connect(sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) >= 0)
return sock; return sock;
Socket_Idle(100); Socket_Sleep(100);
} }
} }
Socket_Close(sock);
return -2; /* Error: Couldn't connect */ 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); int len = strlen(str);
Socket_SendData(socket, &type, sizeof(int)); Socket_SendData(socket, &type, sizeof(int));
...@@ -174,10 +173,8 @@ void Gmsh_SendString(int socket, int type, char str[]) ...@@ -174,10 +173,8 @@ void Gmsh_SendString(int socket, int type, char str[])
void Gmsh_Disconnect(int sock) void Gmsh_Disconnect(int sock)
{ {
#if !defined(WIN32) || defined(__CYGWIN__) Socket_Close(sock);
close(sock); #if defined(WIN32) && !defined(__CYGWIN__)
#else
closesocket(sock);
WSACleanup(); WSACleanup();
#endif #endif
} }
/* /*
* 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 * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
...@@ -35,9 +35,10 @@ ...@@ -35,9 +35,10 @@
#define GMSH_CLIENT_WARNING 11 #define GMSH_CLIENT_WARNING 11
#define GMSH_CLIENT_ERROR 12 #define GMSH_CLIENT_ERROR 12
#define GMSH_CLIENT_PROGRESS 13 #define GMSH_CLIENT_PROGRESS 13
#define GMSH_CLIENT_VIEW 20 /* deprecated: use MERGE_FILE instead */
#define GMSH_CLIENT_MERGE_FILE 20 #define GMSH_CLIENT_MERGE_FILE 20
#define GMSH_CLIENT_PARSE_STRING 21 #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 100
#define GMSH_CLIENT_OPTION_1 (GMSH_CLIENT_OPTION+0) #define GMSH_CLIENT_OPTION_1 (GMSH_CLIENT_OPTION+0)
#define GMSH_CLIENT_OPTION_2 (GMSH_CLIENT_OPTION+1) #define GMSH_CLIENT_OPTION_2 (GMSH_CLIENT_OPTION+1)
...@@ -45,8 +46,8 @@ ...@@ -45,8 +46,8 @@
#define GMSH_CLIENT_OPTION_4 (GMSH_CLIENT_OPTION+3) #define GMSH_CLIENT_OPTION_4 (GMSH_CLIENT_OPTION+3)
#define GMSH_CLIENT_OPTION_5 (GMSH_CLIENT_OPTION+4) #define GMSH_CLIENT_OPTION_5 (GMSH_CLIENT_OPTION+4)
int Gmsh_Connect(char *sockname); int Gmsh_Connect(const char *sockname);
void Gmsh_SendString(int socket, int type, char str[]); void Gmsh_SendString(int socket, int type, const char *str);
void Gmsh_Disconnect(int sock); void Gmsh_Disconnect(int sock);
#endif #endif
...@@ -82,6 +82,9 @@ int main(int argc, char *argv[]) ...@@ -82,6 +82,9 @@ int main(int argc, char *argv[])
if(argv[i]) if(argv[i])
option = argv[i++]; option = argv[i++];
} }
else{
i++;
}
} }
else else
name = argv[i++]; name = argv[i++];
...@@ -99,34 +102,29 @@ int main(int argc, char *argv[]) ...@@ -99,34 +102,29 @@ int main(int argc, char *argv[])
line option: */ line option: */
s = Gmsh_Connect(socket); s = Gmsh_Connect(socket);
switch (s) {
/* 3.1. If the socket is <0, issue an error... */ if(s < 0) {
case -1:
printf("Couldn't create socket %s\n", socket);
break;
case -2:
printf("Couldn't connect to socket %s\n", socket); printf("Couldn't connect to socket %s\n", socket);
break; exit(1);
default: }
/* 3.2. ...otherwise, send the GMSH_CLIENT_START command (together /* 4. Send the GMSH_CLIENT_START command (together with the process
with the process ID of the solver), check if a problem name was ID of the solver), check if a problem name was specified, and
specified, and decide what to do according to the 'what' decide what to do according to the 'what' variable: */
variable: */
sprintf(tmp, "%d", getpid()); sprintf(tmp, "%d", getpid());
Gmsh_SendString(s, GMSH_CLIENT_START, tmp); Gmsh_SendString(s, GMSH_CLIENT_START, tmp);
if(!name) { if(!name) {
Gmsh_SendString(s, GMSH_CLIENT_ERROR, "Missing file name"); Gmsh_SendString(s, GMSH_CLIENT_ERROR, "Missing file name");
Gmsh_Disconnect(s); Gmsh_Disconnect(s);
exit(1); exit(1);
} }
switch (what) { switch (what) {
/* 3.2.1. If what==options, the solver sends the valid options /* 4.1. If what==options, the solver sends the valid options (here
(here for the first option): */ for the first option): */
case options: case options:
Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val1"); Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val1");
...@@ -134,9 +132,9 @@ int main(int argc, char *argv[]) ...@@ -134,9 +132,9 @@ int main(int argc, char *argv[])
Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val3"); Gmsh_SendString(s, GMSH_CLIENT_OPTION_1, "Val3");
break; break;
/* 3.2.2. If what==run, the solver runs the chosen option, /* 4.2. If what==run, the solver runs the chosen option, updates
updates the progress message, issues some information data, the progress message, issues some information data, produces a
produces a post-processing map and asks Gmsh to merge it: */ post-processing map and asks Gmsh to merge it: */
case run: case run:
sprintf(tmp, "Running %s with option %s...", name, option); sprintf(tmp, "Running %s with option %s...", name, option);
...@@ -167,13 +165,10 @@ int main(int argc, char *argv[]) ...@@ -167,13 +165,10 @@ int main(int argc, char *argv[])
break; break;
} }
/* 3.3. We can now disconnect the solver from Gmsh: */ /* 5. We can now disconnect the solver from Gmsh: */
Gmsh_SendString(s, GMSH_CLIENT_STOP, "Goodbye!"); Gmsh_SendString(s, GMSH_CLIENT_STOP, "Goodbye!");
Gmsh_Disconnect(s); Gmsh_Disconnect(s);
break;
}
/* 4. That's it! */
return 0; return 0;
} }
...@@ -4,6 +4,7 @@ Solver.Name1 = "My C solver"; ...@@ -4,6 +4,7 @@ Solver.Name1 = "My C solver";
Solver.Help1 = "A simple example of the client/server Solver.Help1 = "A simple example of the client/server
solver implementation in Gmsh..."; solver implementation in Gmsh...";
Solver.Executable1 = "./solver.exe"; Solver.Executable1 = "./solver.exe";
Solver.InputName1 = "dummy";
Solver.SocketCommand1 = "-socket %s"; Solver.SocketCommand1 = "-socket %s";
Solver.NameCommand1 = "%s"; Solver.NameCommand1 = "%s";
Solver.OptionCommand1 = "-options"; Solver.OptionCommand1 = "-options";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment