xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

external.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 - 2011 Thomas Schmitt
3  *
4  * This file is part of the libisofs project; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License version 2
6  * or later as published by the Free Software Foundation.
7  * See COPYING file for details.
8  *
9  * It implements a filter facility which can pipe a IsoStream into an external
10  * process, read its output and forward it as IsoStream output to an IsoFile.
11  * The external processes get started according to an IsoExternalFilterCommand
12  * which is described in libisofs.h.
13  *
14  */
15 
16 #ifdef HAVE_CONFIG_H
17 #include "../config.h"
18 #endif
19 
20 #include "../libisofs.h"
21 #include "../filter.h"
22 #include "../fsource.h"
23 #include "../stream.h"
24 
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <sys/wait.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <string.h>
34 
35 #ifdef Libisofs_external_filters_selecT
36 #include <sys/select.h>
37 #endif
38 
39 /*
40  * A filter that starts an external process and uses its stdin and stdout
41  * for classical pipe filtering.
42  */
43 
44 /* IMPORTANT: Any change must be reflected by extf_clone_stream() */
45 /*
46  * Individual runtime properties exist only as long as the stream is opened.
47  */
48 typedef struct
49 {
50  int send_fd;
51  int recv_fd;
52  pid_t pid;
53  off_t in_counter;
54  int in_eof;
55  off_t out_counter;
56  int out_eof;
57  uint8_t pipebuf[2048]; /* buffers in case of EAGAIN on write() */
60 
61 
62 static
63 int extf_running_new(ExternalFilterRuntime **running, int send_fd, int recv_fd,
64  pid_t child_pid, int flag)
65 {
67  *running = o = calloc(sizeof(ExternalFilterRuntime), 1);
68  if (o == NULL) {
69  return ISO_OUT_OF_MEM;
70  }
71  o->send_fd = send_fd;
72  o->recv_fd = recv_fd;
73  o->pid = child_pid;
74  o->in_counter = 0;
75  o->in_eof = 0;
76  o->out_counter = 0;
77  o->out_eof = 0;
78  memset(o->pipebuf, 0, sizeof(o->pipebuf));
79  o->pipebuf_fill = 0;
80  return 1;
81 }
82 
83 
84 /*
85  * The data payload of an individual IsoStream from External Filter
86  */
87 typedef struct
88 {
89  ino_t id;
90 
92 
94 
95  off_t size; /* -1 means that the size is unknown yet */
96 
97  ExternalFilterRuntime *running; /* is non-NULL when open */
98 
100 
101 
102 /* Each individual ExternalFilterStreamData needs a unique id number. */
103 /* >>> This is very suboptimal:
104  The counter can rollover.
105 */
106 static ino_t extf_ino_id = 0;
107 
108 
109 /* <<< */
110 static int print_fd= 0;
111 
112 
113 /*
114  * Methods for the IsoStreamIface of an External Filter object.
115  */
116 
117 
118 /*
119  * @param flag bit0= original stream is not open
120  */
121 static
122 int extf_stream_close_flag(IsoStream *stream, int flag)
123 {
124  int ret, status;
126 
127  if (stream == NULL) {
128  return ISO_NULL_POINTER;
129  }
130  data = stream->data;
131 
132  if (data->running == NULL) {
133  return 1;
134  }
135 
136  /* <<< */
137  if (print_fd) {
138  fprintf(stderr, "libisofs_DEBUG: filter close in = %d , ic= %.f\n",
139  data->running->recv_fd, (double) data->running->in_counter);
140  fprintf(stderr, "libisofs_DEBUG: filter close out = %d , oc= %.f\n",
141  data->running->send_fd, (double) data->running->out_counter);
142  }
143 
144  if(data->running->recv_fd != -1)
145  close(data->running->recv_fd);
146  if(data->running->send_fd != -1)
147  close(data->running->send_fd);
148 
149  ret = waitpid(data->running->pid, &status, WNOHANG);
150  if (ret == 0 && data->running->pid != 0) {
151  kill(data->running->pid, SIGKILL);
152  waitpid(data->running->pid, &status, 0);
153  }
154  free(data->running);
155  data->running = NULL;
156  if (flag & 1)
157  return 1;
158  return iso_stream_close(data->orig);
159 }
160 
161 
162 static
164 {
165  return extf_stream_close_flag(stream, 0);
166 }
167 
168 
169 /*
170  * @param flag bit0= do not run .get_size() if size is < 0
171  */
172 static
173 int extf_stream_open_flag(IsoStream *stream, int flag)
174 {
176  ExternalFilterRuntime *running = NULL;
177  pid_t child_pid;
178  int send_pipe[2], recv_pipe[2], ret, stream_open = 0;
179 
180  send_pipe[0] = send_pipe[1] = recv_pipe[0] = recv_pipe[1] = -1;
181 
182  if (stream == NULL) {
183  return ISO_NULL_POINTER;
184  }
185  data = (ExternalFilterStreamData*)stream->data;
186  if (data->running != NULL) {
188  }
189  if (data->size < 0 && !(flag & 1)) {
190  /* Do the size determination run now, so that the size gets cached
191  and .get_size() will not fail on an opened stream.
192  */
193  stream->class->get_size(stream);
194  }
195 
196  ret = pipe(send_pipe);
197  if (ret == -1) {
198  ret = ISO_OUT_OF_MEM;
199  goto parent_failed;
200  }
201  ret = pipe(recv_pipe);
202  if (ret == -1) {
203  ret = ISO_OUT_OF_MEM;
204  goto parent_failed;
205  }
206 
207  child_pid= fork();
208  if (child_pid == -1) {
209  ret = ISO_DATA_SOURCE_FATAL;
210  goto parent_failed;
211  }
212 
213  if (child_pid != 0) {
214  /* parent */
215  ret = extf_running_new(&running, send_pipe[1], recv_pipe[0], child_pid,
216  0);
217  if (ret < 0) {
218  goto parent_failed;
219  }
220  data->running = running;
221 
222  /* <<< */
223  if (print_fd) {
224  fprintf(stderr, "libisofs_DEBUG: filter parent in = %d\n",
225  data->running->recv_fd);
226  fprintf(stderr, "libisofs_DEBUG: filter parent out = %d\n",
227  data->running->send_fd);
228  }
229 
230  /* Give up the child-side pipe ends */
231  close(send_pipe[0]);
232  close(recv_pipe[1]);
233 
234  /* Open stream only after forking so that the child does not know
235  the pipe inlets of eventually underlying other filter streams.
236  They would stay open and prevent those underlying filter children
237  from seeing EOF at their input.
238  */
239  ret = iso_stream_open(data->orig);
240 
241 
242  /* <<< TEST <<<
243  ret= ISO_FILE_READ_ERROR;
244  */
245 
246  if (ret < 0) {
247  /* Dispose pipes and child */
248  extf_stream_close_flag(stream, 1);
249  return ret;
250  }
251  stream_open = 1;
252  /* Make filter outlet non-blocking */
253  ret = fcntl(recv_pipe[0], F_GETFL);
254  if (ret != -1) {
255  ret |= O_NONBLOCK;
256  fcntl(recv_pipe[0], F_SETFL, ret);
257  }
258  /* Make filter sink non-blocking */
259  ret = fcntl(send_pipe[1], F_GETFL);
260  if (ret != -1) {
261  ret |= O_NONBLOCK;
262  fcntl(send_pipe[1], F_SETFL, ret);
263  }
264  return 1;
265  }
266 
267  /* child */
268 
269  /* Give up the parent-side pipe ends */
270  close(send_pipe[1]);
271  close(recv_pipe[0]);
272 
273  /* attach pipe ends to stdin and stdout */;
274  close(0);
275  ret = dup2(send_pipe[0], 0);
276  if (ret == -1) {
277  goto child_failed;
278  }
279  close(1);
280  ret = dup2(recv_pipe[1], 1);
281  if (ret == -1) {
282  goto child_failed;
283  }
284 
285  /* <<< */
286  if (print_fd) {
287  fprintf(stderr, "libisofs_DEBUG: filter child in = %d\n",
288  send_pipe[0]);
289  fprintf(stderr, "libisofs_DEBUG: filter child out = %d\n",
290  recv_pipe[1]);
291  }
292 
293  /* Self conversion into external program */
294  execv(data->cmd->path, data->cmd->argv); /* should never come back */
295 
296 child_failed:;
297  fprintf(stderr,"--- execution of external filter command failed:\n");
298  fprintf(stderr," %s\n", data->cmd->path);
299  exit(127);
300 
301 parent_failed:;
302 
303  /* <<< */
304  if (print_fd) {
305  fprintf(stderr, "libisofs_DEBUG: FAILED : filter parent in = %d\n",
306  recv_pipe[0]);
307  fprintf(stderr, "libisofs_DEBUG: FAILED : filter parent out = %d\n",
308  send_pipe[1]);
309  }
310 
311  if (stream_open)
312  iso_stream_close(data->orig);
313  if(send_pipe[0] != -1)
314  close(send_pipe[0]);
315  if(send_pipe[1] != -1)
316  close(send_pipe[1]);
317  if(recv_pipe[0] != -1)
318  close(recv_pipe[0]);
319  if(recv_pipe[1] != -1)
320  close(recv_pipe[1]);
321  return ret;
322 }
323 
324 
325 static
327 {
328  return extf_stream_open_flag(stream, 0);
329 }
330 
331 
332 #ifdef Libisofs_external_filters_selecT
333 
334 /* Performance is weaker than with non-blocking i/o and usleep(). */
335 
336 static
337 int extf_wait_for_io(int fd_in, int fd_out, int microsec, int flag)
338 {
339  struct timeval wt;
340  fd_set rds,wts,exs;
341  int ready, fd_max;
342 
343  fd_max = fd_out;
344  if (fd_in > fd_out)
345  fd_max = fd_in;
346 
347  FD_ZERO(&rds);
348  FD_ZERO(&wts);
349  FD_ZERO(&exs);
350  if (fd_in >= 0) {
351  FD_SET(fd_in,&rds);
352  FD_SET(fd_in,&exs);
353  }
354  if (fd_out >= 0) {
355  FD_SET(fd_out,&rds);
356  FD_SET(fd_in,&exs);
357  }
358  wt.tv_sec = microsec/1000000;
359  wt.tv_usec = microsec%1000000;
360  ready = select(fd_max + 1, &rds, &wts, &exs, &wt);
361  if (ready <= 0)
362  return 0;
363  if (fd_in >= 0) {
364  if (FD_ISSET(fd_in, &rds))
365  return 1;
366  }
367  if (fd_out >= 0) {
368  if (FD_ISSET(fd_out, &rds))
369  return 2;
370  }
371  if (fd_in >= 0) {
372  if (FD_ISSET(fd_in, &exs))
373  return -1;
374  }
375  if (fd_out >= 0) {
376  if (FD_ISSET(fd_out, &exs))
377  return -2;
378  }
379  return(0);
380 }
381 
382 #endif /* Libisofs_external_filters_selecT */
383 
384 
385 static
386 int extf_stream_read(IsoStream *stream, void *buf, size_t desired)
387 {
388  int ret, blocking = 0;
390  ExternalFilterRuntime *running;
391  size_t fill = 0;
392 
393  if (stream == NULL) {
394  return ISO_NULL_POINTER;
395  }
396  data = stream->data;
397  running= data->running;
398  if (running == NULL) {
399  return ISO_FILE_NOT_OPENED;
400  }
401  if (running->out_eof) {
402  return 0;
403  }
404 
405  while (1) {
406  if (running->in_eof && !blocking) {
407  /* Make filter outlet blocking */
408  ret = fcntl(running->recv_fd, F_GETFL);
409  if (ret != -1) {
410  ret &= ~O_NONBLOCK;
411  fcntl(running->recv_fd, F_SETFL, ret);
412  }
413  blocking = 1;
414  }
415 
416  /* Try to read desired amount from filter */;
417  while (1) {
418  ret = read(running->recv_fd, ((char *) buf) + fill,
419  desired - fill);
420  if (ret < 0) {
421  if (errno == EAGAIN)
422  break;
423  return ISO_FILE_READ_ERROR;
424  }
425  fill += ret;
426  if (ret == 0) {
427  running->out_eof = 1;
428  }
429  if (ret == 0 || fill >= desired) {
430  running->out_counter += fill;
431  return fill;
432  }
433  }
434 
435  if (running->in_eof) {
436  usleep(1000); /* just in case it is still non-blocking */
437  continue;
438  }
439  if (running->pipebuf_fill) {
440  ret = running->pipebuf_fill;
441  running->pipebuf_fill = 0;
442  } else {
443  ret = iso_stream_read(data->orig, running->pipebuf,
444  sizeof(running->pipebuf));
445  if (ret > 0)
446  running->in_counter += ret;
447  }
448  if (ret < 0) {
449  running->in_eof = 1;
450  return ret;
451  }
452  if (ret == 0) {
453 
454  /* <<< */
455  if (print_fd) {
456  fprintf(stderr,
457  "libisofs_DEBUG: filter close out = %d , ic= %.f\n",
458  running->send_fd, (double) running->in_counter);
459  }
460 
461  running->in_eof = 1;
462  close(running->send_fd); /* Tell the filter: it is over */
463  running->send_fd = -1;
464  } else {
465  running->pipebuf_fill = ret;
466  ret = write(running->send_fd, running->pipebuf,
467  running->pipebuf_fill);
468  if (ret == -1) {
469  if (errno == EAGAIN) {
470 
471 #ifdef Libisofs_external_filters_selecT
472 
473  /* This select() based waiting saves 10 % CPU load but
474  needs 50 % more real time */
475 
476  ret = extf_wait_for_io(running->recv_fd, running->send_fd,
477  100000, 0);
478  if (ret < 0)
479  usleep(1000); /* To make sure sufficient laziness */
480 
481 #else
482 
483  /* No sleeping needs 90 % more CPU and saves 6 % time */
484  usleep(1000); /* go lazy because the filter is slow */
485 
486 #endif /* ! Libisofs_external_filters_selecT */
487 
488  continue;
489  }
490 
491  /* From the view of the caller it _is_ a read error */
492  running->in_eof = 1;
493  return ISO_FILE_READ_ERROR;
494  }
495  running->pipebuf_fill = 0;
496  }
497  }
498  return ISO_FILE_READ_ERROR; /* should never be hit */
499 }
500 
501 
502 static
504 {
505  int ret, ret_close;
506  off_t count = 0;
508  char buf[64 * 1024];
509  size_t bufsize = 64 * 1024;
510 
511  if (stream == NULL) {
512  return ISO_NULL_POINTER;
513  }
514  data = stream->data;
515 
516  if (data->size >= 0) {
517  return data->size;
518  }
519 
520  /* Run filter command and count output bytes */
521  ret = extf_stream_open_flag(stream, 1);
522  if (ret < 0) {
523  return ret;
524  }
525  while (1) {
526  ret = extf_stream_read(stream, buf, bufsize);
527  if (ret <= 0)
528  break;
529  count += ret;
530  }
531  ret_close = extf_stream_close(stream);
532  if (ret < 0)
533  return ret;
534  if (ret_close < 0)
535  return ret_close;
536 
537  data->size = count;
538  return count;
539 }
540 
541 
542 static
544 {
545  /* Only repeatable streams are accepted as orig */
546  return 1;
547 }
548 
549 
550 static
551 void extf_stream_get_id(IsoStream *stream, unsigned int *fs_id,
552  dev_t *dev_id, ino_t *ino_id)
553 {
555 
556  data = stream->data;
557  *fs_id = ISO_FILTER_FS_ID;
558  *dev_id = ISO_FILTER_EXTERNAL_DEV_ID;
559  *ino_id = data->id;
560 }
561 
562 
563 static
565 {
567 
568  if (stream == NULL) {
569  return;
570  }
571  data = stream->data;
572  if (data->running != NULL) {
573  extf_stream_close(stream);
574  }
575  iso_stream_unref(data->orig);
576  if (data->cmd->refcount > 0)
577  data->cmd->refcount--;
578  free(data);
579 }
580 
581 
582 static
584 {
585  /* By principle size is determined only once */
586  return 1;
587 }
588 
589 
590 static
592 {
594 
595  if (stream == NULL) {
596  return NULL;
597  }
598  data = stream->data;
599  return data->orig;
600 }
601 
602 static
603 int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
604 {
605  int ret;
606  IsoStream *new_input_stream, *stream;
607  ExternalFilterStreamData *stream_data, *old_stream_data;
608 
609  if (flag)
610  return ISO_STREAM_NO_CLONE; /* unknown option required */
611 
612  stream_data = calloc(1, sizeof(ExternalFilterStreamData));
613  if (stream_data == NULL)
614  return ISO_OUT_OF_MEM;
615  ret = iso_stream_clone_filter_common(old_stream, &stream,
616  &new_input_stream, 0);
617  if (ret < 0) {
618  free((char *) stream_data);
619  return ret;
620  }
621  old_stream_data = (ExternalFilterStreamData *) old_stream->data;
622  stream_data->id = ++extf_ino_id;
623  stream_data->orig = new_input_stream;
624  stream_data->cmd = old_stream_data->cmd;
625  stream_data->cmd->refcount++;
626  stream_data->size = old_stream_data->size;
627  stream_data->running = NULL;
628  stream->data = stream_data;
629  *new_stream = stream;
630  return ISO_SUCCESS;
631 }
632 
633 static
634 int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
635 /* Function is defined after definition of extf_stream_class */
636 
637 
639  4,
640  "extf",
650  extf_cmp_ino,
652 };
653 
654 
655 static
657 {
658  int i;
659  ExternalFilterStreamData *data1, *data2;
660  IsoExternalFilterCommand *cmd1, *cmd2;
661 
662  /* This function may rely on being called by iso_stream_cmp_ino()
663  only with s1, s2 which both point to it as their .cmp_ino() function.
664  It would be a programming error to let any other than extf_stream_class
665  point to extf_cmp_ino(). This fallback endangers transitivity of
666  iso_stream_cmp_ino().
667  */
668  if (s1->class != &extf_stream_class || s2->class != &extf_stream_class)
669  return iso_stream_cmp_ino(s1, s2, 1);
670 
671  data1 = (ExternalFilterStreamData*) s1->data;
672  data2 = (ExternalFilterStreamData*) s2->data;
673  cmd1 = data1->cmd;
674  cmd2 = data2->cmd;
675  if (cmd1 != cmd2) {
676  if (strcmp(cmd1->name, cmd2->name) != 0)
677  return strcmp(cmd1->name, cmd2->name);
678  if (strcmp(cmd1->path, cmd2->path) != 0)
679  return strcmp(cmd1->path, cmd2->path);
680  if (cmd1->argc != cmd2->argc)
681  return cmd1->argc < cmd2->argc ? -1 : 1;
682  for (i = 0; i < cmd1->argc; i++) {
683  if (strcmp(cmd1->argv[i], cmd2->argv[i]) != 0)
684  return strcmp(cmd1->argv[i], cmd2->argv[i]);
685  }
686  if (cmd1->behavior != cmd2->behavior)
687  return cmd1->behavior < cmd2->behavior ? -1 : 1;
688  if (strcmp(cmd1->suffix, cmd2->suffix) != 0)
689  return strcmp(cmd1->suffix, cmd2->suffix);
690  }
691 
692  /* Both streams apply the same treatment to their input streams */
693  return iso_stream_cmp_ino(data1->orig, data2->orig, 0);
694 }
695 
696 
697 /* ------------------------------------------------------------------------- */
698 
699 static
701 {
702  /* no data are allocated */;
703 }
704 
705 
706 /* To be called by iso_file_add_filter().
707  * The FilterContext input parameter is not furtherly needed for the
708  * emerging IsoStream.
709  */
710 static
712  IsoStream **filtered)
713 {
714  IsoStream *str;
717 
718  if (filter == NULL || original == NULL || filtered == NULL) {
719  return ISO_NULL_POINTER;
720  }
721  cmd = (IsoExternalFilterCommand *) filter->data;
722  if (cmd->refcount + 1 <= 0) {
723  return ISO_EXTF_TOO_OFTEN;
724  }
725 
726  str = malloc(sizeof(IsoStream));
727  if (str == NULL) {
728  return ISO_OUT_OF_MEM;
729  }
730  data = malloc(sizeof(ExternalFilterStreamData));
731  if (data == NULL) {
732  free(str);
733  return ISO_OUT_OF_MEM;
734  }
735 
736 
737  /* These data items are not owned by this filter object */
738  data->id = ++extf_ino_id;
739  data->orig = original;
740  data->cmd = cmd;
741  data->size = -1;
742  data->running = NULL;
743 
744  /* get reference to the source */
745  iso_stream_ref(data->orig);
746 
747  str->refcount = 1;
748  str->data = data;
749  str->class = &extf_stream_class;
750 
751  *filtered = str;
752 
753  cmd->refcount++;
754  return ISO_SUCCESS;
755 }
756 
757 
758 /* Produce a parameter object suitable for iso_file_add_filter().
759  * It may be disposed by free() after all those calls are made.
760  *
761  * This is an internal call of libisofs to be used by an API call that
762  * attaches an IsoExternalFilterCommand to one or more IsoFile objects.
763  * See libisofs.h for IsoExternalFilterCommand.
764  */
765 static
767  FilterContext **filter, int flag)
768 {
769  FilterContext *f;
770 
771  *filter = f = calloc(1, sizeof(FilterContext));
772  if (f == NULL) {
773  return ISO_OUT_OF_MEM;
774  }
775  f->refcount = 1;
776  f->version = 0;
777  f->data = cmd;
778  f->free = extf_filter_free;
780  return ISO_SUCCESS;
781 }
782 
783 
784 /*
785  * A function which adds a filter to an IsoFile shall create a temporary
786  * FilterContext by iso_extf_create_context(), use it in one or more calls
787  * of filter.c:iso_file_add_filter() and finally dispose it by free().
788  */
789 
791  int flag)
792 {
793  int ret;
794  FilterContext *f = NULL;
795  IsoStream *stream;
796  off_t original_size = 0, filtered_size = 0;
797 
798  if (cmd->behavior & (1 | 2 | 4)) {
799  original_size = iso_file_get_size(file);
800  if (original_size <= 0 ||
801  ((cmd->behavior & 4) && original_size <= 2048)) {
802  return 2;
803  }
804  }
805  ret = extf_create_context(cmd, &f, 0);
806  if (ret < 0) {
807  return ret;
808  }
809  ret = iso_file_add_filter(file, f, 0);
810  free(f);
811  if (ret < 0) {
812  return ret;
813  }
814  /* Run a full filter process getsize so that the size is cached */
815  stream = iso_file_get_stream(file);
816  filtered_size = iso_stream_get_size(stream);
817  if (filtered_size < 0) {
818  iso_file_remove_filter(file, 0);
819  return filtered_size;
820  }
821  if (((cmd->behavior & 2) && filtered_size >= original_size) ||
822  ((cmd->behavior & 4) && filtered_size / 2048 >= original_size / 2048)){
823  ret = iso_file_remove_filter(file, 0);
824  if (ret < 0) {
825  return ret;
826  }
827  return 2;
828  }
829  return ISO_SUCCESS;
830 }
831 
832 
834  IsoExternalFilterCommand **cmd, int flag)
835 {
837 
838  if (stream->class != &extf_stream_class)
839  return 0;
840  data = stream->data;
841  *cmd = data->cmd;
842  return 1;
843 }
844 
static int extf_stream_close_flag(IsoStream *stream, int flag)
Definition: external.c:122
static int extf_stream_is_repeatable(IsoStream *stream)
Definition: external.c:543
static void extf_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, ino_t *ino_id)
Definition: external.c:551
static int extf_stream_open_flag(IsoStream *stream, int flag)
Definition: external.c:173
static int extf_stream_read(IsoStream *stream, void *buf, size_t desired)
Definition: external.c:386
static int extf_stream_open(IsoStream *stream)
Definition: external.c:326
int iso_file_add_external_filter(IsoFile *file, IsoExternalFilterCommand *cmd, int flag)
Definition: external.c:790
static int extf_create_context(IsoExternalFilterCommand *cmd, FilterContext **filter, int flag)
Definition: external.c:766
static ino_t extf_ino_id
Definition: external.c:106
static void extf_stream_free(IsoStream *stream)
Definition: external.c:564
int iso_stream_get_external_filter(IsoStream *stream, IsoExternalFilterCommand **cmd, int flag)
Definition: external.c:833
static int extf_cmp_ino(IsoStream *s1, IsoStream *s2)
Definition: external.c:656
static int extf_stream_close(IsoStream *stream)
Definition: external.c:163
static void extf_filter_free(FilterContext *filter)
Definition: external.c:700
static off_t extf_stream_get_size(IsoStream *stream)
Definition: external.c:503
static int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
Definition: external.c:603
static IsoStream * extf_get_input_stream(IsoStream *stream, int flag)
Definition: external.c:591
static int extf_running_new(ExternalFilterRuntime **running, int send_fd, int recv_fd, pid_t child_pid, int flag)
Definition: external.c:63
static int extf_filter_get_filter(FilterContext *filter, IsoStream *original, IsoStream **filtered)
Definition: external.c:711
static int extf_update_size(IsoStream *stream)
Definition: external.c:583
IsoStreamIface extf_stream_class
Definition: external.c:638
static int print_fd
Definition: external.c:110
int iso_file_remove_filter(IsoFile *file, int flag)
Definition: filter.c:58
int iso_file_add_filter(IsoFile *file, FilterContext *filter, int flag)
Definition: filter.c:33
#define ISO_FILTER_EXTERNAL_DEV_ID
Definition: filter.h:23
#define ISO_FILTER_FS_ID
Definition: fsource.h:25
IsoStream * iso_file_get_stream(IsoFile *file)
Definition: node.c:1161
#define ISO_SUCCESS
Definition: libisofs.h:8719
#define ISO_STREAM_NO_CLONE
Definition: libisofs.h:9089
#define ISO_DATA_SOURCE_FATAL
Definition: libisofs.h:9277
off_t iso_file_get_size(IsoFile *file)
Definition: node.c:1144
int iso_stream_open(IsoStream *stream)
Definition: stream.c:798
#define ISO_FILE_NOT_OPENED
Definition: libisofs.h:8811
#define ISO_OUT_OF_MEM
Definition: libisofs.h:8745
off_t iso_stream_get_size(IsoStream *stream)
Definition: stream.c:810
#define ISO_EXTF_TOO_OFTEN
Definition: libisofs.h:8953
#define ISO_FILE_READ_ERROR
Definition: libisofs.h:8820
int iso_stream_read(IsoStream *stream, void *buf, size_t count)
Definition: stream.c:816
#define ISO_NULL_POINTER
Definition: libisofs.h:8742
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
Definition: stream.c:1042
void iso_stream_unref(IsoStream *stream)
Definition: stream.c:789
int iso_stream_close(IsoStream *stream)
Definition: stream.c:804
#define ISO_FILE_ALREADY_OPENED
Definition: libisofs.h:8796
void iso_stream_ref(IsoStream *stream)
Definition: stream.c:784
int iso_stream_clone_filter_common(IsoStream *old_stream, IsoStream **new_stream, IsoStream **new_input, int flag)
Definition: stream.c:1292
uint8_t pipebuf[2048]
Definition: external.c:57
IsoExternalFilterCommand * cmd
Definition: external.c:93
ExternalFilterRuntime * running
Definition: external.c:97
off_t(* get_size)(IsoStream *stream)
Definition: libisofs.h:1039
Definition: node.h:149
void(* free)(FilterContext *filter)
Definition: filter.h:60
int refcount
Definition: filter.h:36
int version
Definition: filter.h:35
int(* get_filter)(FilterContext *filter, IsoStream *original, IsoStream **filtered)
Definition: filter.h:53
void * data
Definition: filter.h:39
int refcount
Definition: libisofs.h:1186
void * data
Definition: libisofs.h:1187
IsoStreamIface * class
Definition: libisofs.h:1185