aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2009-04-23 00:10:28 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2009-04-23 04:44:42 +1000
commit2b799037c73b95cbf7dd392527947bd5a711083f (patch)
tree62e096ace34ebc236784bf620caed6b55580963a /shell
parent560c665526a24446df2d5c3f069574d2b4d432d6 (diff)
downloadbusybox-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.c112
-rw-r--r--shell/ash_mingw.h17
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 * * * * */
786struct forkpoint {
787 const char *name;
788 void (*func)(union node *,int);
789};
790
791/* entry names should not be too long */
792struct forkpoint forkpoints[] = {
793 { NULL, NULL },
794};
795
796/* * * * * fork emulation * * * * */
797static int
798forkshell_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
820static void
821forkshell_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
834static void
835forkshell_transfer_done(struct forkshell *fs)
836{
837 guard_send(fs->fd, SER_DONE);
838 close(fs->fd);
839}
840
841static void
842forkshell_cleanup(struct forkshell *fs)
843{
844}
845
846static int
847forkshell(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
865static void
866subshell_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 @@
1struct forkshell {
2 const char *fp;
3 union node *n;
4 int flags;
5 struct child_process cmd;
6 int fd;
7};
8
9static int forkshell_init(struct forkshell *fs);
10static void forkshell_transfer(struct forkshell *fs);
11static void forkshell_transfer_done(struct forkshell *fs);
12static void forkshell_cleanup(struct forkshell *fs);
13static int forkshell(const char *fp, union node *n, int flags);
14static void subshell_run();
15
16static int subash_fd = -1;
17static char subash_entry[16];