(prog_stream_create): New function.
Creates a stream connected to the stdin or stdout of a given program.
Showing
2 changed files
with
123 additions
and
4 deletions
... | @@ -54,6 +54,8 @@ extern int decoder_stream_create __P ((stream_t *stream, stream_t iostream, | ... | @@ -54,6 +54,8 @@ extern int decoder_stream_create __P ((stream_t *stream, stream_t iostream, |
54 | const char *encoding)); | 54 | const char *encoding)); |
55 | extern int stdio_stream_create __P ((stream_t *stream, FILE* stdio, | 55 | extern int stdio_stream_create __P ((stream_t *stream, FILE* stdio, |
56 | int flags)); | 56 | int flags)); |
57 | extern int prog_stream_create __P ((stream_t *stream, char *progname, | ||
58 | int flags)); | ||
57 | 59 | ||
58 | extern void stream_destroy __P ((stream_t *, void *owner)); | 60 | extern void stream_destroy __P ((stream_t *, void *owner)); |
59 | 61 | ... | ... |
... | @@ -457,10 +457,7 @@ _file_open (stream_t stream) | ... | @@ -457,10 +457,7 @@ _file_open (stream_t stream) |
457 | 457 | ||
458 | fs->file = fdopen (fd, mode); | 458 | fs->file = fdopen (fd, mode); |
459 | if (fs->file == NULL) | 459 | if (fs->file == NULL) |
460 | { | 460 | return errno; |
461 | int ret = errno; | ||
462 | return ret; | ||
463 | } | ||
464 | 461 | ||
465 | return 0; | 462 | return 0; |
466 | } | 463 | } |
... | @@ -572,3 +569,123 @@ stdio_stream_create (stream_t *stream, FILE *file, int flags) | ... | @@ -572,3 +569,123 @@ stdio_stream_create (stream_t *stream, FILE *file, int flags) |
572 | return 0; | 569 | return 0; |
573 | } | 570 | } |
574 | 571 | ||
572 | static int | ||
573 | _prog_close (stream_t stream) | ||
574 | { | ||
575 | struct _file_stream *fs = stream_get_owner (stream); | ||
576 | int err = 0; | ||
577 | |||
578 | if (!stream) | ||
579 | return EINVAL; | ||
580 | |||
581 | if (fs->file) | ||
582 | { | ||
583 | int flags = 0; | ||
584 | |||
585 | stream_get_flags (stream, &flags); | ||
586 | |||
587 | if ((flags & MU_STREAM_NO_CLOSE) == 0) | ||
588 | { | ||
589 | if (pclose (fs->file) != 0) | ||
590 | err = errno; | ||
591 | } | ||
592 | |||
593 | fs->file = NULL; | ||
594 | } | ||
595 | return err; | ||
596 | } | ||
597 | |||
598 | static int | ||
599 | _prog_open (stream_t stream) | ||
600 | { | ||
601 | struct _file_stream *fs = stream_get_owner (stream); | ||
602 | const char *mode; | ||
603 | int flags = 0; | ||
604 | |||
605 | if (!fs || !fs->filename) | ||
606 | return EINVAL; | ||
607 | |||
608 | if (fs->file) | ||
609 | { | ||
610 | pclose (fs->file); | ||
611 | fs->file = NULL; | ||
612 | } | ||
613 | |||
614 | stream_get_flags(stream, &flags); | ||
615 | |||
616 | if (flags & MU_STREAM_APPEND) | ||
617 | mode = "w"; | ||
618 | else if (flags & MU_STREAM_READ) | ||
619 | mode = "r"; | ||
620 | else if (flags & MU_STREAM_WRITE) | ||
621 | mode = "w"; | ||
622 | else /* Default readonly. */ | ||
623 | mode = "r"; | ||
624 | |||
625 | fs->file = popen (fs->filename, mode); | ||
626 | if (!fs->file) | ||
627 | return errno; | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | int | ||
633 | prog_stream_create (stream_t *stream, char *progname, int flags) | ||
634 | { | ||
635 | struct _file_stream *fs; | ||
636 | int ret; | ||
637 | |||
638 | if (stream == NULL) | ||
639 | return EINVAL; | ||
640 | |||
641 | if (progname == NULL | ||
642 | || (flags & MU_STREAM_RDWR) | ||
643 | || (flags & (MU_STREAM_READ|MU_STREAM_WRITE)) == | ||
644 | (MU_STREAM_READ|MU_STREAM_WRITE)) | ||
645 | return EINVAL; | ||
646 | |||
647 | fs = calloc (1, sizeof (struct _file_stream)); | ||
648 | if (fs == NULL) | ||
649 | return ENOMEM; | ||
650 | |||
651 | fs->filename = strdup (progname); | ||
652 | |||
653 | ret = stream_create (stream, flags|MU_STREAM_NO_CHECK, fs); | ||
654 | if (ret != 0) | ||
655 | { | ||
656 | free (fs); | ||
657 | return ret; | ||
658 | } | ||
659 | |||
660 | /* Check if we need to enable caching */ | ||
661 | |||
662 | if (flags & MU_STREAM_SEEKABLE) | ||
663 | { | ||
664 | if ((ret = memory_stream_create (&fs->cache, 0, MU_STREAM_RDWR)) | ||
665 | || (ret = stream_open (fs->cache))) | ||
666 | { | ||
667 | stream_destroy (stream, fs); | ||
668 | free (fs); | ||
669 | return ret; | ||
670 | } | ||
671 | stream_set_read (*stream, _stdin_file_read, fs); | ||
672 | stream_set_readline (*stream, _stdin_file_readline, fs); | ||
673 | stream_set_write (*stream, _stdout_file_write, fs); | ||
674 | } | ||
675 | else | ||
676 | { | ||
677 | stream_set_read (*stream, _file_read, fs); | ||
678 | stream_set_readline (*stream, _file_readline, fs); | ||
679 | stream_set_write (*stream, _file_write, fs); | ||
680 | } | ||
681 | |||
682 | /* We don't need to open the FILE, just return success. */ | ||
683 | |||
684 | stream_set_open (*stream, _prog_open, fs); | ||
685 | stream_set_close (*stream, _prog_close, fs); | ||
686 | stream_set_fd (*stream, _file_get_fd, fs); | ||
687 | stream_set_flush (*stream, _file_flush, fs); | ||
688 | stream_set_destroy (*stream, _file_destroy, fs); | ||
689 | |||
690 | return 0; | ||
691 | } | ... | ... |
-
Please register or sign in to post a comment