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 17:11:33.000000000 +0900
@@ -36,6 +36,12 @@
 #include "conf.h"
 #include "main.h"
 
+#include <unistd.h>
+#include <sys/types.h> /* creat */
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/wait.h> /* wait */
+
 GList           *pagelist = NULL;
 int		 page_nr = 0,
 		 timer_id = 0,
@@ -144,19 +150,23 @@
   char *bff, *p = NULL, **names;
   gboolean first = TRUE;
   int s, t, bffbeg = 0;
+  int pfd[2]; /* pipe */
+  int pid_i, pid_j; /* two children*/
+  int wait_i, wait_j; /* waiting pid */
+  char cmd[3][20];
 
   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);
+      sprintf(cmd[0], "%s", "unzip");
+      sprintf(cmd[1], "%s", "-l");
+      sprintf(cmd[2], "ZIP command:");
       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);
+      sprintf(cmd[0], "%s", "unrar");
+      sprintf(cmd[1], "%s", "v");
+      sprintf(cmd[2], "RAR command:");
       break;
     default:			// Patch from Ilja Pyykkonen 2005/09/04
       p = g_strdup_printf(_("Cannot open file '%s': unknown file type"), 
@@ -165,7 +175,77 @@
       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]);
+    if (debug) fprintf(stderr, "%s %s %s %s\n", 
+		cmd[2], cmd[0], cmd[1], pref.lastbook);
+    execlp(cmd[0], cmd[0], cmd[1], pref.lastbook, 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 */
+      int new_fd;
+
+      close(pfd[1]);
+      close(0); /* close stdin */
+      if (dup(pfd[0]) != 0) {
+        fprintf(stderr, "Dup failure\n");
+        return;
+      }
+      close(pfd[0]);
+      /* create tmpf */
+      if ((new_fd = creat(tmpf, 00600)) == -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(new_fd) != 1) {
+        fprintf(stderr, "Dup failure\n");
+        return;
+      }
+      close(new_fd);
+      execlp("grep", "grep", all_extensions, NULL);
+      return; /* should not reach here */
+    }
+    else { /* parent */
+      close(pfd[0]);
+      close(pfd[1]);
+      /* wait children */
+      wait_i = wait(0);
+      wait_j = wait(0);
+     if (!((wait_i == pid_i && wait_j == pid_j) || 
+	(wait_i == pid_j && wait_j == pid_i))) {
+        fprintf(stderr, "Forked children status strange\n");
+        return;
+     }
+
+    }
+  }
+  bff = NULL;
 
   if (!g_file_test(tmpf, G_FILE_TEST_EXISTS)) {
     printf(_("Cannot open temporary file %s\n"), tmpf);
@@ -236,7 +316,10 @@
 {
   char *p, *bff = NULL, *esc;
   int len, i, idx = 0;
-  
+
+  int pid;
+  int fd;
+
   p = (char *)g_list_nth_data(pagelist, nr);
   len = strlen(p);
   esc = g_malloc(2*len + 1);
@@ -254,21 +337,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 ((fd = creat(tmpf, 00600)) == -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(fd) != 1) {
+        fprintf(stderr, "Dup failure\n");
+        return;
+      }
+      close(fd);
+      switch(pref.booktype) {
+        case RAR_FILE:
+          execlp("unrar",
+			"unrar", "p", "-ierr", "-clr", "--",
+			pref.lastbook, p, NULL);
+          return; /* should not reach here */
+        case ZIP_FILE:
+          execlp("unzip",
+			"unzip", "-p", "-C",
+			pref.lastbook, p, NULL);
+          return; /* should not return here */
+      }
+      return; /* should not reach here */
+    default: /* parent */
+      waitpid(pid, 0, 0);
   }
-  system(bff);
+
+  bff = NULL;
   g_free(bff);
   g_free(esc);