go to www.geomview.org home page
 
Home

Overview
FAQ
Documentation

Download

Mailing List

Geomview For Windows?

Support
Users
Development

Bug Reporting
Contributing
Contact Us

Sponsors

 

Site Search

 

Advanced
Search

 
About the software@geom archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sockets



Yes, you can use (UNIX-domain) sockets to exchange data/commands with geomview.
See "src/bin/util/togeomview.c" in the source distribution, or as a simpler
example, try the following program.  As it stands, it just copies its own
standard input to the socket, but you could just as well incorporate this code
into your program and write directly.  [See "man 3 fdopen" for producing a
FILE structure given an integer file descriptor like 'fd' here.]

Note that geomview must be started with a command-line option like
	-Mgs  socketname		(if you're sending raw geometry)
  or	-Mcs  socketname		(if you're sending geomview commands)

in order to handle the socket.  There's no way to make it begin listening
to a socket after it's started.


Example program follows.   Just "cc -o program program.c" to compile.


#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

extern int errno;

main(int argc, char *argv[])
{
    int n, fd = -1;
    char pipename[1024];
    struct sockaddr_un un;
    struct stat st;
    char *todir = "/tmp/geomview";
    char *toname = "mypipe";

	/* Create the directory for pipes/sockets
	 * unless someone else already has.
	 */
    if(access(todir, 1) < 0) {
	mkdir(todir, 0777);
	chmod(todir, 0777);
    }
    sprintf(pipename, "%s/%s", todir, toname);

	/* Remove any pre-existing pipe if it's not of the type we want. */
    if(stat(pipename, &st) > 0 && (st.st_mode&S_IFMT) != S_IFSOCK)
	unlink(pipename);

	/* Create a UNIX-domain socket with the given pathname */
    strncpy(un.sun_path, pipename, sizeof(un.sun_path)-1);
    un.sun_family = AF_UNIX;
    fd = socket(AF_UNIX, SOCK_STREAM, 0);

	/* If geomview is already listening on our socket, connect to it... */

    if(connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
	if(errno != ECONNREFUSED && errno != ENOENT) {
	    fprintf(stderr, "togeomview: Can't connect to ");
	    perror(pipename);
	    exit(1);
	}

	  /* Otherwise, start geomview, and wait a while for it to start up.
	   * We'll know it's started by the fact that it began listening
	   * on our socket.
	   */
	system("geomview -Msg mypipe &");

	for(n = 0; connect(fd, (struct sockaddr*)&un, sizeof(un)) < 0; n++) {
		/* Wait up to 20 seconds to connect */
	    if(n == 20) {
		fprintf(stderr, "Couldn't start geomview.\n");
		exit(1);
	    }
	    sleep(1);
	}
    }

	/* Failed? */
    if(fd < 0) {
	fprintf(stderr, "Can't open connection to geomview: ");
	perror(pipename);
	exit(1);
    }

    /* Enlarge the socket buffer */
    {
	int big = 32768;	/* Allow 32K of buffer space in each direction
				 * rather than the default (8K?)
				 */
	setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &big, sizeof(big));
	setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &big, sizeof(big));
    }

    /* Write data to the socket. Here, we just copy from our standard input. */

    while((n = read(0, pipename, sizeof(pipename))) > 0) {
	if(write(fd, pipename, n) < n) {
	    perror("Error writing to geomview");
	    exit(1);
	}
    }
    exit(0);
}


  - Stuart


 
Home | Overview | FAQ | Documentation | Support | Download | Mailing List
Windows? | Development | Bug Reporting | Contributing | Contact Us | Sponsors
 
site hosted by
SourceForge Logo