about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2013-11-24 22:07:20 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2013-11-24 22:07:20 +0000
commit7903da13d060ae1237340ace03ce6761bd8ab1f8 (patch)
treef9ff39f8502d7526c8a1210337824130a5411f72
parentdc94d059b5b4301d9d8d37b5a050fe74da6a76cf (diff)
downloadnetpbm-mirror-7903da13d060ae1237340ace03ce6761bd8ab1f8.tar.gz
netpbm-mirror-7903da13d060ae1237340ace03ce6761bd8ab1f8.tar.xz
netpbm-mirror-7903da13d060ae1237340ace03ce6761bd8ab1f8.zip
Release 10.64.04
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@2038 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/other/pnmtops.c73
-rw-r--r--doc/HISTORY18
-rw-r--r--version.mk2
3 files changed, 81 insertions, 12 deletions
diff --git a/converter/other/pnmtops.c b/converter/other/pnmtops.c
index 1d0a44f7..e1f2d185 100644
--- a/converter/other/pnmtops.c
+++ b/converter/other/pnmtops.c
@@ -42,6 +42,8 @@
 #include <unistd.h>
 #include <assert.h>
 #include <string.h>
+#include <errno.h>
+#include <signal.h>
 #ifndef NOFLATE
 #include <zlib.h>
 #endif
@@ -52,6 +54,37 @@
 #include "shhopt.h"
 #include "nstring.h"
 
+
+
+static void
+setSignals() {
+/*----------------------------------------------------------------------------
+   Set up the process-global signal-related state.
+
+   Note that we can't rely on defaults, because much of this is inherited
+   from the process that forked and exec'ed this program.
+-----------------------------------------------------------------------------*/
+    /* See waitForChildren() for why we do this to SIGCHLD */
+
+    struct sigaction sigchldAction;
+    int rc;
+    sigset_t emptySet;
+
+    sigemptyset(&emptySet);
+
+    sigchldAction.sa_handler = SIG_DFL;
+    sigchldAction.sa_mask = emptySet;
+    sigchldAction.sa_flags = SA_NOCLDSTOP;
+
+    rc = sigaction(SIGCHLD, &sigchldAction, NULL);
+
+    if (rc != 0)
+        pm_error("sigaction() to set up signal environment failed, "
+                 "errno = %d (%s)", errno, strerror(errno));
+}
+
+
+
 struct cmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
@@ -351,6 +384,17 @@ writeFile(const unsigned char * const buffer,
 
 
 
+static void
+writeFileChar(const char * const buffer,
+              size_t       const writeCt,
+              const char * const name,
+              FILE *       const ofP) {
+
+    writeFile((const unsigned char *)buffer, writeCt, name, ofP);
+}
+
+
+
 #define MAX_FILTER_CT 10
     /* The maximum number of filters this code is capable of applying */
 
@@ -558,8 +602,10 @@ rlePutBuffer (unsigned int    const repeat,
     if (repeat) {
         fputc(257 - count,  fP);
         fputc(repeatitem, fP);
-    } else
+    } else {
+        fputc(count - 1, fP);
         writeFile(itembuf, count, "rlePutBuffer", fP);
+    }
 }
 
 
@@ -736,7 +782,8 @@ ascii85Filter(FILE *          const ifP,
             ++count;
 
             if (value == 0 && count == 4) {
-                putchar('z');  /* Ascii85 encoding z exception */
+                writeFileChar("z", 1, "ASCII 85 filter", ofP);
+                    /* Ascii85 encoding z exception */
                 ++outcount;
                 count = 0;
             } else if (count == 4) {
@@ -746,15 +793,14 @@ ascii85Filter(FILE *          const ifP,
                 outbuff[1] = value % 85 + 33;
                 outbuff[0] = value / 85 + 33;
 
-                writeFile((const unsigned char *)outbuff, count + 1,
-                          "ASCII 85 filter", ofP);
+                writeFileChar(outbuff, count + 1, "ASCII 85 filter", ofP);
 
                 count = value = 0;
                 outcount += 5; 
             }
 
             if (outcount > 75) {
-                putchar('\n');
+                writeFileChar("\n", 1, "ASCII 85 filter", ofP);
                 outcount = 0;
             }
         }
@@ -770,8 +816,7 @@ ascii85Filter(FILE *          const ifP,
         outbuff[0] = value / 85 + 33;
         outbuff[count + 1] = '\n';
 
-        writeFile((const unsigned char *)outbuff, count + 2,
-                  "ASCII 85 filter", ofP);
+        writeFileChar(outbuff, count + 2, "ASCII 85 filter", ofP);
     }
 
     fclose(ifP);
@@ -966,6 +1011,15 @@ waitForChildren(const pid_t * const pidList) {
    Wait for all child processes with PIDs in pidList[] to exit.
    In pidList[], end-of-list is marked with a special zero value.
 -----------------------------------------------------------------------------*/
+    /* There's an odd behavior in Unix such that if you have set the
+       action for SIGCHLD to ignore the signal (even though ignoring the
+       signal is the default), the process' children do not become
+       zombies.  Consequently, waitpid() always fails with ECHILD - but
+       nonetheless waits for the child to exit.
+    
+       We expect the process not to have the action for SIGCHLD set that
+       way.
+    */
     unsigned int i;
 
     for (i = 0; pidList[i]; ++i) {
@@ -977,7 +1031,8 @@ waitForChildren(const pid_t * const pidList) {
 
         rc = waitpid(pidList[i], &status, 0);
         if (rc == -1)
-            pm_error ("waitpid() for child %u failed", i);
+            pm_error ("waitpid() for child %u failed, errno=%d (%s)",
+                      i, errno, strerror(errno));
         else if (status != EXIT_SUCCESS)
             pm_error ("Child process %u terminated abnormally", i);
     }
@@ -2011,6 +2066,8 @@ main(int argc, const char * argv[]) {
 
     pm_proginit(&argc, argv);
 
+    setSignals();
+
     parseCommandLine(argc, argv, &cmdline);
 
     verbose = cmdline.verbose;
diff --git a/doc/HISTORY b/doc/HISTORY
index d437ff14..5e877d4a 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,15 +4,27 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
+13.11.24 BJH  Release 10.64.04
+
+              pnmtops: Fix bug: wrong output with -ascii85.  Introduced in
+              10.63 (June 2013).
+
+              pnmtops: Fix bug: wrong output with -rle.  Introduced in
+              10.63 (June 2013).
+
+              pnmtops: Fix bug: fails with message about waitpid() failing
+              if invoked with SIGCHLD ignored.  Introduced in 10.56
+              (September 2011).
+
 13.11.12 BJH  Release 10.64.03
 
-              Fix bug: Pnmtops closes Standard Error.  Introduced in
+              pnmtops: Fix bug: closes Standard Error.  Introduced in
               10.64.02 (today).
 
 13.11.12 BJH  Release 10.64.02
 
-              Fix bug: program hangs if it inherits lots of open files.
-              Introduced in 10.56 (September 2011).
+              pnmtops: Fix bug: program hangs if it inherits lots of open
+              files.  Introduced in 10.56 (September 2011).
 
               Fix compile failure on system such as OpenBSD that don't have
               SIGWINCH and SIGIO.  Broken since 10.49 (December 2009).
diff --git a/version.mk b/version.mk
index 51762910..142da613 100644
--- a/version.mk
+++ b/version.mk
@@ -1,4 +1,4 @@
 NETPBM_MAJOR_RELEASE = 10
 NETPBM_MINOR_RELEASE = 64
-NETPBM_POINT_RELEASE = 3
+NETPBM_POINT_RELEASE = 4