Bug 44098

Summary: PS/PDF thumbnails don't work, EINTR from select() when running gs
Product: [Unmaintained] kio Reporter: Jonathan Marten <jjm>
Component: kioslaveAssignee: Konqueror Bugs <konqueror-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: giovanni
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: unspecified   
OS: Other   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Patch as above, but unmangled

Description Jonathan Marten 2002-06-19 10:17:49 UTC
(*** This bug was imported into bugs.kde.org ***)

Package:kioslave
Severity:normal
Version:KDE 3.0.1

Previews for PostScript or PDF files don't appear in Konqueror when
the option is turned on.  The only debug message displayed is:

  kio_file: FileProtocol::stat details=2
  kio (KIOJob): error 4 Cannot create thumbnail for
         /home/jonm/public_html/sunpeak/ClassCodeItemTypeGuide.ps

The problem happens when running GS as a subprocess in
kdebase/kioslave/thumbnail/gscreator.cpp.  GS is started OK by the
child but when it exits the parent receives an EINTR from select()
before it has collected the child output - assuming that this is
because the child exiting has sent a SIGCLD.  It takes this as an
"error or timeout" leaves 'ok' as FALSE and the thumbnail create
fails.

Ignoring the EINTR and restarting the select() seems to fix the
problem.  But... I've only observed this problem on Solaris Linux
seems OK.  I don't know enough about possible variations in signal
handling between Unix variants to claim that this is a universal
solution so I've enabled it for SVR4 only.  Feel free to change that
if necessary...

Patch follows:

------------------------------------------------------------------
--- kdebase/kioslave/thumbnail/gscreator.cpp.origFri Jun 14 11:24:34 2002
+++ kdebase/kioslave/thumbnail/gscreator.cppWed Jun 19 10:16:02 2002
@@ -306 +309 @@
 #include <sys/select.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#ifdef SVR4
+#include <errno.h>
+#endif
 
 #include <qfile.h>
 #include <qimage.h>
@@ -1287 +13112 @@
                 tv.tv_sec = 5;
                 tv.tv_usec = 0;
                 if (select(output[0] + 1 &fds 0 0 &tv) <= 0)
-                    break; // error or timeout
+{
+#ifdef SVR4
+if (errno==EINTR) continue;
+#endif
+break; // error or timeout
+}
 
                 if (FD_ISSET(output[0] &fds))
                 {
@@ -1517 +1597 @@
         if (!ok) // error or timeout gs probably didn't exit yet
             kill(pid SIGTERM);
 
-        int status;
+        int status = 0;
         if (waitpid(pid &status 0) != pid || status != 0)
             ok = false;
     }

------------------------------------------------------------------

-- 
Jonathan Marten SCM Team Engineer          VSP Bracknell UK
jonathan.marten@uk.sun.com                  Sun Microsystems

"Progress is not expedited by frequent requests for progress reports"
Comment 1 Jonathan Marten 2003-06-11 09:11:43 UTC
Created attachment 1774 [details]
Patch as above, but unmangled

The problem still exists in KDE 3.1.2, and the same patch fixes it.
Patch file is attached, hopefully intact this time.
Comment 2 Dirk Mueller 2003-07-22 01:08:13 UTC
Subject: kdebase/kioslave/thumbnail

CVS commit by mueller: 

ignore EINTR in select(). Thanks for the patch. 
CCMAIL: 44098-done@bugs.kde.org


  M +6 -3      gscreator.cpp   1.17


--- kdebase/kioslave/thumbnail/gscreator.cpp  #1.16:1.17
@@ -64,4 +64,5 @@
 #include <sys/wait.h>
 #include <fcntl.h>
+#include <errno.h>
 
 #include <qfile.h>
@@ -233,6 +234,8 @@ bool GSCreator::create(const QString &pa
           tv.tv_sec = 20;
           tv.tv_usec = 0;
-          if (select(output[0] + 1, &fds, 0, 0, &tv) <= 0) 
+          if (select(output[0] + 1, &fds, 0, 0, &tv) <= 0) {
+            if ( errno == EINTR || errno == EAGAIN ) continue;
             break; // error or timeout
+          }
           if (FD_ISSET(output[0], &fds)) {
             count = read(output[0], data.data() + offset, 1024);
@@ -255,5 +258,5 @@ bool GSCreator::create(const QString &pa
     if (!ok) // error or timeout, gs probably didn't exit yet
       kill(pid, SIGTERM);
-    int status;
+    int status = 0;
     if (waitpid(pid, &status, 0) != pid || (status != 0  && status != 256) )
       ok = false;


Comment 3 Luís Pedro Coelho 2003-12-24 17:09:24 UTC
*** Bug 65133 has been marked as a duplicate of this bug. ***