summaryrefslogtreecommitdiffstats
path: root/xpa/stest.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2016-10-17 15:27:21 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2016-10-17 15:27:21 (GMT)
commit912e82088edadbdbf95d594f93ddc9dd99a305f8 (patch)
tree9153dcd3bcf256fb26ebdcbfd8a1a7d9132430f1 /xpa/stest.c
parentfecf4a80a5080aa65e7c2d717f96e86ad04ca46c (diff)
parentd604b7940b14efb191a38ef22c3a38fa3adba4d0 (diff)
downloadblt-912e82088edadbdbf95d594f93ddc9dd99a305f8.zip
blt-912e82088edadbdbf95d594f93ddc9dd99a305f8.tar.gz
blt-912e82088edadbdbf95d594f93ddc9dd99a305f8.tar.bz2
Merge commit 'd604b7940b14efb191a38ef22c3a38fa3adba4d0' as 'xpa'
Diffstat (limited to 'xpa/stest.c')
-rw-r--r--xpa/stest.c729
1 files changed, 729 insertions, 0 deletions
diff --git a/xpa/stest.c b/xpa/stest.c
new file mode 100644
index 0000000..afceb89
--- /dev/null
+++ b/xpa/stest.c
@@ -0,0 +1,729 @@
+/*
+ * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory
+ */
+
+/*
+ *
+ * stest -- server test for xpa
+ *
+ */
+#include <xpap.h>
+
+#ifndef BUILD_WITH_XT
+#if HAVE_XT
+#undef HAVE_XT
+#endif
+#endif
+
+#if HAVE_XT
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#endif
+
+#define MAX_FPS 10
+
+extern char *optarg;
+extern int optind;
+
+XPA xpa1, xpa1a, xpa2, xpa3;
+int quiet=0;
+int dowait=0;
+int dofill=0;
+int dosave=1;
+int doone=0;
+int domyfree=0;
+int doatexit=0;
+int n=0;
+int please_exit=0;
+size_t save_bytes=-1;
+char *save_buf=NULL;
+
+char *mode="";
+char name[SZ_LINE];
+char xclass[SZ_LINE];
+
+#ifdef ANSI_FUNC
+void myfree(void *buf)
+#else
+void myfree(buf)
+ void *buf;
+#endif
+{
+ fprintf(stderr, "myfree calling xfree(%p)\n", buf);
+ xfree(buf);
+}
+
+#ifdef ANSI_FUNC
+int
+send_cb (void *client_data, void *call_data, char *paramlist,
+ char **buf, size_t *len)
+#else
+int send_cb(client_data, call_data, paramlist, buf, len)
+ void *client_data;
+ void *call_data;
+ char *paramlist;
+ char **buf;
+ size_t *len;
+#endif
+{
+ char *s = (char *)client_data;
+ XPA xpa = (XPA)call_data;
+ char tbuf[SZ_LINE];
+ char xtemplate[SZ_LINE];
+ char *names[MAX_FPS];
+ char *bufs[MAX_FPS];
+ char *errs[MAX_FPS];
+ size_t lens[MAX_FPS];
+ int sendbuf=0;
+ int got;
+ int i;
+ int ip;
+
+ /* set the free routine */
+ if( domyfree ) XPASetFree(xpa, myfree, NULL);
+
+ /* introduce ourselves */
+ if( !quiet ){
+ fprintf(stdout, "SEND_CB #%d: %s:%s %s (%s)\n",
+ n++, xpa_class(xpa), xpa_name(xpa), xpa_method(xpa), s);
+ }
+
+ /* process special paramlist tokens */
+ if( paramlist && *paramlist ){
+ ip = 0;
+ word(paramlist, xtemplate, &ip);
+ if( !quiet )
+ fprintf(stdout, "\tparamlist: %s\n", paramlist);
+ if( !strncmp(paramlist, "buf", 3) ){
+ sendbuf=1;
+ }
+ else if( !strcmp(paramlist, "free") ){
+ if( !quiet )
+ fprintf(stdout, "Freeing xpa struct\n");
+ XPAFree(xpa);
+ return(0);
+ }
+ else if( !strcmp(paramlist, "exit") ){
+ if( !quiet )
+ fprintf(stdout, "Exiting\n");
+ if( doatexit){
+ please_exit = 1;
+ } else {
+ XPAFree(xpa1);
+ if( !doone ){
+ XPAFree(xpa1a);
+ XPAFree(xpa2);
+ XPAFree(xpa3);
+ }
+ }
+ }
+ else if( !strcmp(paramlist, "Exit") ){
+ if( !quiet )
+ fprintf(stdout, "Exiting immediately\n");
+ exit(0);
+ }
+ else if( !strncmp(paramlist, "error", 5) ){
+ if( !quiet )
+ fprintf(stdout, "\treturning error: %s\n", &paramlist[6]);
+ *len = 0;
+ *buf = NULL;
+ if( strlen(paramlist) > 6 )
+ XPAError(xpa, &paramlist[6]);
+ else
+ XPAError(xpa, "intentional error from client");
+ return(-1);
+ }
+ else if( !strcmp(paramlist, "wait") || !strcmp(paramlist, "version") ){
+ fprintf(stdout, "Press <CR> to continue ...");
+ fgets(tbuf, SZ_LINE, stdin);
+ }
+ else if( !strcmp(paramlist, "poll") ){
+repoll:
+ fprintf(stdout, "Press 'q' to quit ...");
+ got = XPAPoll (10000, 1);
+ fprintf(stdout, " XPAPoll returns %d ...", got);
+ fgets(tbuf, SZ_LINE, stdin);
+ if( *tbuf != 'q' )
+ goto repoll;
+ }
+ else if( !strncmp(paramlist, "fork ", 5) ){
+#if HAVE_MINGW32==0
+ if( strlen(paramlist) > 5 ){
+ fprintf(stdout, "fork command: %s\n", &paramlist[5]);
+ /* child forks a command and exits */
+ if(!(fork())){
+ system(&paramlist[5]);
+ /* should call _exit but this tests avoidance of atexit routine */
+ exit(0);
+ }
+ }
+#else
+ fprintf(stderr, "ERROR: fork() not available in mingw\n");
+ exit(1);
+#endif
+ }
+ else if( !strcmp(xtemplate, "xpaget") ){
+ word(paramlist, xtemplate, &ip);
+ got = XPAGet(xpa, xtemplate, &(paramlist[ip]), NULL,
+ bufs, lens, names, errs, MAX_FPS);
+ if( !quiet )
+ fprintf(stdout, "XPAGet (%s) returned %d buffer(s)\n", xtemplate, got);
+ for(i=0; i<got; i++){
+ if( !quiet )
+ fprintf(stdout, "\t%d: %s\n", i, names[i]);
+ if( errs[i] == NULL ){
+ if( !quiet && (lens[i] > 0) ){
+ fprintf(stdout, "contents (%lu bytes):\n", (unsigned long)lens[i]);
+ fwrite(bufs[i], sizeof(char), lens[i], stdout);
+ }
+ if( !quiet )
+ fprintf(stdout, "\n");
+ }
+ else{
+ write(fileno(stdout), errs[i], strlen(errs[i]));
+ }
+ if( bufs[i] )
+ xfree(bufs[i]);
+ if( names[i] )
+ xfree(names[i]);
+ if( errs[i] )
+ xfree(errs[i]);
+ }
+ }
+ }
+ else if( dowait ){
+ fprintf(stdout, "Press <CR> to continue ...");
+ fgets(tbuf, SZ_LINE, stdin);
+ }
+
+ /* return information about this xpa */
+ if( !sendbuf ){
+ snprintf(tbuf, SZ_LINE,
+ "class: %s\nname: %s\nmethod: %s\nsendian: %s\ncendian: %s\n",
+ xpa_class(xpa), xpa_name(xpa), xpa_method(xpa),
+ xpa_sendian(xpa), xpa_cendian(xpa));
+
+ if( (xpa->send_mode & XPA_MODE_FILLBUF) ){
+ send(xpa_datafd(xpa), tbuf, strlen(tbuf), 0);
+ *len = 0;
+ *buf = NULL;
+ if( !quiet)
+ fprintf(stdout, "\tcallback writes %d bytes to client\n",
+ (int)strlen(tbuf));
+ }
+ /* return the buffer and let xpa transmit it */
+ else{
+ *len = strlen(tbuf);
+ *buf = (char *)xmalloc(*len);
+ memcpy(*buf, tbuf, *len);
+ if( !quiet)
+ fprintf(stdout, "\tcallback returns %d bytes to xpa handler\n",
+ (int)strlen(tbuf));
+ }
+ }
+ /* return the last buffer we were sent */
+ else{
+ if( (xpa->send_mode & XPA_MODE_FILLBUF) ){
+ send(xpa_datafd(xpa), save_buf, save_bytes, 0);
+ *len = 0;
+ *buf = NULL;
+ if( !quiet)
+ fprintf(stdout, "\tcallback writes %lu bytes to client\n",
+ (unsigned long)save_bytes);
+ }
+ /* return the buffer and let xpa transmit it */
+ else{
+ *len = save_bytes;
+ *buf = (char *)xmalloc(*len);
+ memcpy(*buf, save_buf, *len);
+ if( !quiet)
+ fprintf(stdout, "\tcallback returns %lu bytes to xpa handler\n",
+ (unsigned long)save_bytes);
+ }
+ }
+ if( !quiet ){
+ fprintf(stdout, "SEND_CB complete\n");
+ }
+ else{
+ fprintf(stdout, ".");
+ }
+ fflush(stdout);
+ fflush(stderr);
+ return(0);
+}
+
+#ifdef ANSI_FUNC
+int
+receive_cb (void *client_data, void *call_data, char *paramlist,
+ char *buf, size_t len)
+#else
+int receive_cb(client_data, call_data, paramlist, buf, len)
+ void *client_data;
+ void *call_data;
+ char *paramlist;
+ char *buf;
+ size_t len;
+#endif
+{
+ XPA xpa = (XPA)call_data;
+ char *s = (char *)client_data;
+ char tbuf[SZ_LINE];
+ char cbuf[SZ_LINE];
+ char *errs[1];
+ int i;
+ int ip;
+ int got;
+ int xwait;
+
+ /* set the free routine */
+ if( domyfree ) XPASetFree(xpa, myfree, NULL);
+
+ if( !quiet ){
+ fprintf(stdout, "RECEIVE_CB #%d: %s:%s %s (%s)\n",
+ n++, xpa_class(xpa), xpa_name(xpa), xpa_method(xpa), s);
+ }
+ /* process param list */
+ if( paramlist && *paramlist ){
+ if( !quiet )
+ fprintf(stdout, "\tparamlist: %s\n", paramlist);
+ if( !strcmp(paramlist, "free") ){
+ if( !quiet )
+ fprintf(stdout, "Freeing xpa struct\n");
+ XPAFree(xpa);
+ return(0);
+ }
+ else if( !strcmp(paramlist, "exit") ){
+ if( !quiet )
+ fprintf(stdout, "Exiting\n");
+ if( doatexit){
+ please_exit = 1;
+ } else {
+ XPAFree(xpa1);
+ if( !doone ){
+ XPAFree(xpa1a);
+ XPAFree(xpa2);
+ XPAFree(xpa3);
+ }
+ }
+ }
+ else if( !strcmp(paramlist, "Exit") ){
+ if( !quiet )
+ fprintf(stdout, "Exiting immediately\n");
+ exit(0);
+ }
+ else if( !strncmp(paramlist, "error", 5) ){
+ if( !quiet )
+ fprintf(stdout, "Processing error: %s\n", &paramlist[6]);
+ if( strlen(paramlist) > 6 )
+ XPAError(xpa, &paramlist[6]);
+ else
+ XPAError(xpa, "intentional error from client");
+ return(-1);
+ }
+ else if( !strcmp(paramlist, "wait") ){
+ fprintf(stdout, "Press <CR> to continue ...");
+ fgets(tbuf, SZ_LINE, stdin);
+ }
+ else if( !strcmp(paramlist, "poll") ){
+repoll:
+ fprintf(stdout, "Press 'q' to quit ...");
+ got = XPAPoll (10000, 1);
+ fprintf(stdout, " ... XPAPoll returns %d ...", got);
+ fgets(tbuf, SZ_LINE, stdin);
+ if( *tbuf != 'q' )
+ goto repoll;
+ }
+ else if( !strncmp(paramlist, "fork ", 5) ){
+#if HAVE_MINGW32==0
+ if( strlen(paramlist) > 5 ){
+ fprintf(stdout, "fork command: %s\n", &paramlist[5]);
+ /* child forks a command and exits */
+ if(!(fork())){
+ system(&paramlist[5]);
+ /* should call _exit but this tests avoidance of atexit routine */
+ exit(0);
+ }
+ }
+#else
+ fprintf(stderr, "ERROR: fork() not available in mingw\n");
+ exit(1);
+#endif
+ }
+ else if( !strncmp(paramlist, "xpaset", 6) ){
+ ip = 0;
+ word(paramlist, tbuf, &ip);
+ if( word(paramlist, tbuf, &ip) ){
+ if( !quiet )
+ fprintf(stdout, "calling XPASet(%s, \"%s\")\n",
+ tbuf, &(paramlist[ip]));
+ got = XPASet(NULL, tbuf, &(paramlist[ip]), mode,
+ paramlist, strlen(paramlist), NULL, errs, 1);
+ if( got == 0 ){
+ if( !quiet )
+ fprintf(stdout, "no XPA access points matched template %s\n",
+ tbuf);
+ }
+ else if( errs[0] != NULL ){
+ if( !quiet )
+ fprintf(stdout, "Error on xpaset to %s: %s\n", tbuf, errs[0]);
+ xfree(errs[0]);
+ }
+ else{
+ if( !quiet )
+ fprintf(stdout, "XPASet to %s successful\n", tbuf);
+ }
+ }
+ return(0);
+ }
+ }
+ else if( dowait ){
+ fprintf(stdout, "Press <CR> to continue ...");
+ fgets(tbuf, SZ_LINE, stdin);
+ }
+
+ /* reset save buffer */
+ if( save_buf != NULL ){
+ xfree(save_buf);
+ save_buf = NULL;
+ }
+ save_bytes = 0;
+ xwait = dowait;
+ if( !(xpa->receive_mode & XPA_MODE_FILLBUF) && dofill ){
+ while( (got=recv(xpa_datafd(xpa), tbuf, SZ_LINE, 0)) >0 ){
+ if( xwait >0 ){
+ fprintf(stdout, "got %d bytes ... press <CR> to continue ...", got);
+ fgets(cbuf, SZ_LINE, stdin);
+ xwait--;
+ }
+ i = save_bytes;
+ save_bytes += got;
+ if( dosave ){
+ if( save_buf == NULL )
+ save_buf = (char *)xmalloc(save_bytes);
+ else
+ save_buf = (char *)xrealloc(save_buf, save_bytes);
+ memcpy(&save_buf[i], tbuf, got);
+ }
+ }
+ if( !quiet )
+ fprintf(stdout, "\tcallback read %lu bytes\n",
+ (unsigned long)save_bytes);
+ }
+ else{
+ if( !quiet ){
+ fprintf(stdout, "\tenter callback with buf: %lu bytes\n",
+ (unsigned long)len);
+ }
+ save_bytes = len;
+ save_buf = (char *)xmalloc(len);
+ memcpy(save_buf, buf, len);
+ }
+ if( !quiet ){
+ fprintf(stdout, "RECEIVE_CB complete\n");
+ }
+ else{
+ fprintf(stdout, ".");
+ }
+ fflush(stdout);
+ fflush(stderr);
+ return(0);
+}
+
+#ifdef ANSI_FUNC
+int
+info_cb (void *client_data, void *call_data, char *paramlist)
+#else
+int info_cb(client_data, call_data, paramlist)
+ void *client_data;
+ void *call_data;
+ char *paramlist;
+#endif
+{
+ XPA xpa = (XPA)call_data;
+ char *s = (char *)client_data;
+ char xtemplate[SZ_LINE];
+ char *names[MAX_FPS];
+ char *bufs[MAX_FPS];
+ char *errs[MAX_FPS];
+ size_t lens[MAX_FPS];
+ int i;
+ int ip;
+ int got;
+
+ if( !quiet ){
+ fprintf(stdout, "INFO_CB #%d: %s:%s (%s)\n",
+ n++, xpa_class(xpa), xpa_name(xpa), s);
+ }
+
+ if( paramlist && *paramlist ){
+ if( !quiet )
+ fprintf(stdout, "\tparamlist: %s\n", paramlist);
+ ip = 0;
+ word(paramlist, xtemplate, &ip);
+ if( !strcmp(xtemplate, "xpaget") ){
+ word(paramlist, xtemplate, &ip);
+ got = XPAGet(xpa, xtemplate, &(paramlist[ip]), NULL,
+ bufs, lens, names, errs, MAX_FPS);
+ if( !quiet )
+ fprintf(stdout, "XPAGet (%s) returned %d buffer(s)\n", xtemplate, got);
+ for(i=0; i<got; i++){
+ if( !quiet )
+ fprintf(stdout, "\t%d: %s\n", i, names[i]);
+ if( errs[i] == NULL ){
+ if( !quiet && (lens[i] > 0) ){
+ fprintf(stdout, "contents (%lu bytes):\n",
+ (unsigned long)lens[i]);
+ fwrite(bufs[i], sizeof(char), lens[i], stdout);
+ }
+ if( !quiet )
+ fprintf(stdout, "\n");
+ }
+ else{
+ write(fileno(stdout), errs[i], strlen(errs[i]));
+ }
+ if( bufs[i] )
+ xfree(bufs[i]);
+ if( names[i] )
+ xfree(names[i]);
+ if( errs[i] )
+ xfree(errs[i]);
+ }
+ }
+ }
+ if( !quiet ){
+ fprintf(stdout, "INFO_CB complete\n");
+ }
+ else{
+ fprintf(stdout, ".");
+ }
+ fflush(stdout);
+ fflush(stderr);
+ return(0);
+}
+
+#ifdef ANSI_FUNC
+int
+main (int argc, char **argv)
+#else
+main(argc, argv)
+ int argc;
+ char **argv;
+#endif
+{
+#if HAVE_XT
+ Widget top;
+ XtAppContext appcontext;
+#endif
+ char *proxy=NULL;
+ char tbuf[SZ_LINE];
+ char tbuf2[SZ_LINE];
+ char cmd[SZ_LINE];
+ int c;
+ int got=0;
+ int x=0;
+ int delay=0;
+
+#if HAVE_MINGW32==0
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+#endif
+
+ *cmd = '\0';
+ /* process switch arguments */
+ while ((c = getopt(argc, argv, "1ad:f:mqrRp:suwxX")) != -1){
+ switch(c){
+ case '1':
+ doone = 1;
+ break;
+ case 'a':
+ mode = "ack=false";
+ break;
+ case 'd':
+ delay = atoi(optarg);
+ break;
+ case 'f':
+ snprintf(cmd, SZ_LINE, "%s %s &\n", argv[0], optarg);
+ break;
+ case 'm':
+ domyfree = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 'p':
+ proxy = optarg;
+ break;
+ case 'r':
+ mode = "fillbuf=false";
+ break;
+ case 'R':
+ mode = "fillbuf=false";
+ dofill = 1;
+ dosave = 0;
+ break;
+ case 's':
+ x = 0;
+ break;
+ case 'u':
+ mode = "buf=false";
+ break;
+ case 'w':
+ dowait++;
+ break;
+ case 'x':
+ doatexit=1;
+ break;
+ case 'X':
+ x = 1;
+ break;
+ }
+ }
+
+ if( optind >= argc ){
+ strcpy(name, "xpa");
+ }
+ else{
+ strcpy(name, argv[optind]);
+ }
+ strcpy(xclass, name);
+ cluc(xclass);
+
+ if( doatexit ){
+#if HAVE_ATEXIT
+ XPAAtExit();
+#else
+ fprintf(stderr, "ERROR: atexit not available\n");
+ exit(1);
+#endif
+ }
+
+ if( x ){
+#if HAVE_XT
+ top = XtAppInitialize(&appcontext, "Server", NULL, 0,
+ &argc, argv, NULL, NULL, 0);
+ XtVaSetValues(top, XtNwidth, (XtArgVal)10, XtNheight, (XtArgVal)10,
+ XtNmappedWhenManaged, (XtArgVal)False, NULL);
+#else
+ fprintf(stderr, "Xt is not available ...\n");
+ got = 1;
+ goto done;
+#endif
+ }
+
+ strcpy(tbuf, name);
+ snprintf(tbuf2, SZ_LINE, "help for %s", tbuf);
+ xpa1 = XPANew(xclass, tbuf, tbuf2,
+ send_cb, (void *)"send1", mode,
+ receive_cb, (void *)"receive1", mode);
+ if( xpa1 == NULL ){
+ fprintf(stderr, "ERROR: could not init xpa1\n");
+ }
+ else{
+ fprintf(stdout, "%s using method: %s\n", xpa_name(xpa1), xpa_method(xpa1));
+ }
+
+ if( !doone ){
+ snprintf(tbuf, SZ_LINE, "%s1", name);
+ snprintf(tbuf2, SZ_LINE, "help for %s", tbuf);
+ xpa1a = XPANew(xclass, tbuf, tbuf2,
+ send_cb, (void *)"send1a", mode,
+ receive_cb, (void *)"receive1a", mode);
+ if( xpa1a == NULL ){
+ fprintf(stderr, "ERROR: could not init xpa1a\n");
+ }
+ else{
+ fprintf(stdout, "%s using method: %s\n",
+ xpa_name(xpa1a), xpa_method(xpa1a));
+ }
+
+ snprintf(tbuf, SZ_LINE, "c_%s", name);
+ xpa2 = XPACmdNew(xclass, tbuf);
+ if( xpa2 == NULL ){
+ fprintf(stderr, "ERROR: could not init xpa2\n");
+ }
+ else{
+ XPACmdAdd(xpa2, "cmd2", "and help for cmd2",
+ send_cb, (void *)"cmd2", mode,
+ receive_cb, (void *)"cmd2", mode);
+ XPACmdAdd(xpa2, "cmd1 xx yy", "help for cmd1 xx yy",
+ send_cb, (void *)"cmd1 xx yy", mode,
+ receive_cb, (void *)"cmd1 xx yy", mode);
+ XPACmdAdd(xpa2, "cmd1 xx", "help for cmd1 xx",
+ send_cb, (void *)"cmd1 xx", mode,
+ receive_cb, (void *)"cmd1 xx", mode);
+ XPACmdAdd(xpa2, "cmd1", NULL,
+ send_cb, (void *)"cmd1", mode,
+ receive_cb, (void *)"cmd1", mode);
+ fprintf(stdout, "%s using method: %s\n",
+ xpa_name(xpa2), xpa_method(xpa2));
+ }
+
+ snprintf(tbuf, SZ_LINE, "i_%s", name);
+ xpa3 = XPAInfoNew(xclass, tbuf, info_cb, (void *)"info1", mode);
+ if( xpa3 == NULL ){
+ fprintf(stderr, "ERROR: could not init xpa3\n");
+ }
+ else{
+ fprintf(stdout, "%s using method: %s\n", xpa_name(xpa3), xpa_method(xpa3));
+ }
+ }
+
+ if( *cmd != '\0' ){
+ fprintf(stdout, "starting bkgd process: %s", cmd);
+ system(cmd);
+ }
+
+ /* delay if necessary */
+ if( delay ){
+ fprintf(stdout, "starting delay of %d seconds ...", delay);
+ XPASleep(delay*1000);
+ fprintf(stdout, " done\n");
+ }
+ fflush(stdout);
+ fflush(stderr);
+
+ /* connect to proxy, if necessary */
+ if( proxy ){
+ if( XPARemote(xpa1, proxy, "+", "proxy=true") < 0 ){
+ fprintf(stderr, "ERROR: could not connect to proxy: %s\n", proxy);
+ }
+ }
+
+ if( x ){
+#if HAVE_XT
+ fprintf(stdout, "\nEntering Xt loop ...\n");
+ XPAXtAddInput(appcontext, NULL);
+ XtRealizeWidget(top);
+ XtAppMainLoop(appcontext);
+#else
+ fprintf(stderr, "Xt is not available ...\n");
+ got = 1;
+ goto done;
+#endif
+ }
+ else{
+ fprintf(stdout, "\nEntering select loop ...\n");
+ if( !doatexit ){
+ XPAMainLoop();
+ } else {
+ while( !please_exit )
+ if( !XPAPoll(-1, 100) ) please_exit=1;
+ }
+ goto done;
+ }
+
+done:
+ if( !doatexit ){
+ XPAFree(xpa1);
+ if( !doone ){
+ XPAFree(xpa1a);
+ XPAFree(xpa2);
+ XPAFree(xpa3);
+ }
+ }
+
+ /* make valgrind happy */
+ XPACleanup();
+ if( save_buf ) xfree(save_buf);
+ exit(got);
+}