--- 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);