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