gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 89ffafd7: Library (pdf.h): using fork+execl to


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 89ffafd7: Library (pdf.h): using fork+execl to return control back to Gnuastro
Date: Fri, 17 May 2024 16:03:49 -0400 (EDT)

branch: master
commit 89ffafd7fa67da33e567a544a0f44a606c00a192
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (pdf.h): using fork+execl to return control back to Gnuastro
    
    Until now, we were calling Ghostscript through the 'execl' function (which
    was itself a recent replace from 'system()' in Commit 61fbd358). But
    through 'execl' Gnuastro gives its full control to Ghostscript; not
    allowing Gnuastro to clean up afterwards (in particular, the EPS file!).
    
    With this commit, 'execl' is now only called on a child process of
    Gnuastro. Therefore it only closes the child, not the parent and once it is
    finished, Gnuastro is able to complete its cleaning up.
    
    This issue (that the EPS file was not getting deleted was reported by
    Sepideh Eskandarlou.
---
 lib/pdf.c | 40 ++++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/lib/pdf.c b/lib/pdf.c
index 7b0d2558..497cafbf 100644
--- a/lib/pdf.c
+++ b/lib/pdf.c
@@ -28,6 +28,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/wait.h>
 
 #include <gnuastro/eps.h>
 #include <gnuastro/pdf.h>
@@ -103,6 +104,8 @@ gal_pdf_write(gal_data_t *in, char *filename, float 
widthincm,
               uint32_t borderwidth, uint8_t bordercolor,
               int dontoptimize, gal_data_t *marks)
 {
+  pid_t pid;
+  int childstat=0;
   size_t w_h_in_pt[2];
   char *device, *devwp, *devhp, *devopt;
   char *epsname=gal_checkset_malloc_cat(filename, ".ps");
@@ -129,16 +132,33 @@ gal_pdf_write(gal_data_t *in, char *filename, float 
widthincm,
     error(EXIT_FAILURE, 0, "%s: asprintf allocation error", __func__);
 
   /* Run Ghostscript (if the command changes, also change the command in
-     the error message). */
-  if( execl(PATH_GHOSTSCRIPT, "gs", "-q", "-o", filename, devopt,
-            devwp, devhp, "-dPDFFitPage", epsname, (char *)0) )
-    error(EXIT_FAILURE, 0, "the Ghostscript command (printed after "
-          "this message) to convert the EPS file to PDF was not "
-          "successful! The EPS file ('%s') is left if you want to "
-          "convert it through any other means (for example the "
-          "'epspdf' program). The Ghostscript command was: %s "
-          "-q -o %s %s %s %s -dPDFFitPage %s", PATH_GHOSTSCRIPT,
-          epsname, filename, devopt, devwp, devhp, epsname);
+     the error message). We are not using the 'system()' command because
+     that call '/bin/sh', which may not always be usable within the running
+     environment; see https://savannah.nongnu.org/bugs/?65677.
+
+     For a very nice summary on fork/execl, see the first answer in the
+     link below.
+     
https://stackoverflow.com/questions/4204915/please-explain-the-exec-function-and-its-family
+
+     In summary: the child gets 'pid=0' and the parent gets the process ID
+     of the child. The parent then waits for the child to finish and
+     continues. */
+  pid=fork();
+  if(pid<0) error(EXIT_FAILURE, 0, "%s: could not build fork", __func__);
+  if(pid==0)
+    execl(PATH_GHOSTSCRIPT, "gs", "-q", "-o", filename, devopt,
+          devwp, devhp, "-dPDFFitPage", epsname, NULL);
+  else waitpid(pid, &childstat, 0);
+  if(childstat)
+    error(EXIT_FAILURE, 0, "the Ghostscript command (printed at the "
+          "end of this message) to convert/compile the EPS file (made "
+          "by Gnuastro) to PDF was not successful (Ghostscript returned "
+          "with status %d; its error message is shown above)! The EPS "
+          "file ('%s') is left if you want to convert it through any "
+          "other means (for example the 'epspdf' program). The "
+          "Ghostscript command was: %s -q -o %s %s %s %s -dPDFFitPage "
+          "%s", childstat, epsname, PATH_GHOSTSCRIPT, filename, devopt,
+          devwp, devhp, epsname);
 
   /* Delete the EPS file. */
   errno=0;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]