diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-04-23 00:10:28 +1000 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-04-23 04:44:42 +1000 |
commit | 2b799037c73b95cbf7dd392527947bd5a711083f (patch) | |
tree | 62e096ace34ebc236784bf620caed6b55580963a /shell | |
parent | 560c665526a24446df2d5c3f069574d2b4d432d6 (diff) | |
download | busybox-w32-2b799037c73b95cbf7dd392527947bd5a711083f.tar.gz busybox-w32-2b799037c73b95cbf7dd392527947bd5a711083f.tar.bz2 busybox-w32-2b799037c73b95cbf7dd392527947bd5a711083f.zip |
shell/ash: add forkshell_* to transfer data via pipe
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash_mingw.c | 112 | ||||
-rw-r--r-- | shell/ash_mingw.h | 17 |
2 files changed, 129 insertions, 0 deletions
diff --git a/shell/ash_mingw.c b/shell/ash_mingw.c index c52d8b45c..a412b7210 100644 --- a/shell/ash_mingw.c +++ b/shell/ash_mingw.c | |||
@@ -781,3 +781,115 @@ misc_recv(int fd) | |||
781 | /* stackbase... */ | 781 | /* stackbase... */ |
782 | guard_recv1(fd, -1); | 782 | guard_recv1(fd, -1); |
783 | } | 783 | } |
784 | |||
785 | /* * * * * fork entries * * * * */ | ||
786 | struct forkpoint { | ||
787 | const char *name; | ||
788 | void (*func)(union node *,int); | ||
789 | }; | ||
790 | |||
791 | /* entry names should not be too long */ | ||
792 | struct forkpoint forkpoints[] = { | ||
793 | { NULL, NULL }, | ||
794 | }; | ||
795 | |||
796 | /* * * * * fork emulation * * * * */ | ||
797 | static int | ||
798 | forkshell_init(struct forkshell *fs) | ||
799 | { | ||
800 | static char argv2[32]; | ||
801 | static const char *argv[4] = { NULL, "sh", argv2, NULL }; | ||
802 | int p[2]; | ||
803 | |||
804 | if (_pipe(p, 0, 0) < 0) | ||
805 | ash_msg_and_raise_error("Unable to create pipe"); | ||
806 | |||
807 | /* | ||
808 | * Do not use C file handle here because MinGW port | ||
809 | * uses a custom execvp version, which will not reconstruct | ||
810 | * filehandle table correctly (for msvcrt to read) | ||
811 | */ | ||
812 | sprintf(argv2, "subash%lx:%s", _get_osfhandle(p[0]), fs->fp); | ||
813 | |||
814 | argv[0] = CONFIG_BUSYBOX_EXEC_PATH; | ||
815 | fs->cmd.argv = argv; | ||
816 | fs->fd = p[1]; | ||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | static void | ||
821 | forkshell_transfer(struct forkshell *fs) | ||
822 | { | ||
823 | tblentry_send(fs->fd); | ||
824 | vartab_send(fs->fd); | ||
825 | localvars_send(fs->fd); | ||
826 | optlist_send(fs->fd); | ||
827 | misc_send(fs->fd); | ||
828 | |||
829 | guard_send(fs->fd, SER_FORK); | ||
830 | node_send(fs->fd, fs->n); | ||
831 | int_send(fs->fd, fs->flags); | ||
832 | } | ||
833 | |||
834 | static void | ||
835 | forkshell_transfer_done(struct forkshell *fs) | ||
836 | { | ||
837 | guard_send(fs->fd, SER_DONE); | ||
838 | close(fs->fd); | ||
839 | } | ||
840 | |||
841 | static void | ||
842 | forkshell_cleanup(struct forkshell *fs) | ||
843 | { | ||
844 | } | ||
845 | |||
846 | static int | ||
847 | forkshell(const char *fp, union node *n, int flags) | ||
848 | { | ||
849 | struct forkshell fs; | ||
850 | int status; | ||
851 | memset(&fs, 0, sizeof(fs)); | ||
852 | fs.fp = fp; | ||
853 | fs.n = n; | ||
854 | fs.flags = flags; | ||
855 | forkshell_init(&fs); | ||
856 | if (start_command(&fs.cmd)) | ||
857 | ash_msg_and_raise_error("unable to spawn shell"); | ||
858 | forkshell_transfer(&fs); | ||
859 | forkshell_transfer_done(&fs); | ||
860 | forkshell_cleanup(&fs); | ||
861 | set_exitstatus(finish_command(&fs.cmd), fs.cmd.argv, &status); | ||
862 | return status; | ||
863 | } | ||
864 | |||
865 | static void | ||
866 | subshell_run() | ||
867 | { | ||
868 | struct forkpoint *fp; | ||
869 | int fd = subash_fd; | ||
870 | union node *n; | ||
871 | int flags; | ||
872 | |||
873 | if (fd == -1) | ||
874 | return; | ||
875 | |||
876 | for (fp = forkpoints;fp->name && strcmp(fp->name, subash_entry);fp ++); | ||
877 | |||
878 | if (!fp->name) | ||
879 | die("ASH_SHELL_ENTRY invalid"); | ||
880 | |||
881 | tblentry_recv(fd); | ||
882 | vartab_recv(fd); | ||
883 | localvars_recv(fd); | ||
884 | optlist_recv(fd); | ||
885 | misc_recv(fd); | ||
886 | |||
887 | guard_recv1(fd, SER_FORK); | ||
888 | n = node_recv(fd); | ||
889 | flags = int_recv(fd); | ||
890 | guard_recv1(fd, SER_DONE); | ||
891 | |||
892 | fp->func(n, flags); | ||
893 | |||
894 | die("subshell ended unexpectedly"); | ||
895 | } | ||
diff --git a/shell/ash_mingw.h b/shell/ash_mingw.h new file mode 100644 index 000000000..658c7dae2 --- /dev/null +++ b/shell/ash_mingw.h | |||
@@ -0,0 +1,17 @@ | |||
1 | struct forkshell { | ||
2 | const char *fp; | ||
3 | union node *n; | ||
4 | int flags; | ||
5 | struct child_process cmd; | ||
6 | int fd; | ||
7 | }; | ||
8 | |||
9 | static int forkshell_init(struct forkshell *fs); | ||
10 | static void forkshell_transfer(struct forkshell *fs); | ||
11 | static void forkshell_transfer_done(struct forkshell *fs); | ||
12 | static void forkshell_cleanup(struct forkshell *fs); | ||
13 | static int forkshell(const char *fp, union node *n, int flags); | ||
14 | static void subshell_run(); | ||
15 | |||
16 | static int subash_fd = -1; | ||
17 | static char subash_entry[16]; | ||