457 |
|
|
458 |
fs->file = fdopen (fd, mode); |
fs->file = fdopen (fd, mode); |
459 |
if (fs->file == NULL) |
if (fs->file == NULL) |
460 |
{ |
return errno; |
|
int ret = errno; |
|
|
return ret; |
|
|
} |
|
461 |
|
|
462 |
return 0; |
return 0; |
463 |
} |
} |
569 |
return 0; |
return 0; |
570 |
} |
} |
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 |
|
} |