GRASS Programmer's Manual  6.4.2(2012)
rem_io.c
Go to the documentation of this file.
00001 #include <grass/config.h>
00002 
00003 #ifdef HAVE_SOCKET
00004 
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <signal.h>
00008 #include <string.h>
00009 #include <unistd.h>
00010 #include <errno.h>
00011 
00012 #include <grass/gis.h>
00013 #include <grass/glocale.h>
00014 #include <grass/raster.h>
00015 #include <grass/graphics.h>
00016 
00017 #include "transport.h"
00018 #include "open.h"
00019 
00020 #define BUFFERSIZ   2048
00021 
00022 int _rfd, _wfd;
00023 int _quiet;
00024 
00025 int sync_driver(char *);
00026 
00027 static unsigned char outbuf[BUFFERSIZ];
00028 static int cursiz;
00029 static volatile int no_mon;
00030 
00031 static RETSIGTYPE dead(int);
00032 
00033 static int _get(char *buf, int n)
00034 {
00035     int x;
00036 
00037     while (n > 0) {
00038         x = read(_rfd, buf, n);
00039         if (x <= 0) {
00040             fprintf(stderr, _("ERROR %s from graphics driver.\n"),
00041                     x ? "reading" : "eof");
00042             exit(1);
00043         }
00044         n -= x;
00045         buf += x;
00046     }
00047 
00048     return 0;
00049 }
00050 
00051 static int flushout(void)
00052 {
00053     if (cursiz) {
00054         write(_wfd, outbuf, (size_t) cursiz);
00055         cursiz = 0;
00056     }
00057 
00058     return 0;
00059 }
00060 
00061 int _send_ident(int anint)
00062 {
00063     unsigned char achar;
00064 
00065     achar = anint;
00066 
00067     if ((cursiz + 2) >= BUFFERSIZ)
00068         flushout();
00069     outbuf[cursiz++] = COMMAND_ESC;
00070     outbuf[cursiz++] = achar;
00071 
00072     return 0;
00073 }
00074 
00075 int _send_char(const unsigned char *achar)
00076 {
00077     if ((cursiz + 2) >= BUFFERSIZ)
00078         flushout();
00079     outbuf[cursiz++] = *achar;
00080     if (*achar == COMMAND_ESC)
00081         outbuf[cursiz++] = 0;
00082 
00083     return 0;
00084 }
00085 
00086 int _send_char_array(int num, const unsigned char *achar)
00087 {
00088     while (num-- > 0)
00089         _send_char(achar++);
00090 
00091     return 0;
00092 }
00093 
00094 int _send_int_array(int num, const int *anint)
00095 {
00096     return _send_char_array(num * sizeof(int), (const unsigned char *)anint);
00097 }
00098 
00099 int _send_float_array(int num, const float *afloat)
00100 {
00101     return _send_char_array(num * sizeof(float),
00102                             (const unsigned char *)afloat);
00103 }
00104 
00105 int _send_int(const int *anint)
00106 {
00107     return _send_char_array(sizeof(int), (const unsigned char *)anint);
00108 }
00109 
00110 int _send_float(const float *afloat)
00111 {
00112     return _send_char_array(sizeof(float), (const unsigned char *)afloat);
00113 }
00114 
00115 int _send_text(const char *text)
00116 {
00117     return _send_char_array(1 + strlen(text), (const unsigned char *)text);
00118 }
00119 
00120 int _get_char(char *achar)
00121 {
00122     flushout();
00123     _get(achar, 1);
00124 
00125     return 0;
00126 }
00127 
00128 int _get_int(int *anint)
00129 {
00130     flushout();
00131     _get((char *)anint, sizeof(int));
00132 
00133     return 0;
00134 }
00135 
00136 int _get_float(float *afloat)
00137 {
00138     flushout();
00139     _get((char *)afloat, sizeof(float));
00140 
00141     return 0;
00142 }
00143 
00144 int _get_text(char *buf)
00145 {
00146     char *b;
00147 
00148     b = buf;
00149     do
00150         _get_char(b);
00151     while (*b++ != 0);
00152 
00153     return 0;
00154 }
00155 
00156 char *_get_text_2(void)
00157 {
00158     static char *buf;
00159     static int len;
00160     int i;
00161 
00162     for (i = 0;; i++) {
00163         if (i >= len) {
00164             len += 1000;
00165             buf = G_realloc(buf, len);
00166             if (!buf) {
00167                 fprintf(stderr, _("Unable to allocate memory\n"));
00168                 exit(1);
00169             }
00170         }
00171         _get_char(&buf[i]);
00172         if (!buf[i])
00173             break;
00174     }
00175 
00176     return buf;
00177 }
00178 
00179 int REM__open_quiet(void)
00180 {
00181     _quiet = 1;
00182 
00183     return 0;
00184 }
00185 
00186 int sync_driver(char *name)
00187 {
00188 #ifndef __MINGW32__
00189     RETSIGTYPE(*sigalarm) (int);
00190 #endif
00191     int try;
00192     int count;
00193     unsigned char c;
00194 
00195     _send_ident(BEGIN);
00196     flushout();
00197 
00198     /*
00199      * look for at least BEGIN_SYNC_COUNT zero bytes
00200      * then look for COMMAND_ESC
00201      *
00202      * try twice. first timeout is warning, second is fatal
00203      */
00204     count = 0;
00205 #ifndef __MINGW32__
00206     sigalarm = signal(SIGALRM, dead);
00207 #endif
00208     for (try = 0; try < 2; try++) {
00209         no_mon = 0;
00210 #ifndef __MINGW32__
00211         alarm(try ? 10 : 5);
00212 #endif
00213         while (no_mon == 0) {
00214             if (read(_rfd, &c, (size_t) 1) != 1) {
00215                 if (no_mon)
00216                     break;      /* from while */
00217                 fprintf(stderr, _("ERROR - eof from graphics monitor.\n"));
00218                 exit(-1);
00219             }
00220             if (c == 0)
00221                 count++;
00222             else if (c == COMMAND_ESC && count >= BEGIN_SYNC_COUNT)
00223                 break;
00224             else
00225                 count = 0;      /* start over */
00226         }
00227 #ifndef __MINGW32__
00228         alarm(0);
00229         signal(SIGALRM, sigalarm);
00230 #endif
00231         if (no_mon == 0)
00232             return 1;           /* ok! */
00233         if (try)
00234             break;
00235 
00236         fprintf(stderr,
00237                 _("Warning - no response from graphics monitor <%s>.\n"),
00238                 name);
00239         fprintf(stderr, _("Check to see if the mouse is still active.\n"));
00240 #ifndef __MINGW32__
00241         signal(SIGALRM, dead);
00242 #endif
00243     }
00244     fprintf(stderr, _("ERROR - no response from graphics monitor <%s>.\n"),
00245             name);
00246     exit(-1);
00247 }
00248 
00249 static RETSIGTYPE dead(int sig)
00250 {
00251     no_mon = 1;
00252 }
00253 
00254 void _hold_signals(int hold)
00255 {
00256     static RETSIGTYPE(*sigint) (int);
00257 
00258 #ifdef SIGQUIT
00259     static RETSIGTYPE(*sigquit) (int);
00260 #endif
00261 
00262     if (hold) {
00263         sigint = signal(SIGINT, SIG_IGN);
00264 #ifdef SIGQUIT
00265         sigquit = signal(SIGQUIT, SIG_IGN);
00266 #endif
00267     }
00268     else {
00269         signal(SIGINT, sigint);
00270 #ifdef SIGQUIT
00271         signal(SIGQUIT, sigquit);
00272 #endif
00273     }
00274 }
00275 
00289 void REM_stabilize(void)
00290 {
00291     char c;
00292 
00293     flushout();
00294     _send_ident(RESPOND);
00295     _get_char(&c);
00296 }
00297 
00298 void REM_kill_driver(void)
00299 {
00300     char dummy;
00301 
00302     _send_ident(GRAPH_CLOSE);
00303     flushout();
00304     read(_rfd, &dummy, 1);
00305     R_release_driver();
00306 }
00307 
00317 void REM_close_driver(void)
00318 {
00319     R_stabilize();
00320 
00321     close(_rfd);
00322     close(_wfd);
00323     _wfd = _rfd = -1;
00324 }
00325 
00326 void REM_release_driver(void)
00327 {
00328     close(_rfd);
00329     close(_wfd);
00330     _wfd = _rfd = -1;
00331 }
00332 
00333 #endif /* HAVE_SOCKET */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines