Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[patch] interactive source



I won't be at all upset if this patch doesn't make it in.  I haven't yet
thought of a really good use for it.  Whilst reading the manpage for the
Plan9 shell rc(1), I saw:

----------------------------8< cut here >8------------------------------
      . [-i] file [arg ...]
              Reads  file as input to rc and executes its contents.  With a -i
              flag, input is interactive.  Thus from within a shell script,

                   . -i /dev/tty

              does the ``right thing''.
----------------------------8< cut here >8------------------------------

I couldn't resist.  :^)

-Phil
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /home/cvsroot/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.94
diff -p -u -r1.94 builtins.yo
--- Doc/Zsh/builtins.yo	28 May 2007 22:57:40 -0000	1.94
+++ Doc/Zsh/builtins.yo	4 Jun 2007 00:34:14 -0000
@@ -31,7 +31,7 @@ ifnzman(noderef(Zle Builtins)).
 startitem()
 prefix(-)
 findex(.)
-item(tt(.) var(file) [ var(arg) ... ])(
+item(tt(.) [ tt(-i) ] var(file) [ var(arg) ... ])(
 Read commands from var(file) and execute them in the current shell
 environment.
 
@@ -47,6 +47,8 @@ If any arguments var(arg) are given,
 they become the positional parameters; the old positional
 parameters are restored when the var(file) is done executing.
 The exit status is the exit status of the last command executed.
+
+If the first parameter is tt(-i) then the shell sources interactively.
 )
 findex(NOTRANS(:))
 cindex(expanding parameters)
@@ -1195,7 +1197,7 @@ If any var(name)s are given then the arr
 shifted instead of the positional parameters.
 )
 findex(source)
-item(tt(source) var(file) [ var(arg) ... ])(
+item(tt(source) [ tt(-i) ] var(file) [ var(arg) ... ])(
 Same as tt(.), except that the current directory is always searched and
 is always searched first, before directories in tt($path).
 )
Index: Src/builtin.c
===================================================================
RCS file: /home/cvsroot/zsh/Src/builtin.c,v
retrieving revision 1.179
diff -p -u -r1.179 builtin.c
--- Src/builtin.c	29 May 2007 17:01:08 -0000	1.179
+++ Src/builtin.c	4 Jun 2007 00:31:57 -0000
@@ -4544,7 +4544,7 @@ zexit(int val, int from_where)
 	    sourcehome(".zlogout");
 #ifdef GLOBAL_ZLOGOUT
 	    if (isset(RCS) && isset(GLOBALRCS))
-		source(GLOBAL_ZLOGOUT);
+		source(GLOBAL_ZLOGOUT, 0);
 #endif
 	}
     }
@@ -4571,10 +4571,17 @@ bin_dot(char *name, char **argv, UNUSED(
     char **old, *old0 = NULL;
     int ret, diddot = 0, dotdot = 0;
     char *s, **t, *enam, *arg0, *buf;
+    int srcflags = 0;
     struct stat st;
 
     if (!*argv)
 	return 0;
+    if (!strcmp(argv[0], "-i")) {
+	if (!*argv[1])
+	    return 0;
+	srcflags |= ZF_SOURCE_INTERACT;
+	++argv;
+    }
     old = pparams;
     /* get arguments for the script */
     if (argv[1])
@@ -4592,7 +4599,7 @@ bin_dot(char *name, char **argv, UNUSED(
     if (*name != '.' && access(s, F_OK) == 0
 	&& stat(s, &st) >= 0 && !S_ISDIR(st.st_mode)) {
 	diddot = 1;
-	ret = source(enam);
+	ret = source(enam, srcflags);
     }
     if (ret) {
 	/* use a path with / in it */
@@ -4604,7 +4611,7 @@ bin_dot(char *name, char **argv, UNUSED(
 		    else if (arg0[1] == '.' && arg0 + 2 == s)
 			++dotdot;
 		}
-		ret = source(arg0);
+		ret = source(arg0, srcflags);
 		break;
 	    }
 	if (!*s || (ret && isset(PATHDIRS) && diddot < 2 && dotdot == 0)) {
@@ -4622,7 +4629,7 @@ bin_dot(char *name, char **argv, UNUSED(
 		s = unmeta(buf);
 		if (access(s, F_OK) == 0 && stat(s, &st) >= 0
 		    && !S_ISDIR(st.st_mode)) {
-		    ret = source(enam = buf);
+		    ret = source(enam = buf, srcflags);
 		    break;
 		}
 	    }
Index: Src/init.c
===================================================================
RCS file: /home/cvsroot/zsh/Src/init.c,v
retrieving revision 1.75
diff -p -u -r1.75 init.c
--- Src/init.c	29 May 2007 17:01:08 -0000	1.75
+++ Src/init.c	4 Jun 2007 01:57:15 -0000
@@ -953,7 +953,7 @@ run_init_scripts(void)
 
     if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
 	if (islogin)
-	    source("/etc/profile");
+	    source("/etc/profile", 0);
 	if (unset(PRIVILEGED)) {
 	    char *s = getsparam("ENV");
 	    if (islogin)
@@ -962,14 +962,14 @@ run_init_scripts(void)
 	    if (s && !parsestr(s)) {
 		singsub(&s);
 		noerrs = 0;
-		source(s);
+		source(s, 0);
 	    }
 	    noerrs = 0;
 	} else
-	    source("/etc/suid_profile");
+	    source("/etc/suid_profile", 0);
     } else {
 #ifdef GLOBAL_ZSHENV
-	source(GLOBAL_ZSHENV);
+	source(GLOBAL_ZSHENV, 0);
 #endif
 
 	if (isset(RCS) && unset(PRIVILEGED))
@@ -990,7 +990,7 @@ run_init_scripts(void)
 	if (islogin) {
 #ifdef GLOBAL_ZPROFILE
 	    if (isset(RCS) && isset(GLOBALRCS))
-		    source(GLOBAL_ZPROFILE);
+		    source(GLOBAL_ZPROFILE, 0);
 #endif
 	    if (isset(RCS) && unset(PRIVILEGED))
 		sourcehome(".zprofile");
@@ -998,7 +998,7 @@ run_init_scripts(void)
 	if (interact) {
 #ifdef GLOBAL_ZSHRC
 	    if (isset(RCS) && isset(GLOBALRCS))
-		source(GLOBAL_ZSHRC);
+		source(GLOBAL_ZSHRC, 0);
 #endif
 	    if (isset(RCS) && unset(PRIVILEGED))
 		sourcehome(".zshrc");
@@ -1006,7 +1006,7 @@ run_init_scripts(void)
 	if (islogin) {
 #ifdef GLOBAL_ZLOGIN
 	    if (isset(RCS) && isset(GLOBALRCS))
-		source(GLOBAL_ZLOGIN);
+		source(GLOBAL_ZLOGIN, 0);
 #endif
 	    if (isset(RCS) && unset(PRIVILEGED))
 		sourcehome(".zlogin");
@@ -1046,7 +1046,7 @@ init_misc(void)
 
 /**/
 mod_export int
-source(char *s)
+source(char *s, int srcflags)
 {
     Eprog prog;
     int tempfd = -1, fd, cj, oldlineno;
@@ -1055,6 +1055,7 @@ source(char *s)
     char *old_scriptname = scriptname, *us;
     unsigned char *ocs;
     int ocsp;
+    int isrc = 0;
 
     if (!s || 
 	(!(prog = try_source_file((us = unmeta(s)))) &&
@@ -1082,8 +1083,12 @@ source(char *s)
     subsh  = 0;
     lineno = 1;
     loops  = 0;
-    dosetopt(SHINSTDIN, 0, 1);
     scriptname = s;
+    if (srcflags & ZF_SOURCE_INTERACT) {
+	isrc = 1;	/* Pretend to be top-level in loop() */
+	dosetopt(SHINSTDIN, 1, 1);
+    } else
+	dosetopt(SHINSTDIN, 0, 1);
 
     sourcelevel++;
     if (prog) {
@@ -1092,7 +1097,7 @@ source(char *s)
 	execode(prog, 1, 0);
 	popheap();
     } else
-	loop(0, 0);		     /* loop through the file to be sourced  */
+	loop(isrc, 0);		     /* loop through the file to be sourced  */
     sourcelevel--;
 
     /* restore the current shell state */
@@ -1141,7 +1146,7 @@ sourcehome(char *s)
 	VARARR(char, buf, strlen(h) + strlen(s) + 2);
 	sprintf(buf, "%s/%s", h, s);
 	unqueue_signals();
-	source(buf);
+	source(buf, 0);
     }
 }
 
Index: Src/zsh.h
===================================================================
RCS file: /home/cvsroot/zsh/Src/zsh.h,v
retrieving revision 1.115
diff -p -u -r1.115 zsh.h
--- Src/zsh.h	28 May 2007 22:57:41 -0000	1.115
+++ Src/zsh.h	4 Jun 2007 00:25:47 -0000
@@ -2020,6 +2020,12 @@ struct heap {
 #define ZSIG_ALIAS	(1<<3)  /* Trap is stored under an alias */
 #define ZSIG_SHIFT	4
 
+/******************************************************
+ * Special flags for miscellaneous internal functions *
+ ******************************************************/
+
+#define ZF_SOURCE_INTERACT	(1<<0)
+
 /***********/
 /* Sorting */
 /***********/
Index: Src/Modules/newuser.c
===================================================================
RCS file: /home/cvsroot/zsh/Src/Modules/newuser.c,v
retrieving revision 1.5
diff -p -u -r1.5 newuser.c
--- Src/Modules/newuser.c	7 Feb 2006 05:19:21 -0000	1.5
+++ Src/Modules/newuser.c	4 Jun 2007 00:20:12 -0000
@@ -83,7 +83,7 @@ boot_(UNUSED(Module m))
 	VARARR(char, buf, strlen(*sp) + 9);
 	sprintf(buf, "%s/newuser", *sp);
 
-	if (!source(buf))
+	if (!source(buf, 0))
 	    break;
     }
 


Messages sorted by: Reverse Date, Date, Thread, Author