[GRASS5] R_open_driver() after fork()

Glynn Clements glynn.clements at virgin.net
Thu Feb 13 06:08:52 EST 2003


Radim Blazek wrote:

> I have one problem: if module creates child process by fork(),
> it is impossible open driver by R_open_driver() in parent.

Are you calling R_open_driver() in both parent and child? That would
explain why the read() call hangs.

> In sync_driver() it hangs on read(). SIGALRM is recieved and dead()
> executed, but module doesn't continue in execution - still hanging on read(),
> until child is killed.

The timeout code relies upon signal() having the SysV semantics
(signals interrupt system calls); it won't work if signal() has the
BSD semantics (which is the case on Linux with glibc 2.x).

Using sigaction() (without SA_RESTART) works; try the attached patch.

However, I'm unsure as to the portability issues involved. E.g. 
signal() is specified by ANSI (but its semantics aren't well defined),
while sigaction() is POSIX. OTOH, the new r.mapcalc uses sigaction()
to catch SIGFPE, and no-one has complained about that yet (but that
doesn't really say much; we only get regular feedback for Linux and
MacOSX, and occasional feedback for (specific versions of) Cygwin,
Irix and Solaris).

-- 
Glynn Clements <glynn.clements at virgin.net>

-------------- next part --------------
--- src/libes/raster/io.c~	Tue Jan 29 20:27:17 2002
+++ src/libes/raster/io.c	Thu Feb 13 10:55:02 2003
@@ -459,10 +459,18 @@
     return 0;
 }
 
+#ifndef SA_ONESHOT
+# ifdef SA_RESETHAND
+#  define SA_ONESHOT SA_RESETHAND
+# else
+#  define SA_ONESHOT 0
+# endif
+#endif
+
 static int
 sync_driver(char *name)
 {
-    RETSIGTYPE (*sigalarm)(int);
+    struct sigaction act, oldact;
     int try;
     int count;
     unsigned char c;
@@ -477,7 +485,9 @@
  * try twice. first timeout is warning, second is fatal
  */
     count = 0;
-    sigalarm = signal(SIGALRM, dead);
+    act.sa_handler = dead;
+    act.sa_flags = SA_ONESHOT;
+    sigaction(SIGALRM, &act, &oldact);
     for (try = 0; try < 2; try++)
     {
         no_mon = 0;
@@ -499,7 +509,7 @@
                 count = 0;  /* start over */
         }
         alarm(0);
-        signal(SIGALRM, sigalarm);
+        sigaction(SIGALRM, &oldact, NULL);
         if (no_mon == 0)
             return 1;   /* ok! */
         if (try)
@@ -508,7 +518,7 @@
         fprintf (stderr, "Warning - no response from graphics monitor <%s>.\n",
             name);
         fprintf (stderr, "Check to see if the mouse is still active.\n");
-        signal(SIGALRM, dead);
+        sigaction(SIGALRM, &act, &oldact);
     }
     fprintf (stderr, "ERROR - no response from graphics monitor <%s>.\n",
         name);


More information about the grass-dev mailing list