Blob Blame History Raw
--- cbrpager-0.9.16/src/global.c.filen	2008-05-23 14:53:51.000000000 +0900
+++ cbrpager-0.9.16/src/global.c	2008-05-23 23:03:45.000000000 +0900
@@ -36,6 +36,12 @@
 #include "conf.h"
 #include "main.h"
 
+#include <unistd.h>
+#include <sys/types.h> /* open */
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/wait.h> /* wait */
+
 GList           *pagelist = NULL;
 int		 page_nr = 0,
 		 timer_id = 0,
@@ -136,7 +142,6 @@
   return -1;
 }
 
-
 void
 start_show(void)
 {
@@ -144,19 +149,15 @@
   char *bff, *p = NULL, **names;
   gboolean first = TRUE;
   int s, t, bffbeg = 0;
+  int pfd[2]; /* pipe */
+  int pid_i, pid_j; /* two children*/
 
   if (debug) printf("%s\n", pref.lastbook);
 
   switch (pref.booktype = file_type_of(pref.lastbook)) {
     case ZIP_FILE:
-      bff = g_strdup_printf("unzip -l \"%s\" | grep \"%s\" > %s",
-		pref.lastbook, all_extensions, tmpf);
-      if (debug) printf("ZIP command: %s\n", bff);
       break;
     case RAR_FILE:
-      bff = g_strdup_printf("unrar v \"%s\" | grep \"%s\" > %s",
-		pref.lastbook, all_extensions, tmpf);
-      if (debug) printf("RAR command: %s\n", bff);
       break;
     default:			// Patch from Ilja Pyykkonen 2005/09/04
       p = g_strdup_printf(_("Cannot open file '%s': unknown file type"), 
@@ -165,7 +166,76 @@
       g_free(p);
       return;
   }
-  system(bff);
+
+  if(pipe(pfd) == -1) {
+    fprintf(stderr, "Creating pipe failed\n");
+    return;
+  }
+
+  pid_i = fork(); 
+  if (pid_i == -1) {
+    fprintf(stderr, "Forking failed\n");
+    return;
+  }
+  else if (pid_i == 0) { /* child 1: do unzip or unrar */
+    close(pfd[0]);
+    close(1); /* close stdout*/
+    if (dup(pfd[1]) != 1 ) {
+      fprintf(stderr, "Dup failure\n");
+      return;
+    }
+    close(pfd[1]);
+    switch(pref.booktype) {
+      case ZIP_FILE:
+        if (debug) fprintf(stderr, "ZIP command: unzip -l %s\n", 
+		pref.lastbook);
+        execlp("unzip", "unzip", "-l", pref.lastbook, (char *)NULL);
+        return; /* should not reach here */
+      case RAR_FILE:
+        if (debug) fprintf(stderr, "RAR command: unrar -v %s\n", 
+		pref.lastbook);
+        execlp("unrar", "unrar", "v", pref.lastbook, (char *)NULL);
+        return; /* should not reach here */
+    }
+  }
+  else {
+    pid_j = fork() ; 
+    if (pid_j == -1) {
+      fprintf(stderr, "Forking failed\n");
+      return;
+    }
+    else if (pid_j == 0) { /* child 2; do grep */
+      close(pfd[1]);
+      close(0); /* close stdin */
+      if (dup(pfd[0]) != 0) {
+        fprintf(stderr, "Dup failure\n");
+        return;
+      }
+      close(pfd[0]);
+      if ((tmpf_fd = open(tmpf, O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR)) == -1) {
+        p = g_strdup_printf(_("Cannot open file '%s'"), tmpf);
+        ok_dialog(_("File error"), p);
+        g_free(p);
+        return;
+      }
+      close(1); /* close stdout */
+      if (dup(tmpf_fd) != 1) {
+        fprintf(stderr, "Dup failure\n");
+        return;
+      }
+      close(tmpf_fd);
+      execlp("grep", "grep", all_extensions, (char *)NULL);
+      return; /* should not reach here */
+    }
+    else { /* parent */
+      close(pfd[0]);
+      close(pfd[1]);
+      /* wait children */
+      waitpid(pid_i, 0, 0);
+      waitpid(pid_j, 0, 0);
+    }
+  }
+  bff = NULL;
 
   if (!g_file_test(tmpf, G_FILE_TEST_EXISTS)) {
     printf(_("Cannot open temporary file %s\n"), tmpf);
@@ -236,7 +306,9 @@
 {
   char *p, *bff = NULL, *esc;
   int len, i, idx = 0;
-  
+
+  int pid;
+
   p = (char *)g_list_nth_data(pagelist, nr);
   len = strlen(p);
   esc = g_malloc(2*len + 1);
@@ -254,21 +326,42 @@
 
   printf(_("Requesting page %d/%d (%s)\n"), nr+1, g_list_length(pagelist), esc);
 
-  switch (pref.booktype) {
-    case RAR_FILE:
-      bff = g_strdup_printf("unrar p -ierr -clr -- \"%s\" \"%s\" > %s",
-		pref.lastbook,
-		p,
-		tmpf);
-      break;
-    case ZIP_FILE:
-      bff = g_strdup_printf("unzip -p -C \"%s\" \"%s\" > %s",
-                pref.lastbook,
-                p,
-                tmpf);
-      break;
+  pid = fork();
+  switch (pid) {
+    case -1:
+      fprintf(stderr, "Forking failed\n");
+      return;
+    case 0: /* child */
+      if ((tmpf_fd = open(tmpf, O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR)) == -1) {
+        p = g_strdup_printf(_("Cannot open file '%s'"), tmpf);
+        ok_dialog(_("File error"), p);
+        g_free(p);
+        return;
+      }
+      close(1); /* close stdout */
+      if (dup(tmpf_fd) != 1) {
+        fprintf(stderr, "Dup failure\n");
+        return;
+      }
+      close(tmpf_fd);
+      switch(pref.booktype) {
+        case RAR_FILE:
+          execlp("unrar",
+			"unrar", "p", "-ierr", "-clr", "--",
+			pref.lastbook, p, (char *)NULL);
+          return; /* should not reach here */
+        case ZIP_FILE:
+          execlp("unzip",
+			"unzip", "-p", "-C",
+			pref.lastbook, p, (char *)NULL);
+          return; /* should not reach here */
+      }
+      return; /* should not reach here */
+    default: /* parent */
+      waitpid(pid, 0, 0);
   }
-  system(bff);
+
+  bff = NULL;
   g_free(bff);
   g_free(esc);