Commit b9a12f86 b9a12f867fba5466bdb5a385b5018e89ef3819f5 by Sergey Poznyakoff

(prog_stream_create): New function.

Creates a stream connected to the stdin or stdout of
a given program.
1 parent 0f778e9e
...@@ -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 }
......