mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 06:00:54 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			299 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			299 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| %prep
 | |
| 
 | |
|   storepath=($path)
 | |
| 
 | |
|   mkdir command.tmp command.tmp/dir1 command.tmp/dir2
 | |
| 
 | |
|   cd command.tmp
 | |
| 
 | |
|   print '#!/bin/sh\necho This is top' >tstcmd
 | |
| 
 | |
|   print '#!/bin/sh\necho This is dir1' >dir1/tstcmd
 | |
| 
 | |
|   print '#!/bin/sh\necho This is dir2' >dir2/tstcmd
 | |
| 
 | |
|   chmod 755 tstcmd dir1/tstcmd dir2/tstcmd
 | |
| 
 | |
| %test
 | |
|   ./tstcmd
 | |
| 0:./prog execution
 | |
| >This is top
 | |
| 
 | |
|   path=($ZTST_testdir/command.tmp/dir1
 | |
|         $ZTST_testdir/command.tmp/dir2
 | |
|         .)
 | |
|   tstcmd
 | |
|   path=($storepath)
 | |
| 0:path (1)
 | |
| >This is dir1
 | |
| 
 | |
|   path=(. command.tmp/dir{1,2})
 | |
|   tstcmd
 | |
|   path=($storepath)
 | |
| 0:path (2)
 | |
| >This is top
 | |
| 
 | |
|   functst() { print $# arguments:; print -l $*; }
 | |
|   functst "Eines Morgens" "als Gregor Samsa"
 | |
|   functst ""
 | |
|   functst "aus unrühigen Träumen erwachte"
 | |
|   foo="fand er sich in seinem Bett"
 | |
|   bar=
 | |
|   rod="zu einem ungeheuren Ungeziefer verwandelt."
 | |
|   functst $foo $bar $rod
 | |
| # set up alias for next test
 | |
|   alias foo='print This is alias one'
 | |
| 0:function argument passing
 | |
| >2 arguments:
 | |
| >Eines Morgens
 | |
| >als Gregor Samsa
 | |
| >1 arguments:
 | |
| >
 | |
| >1 arguments:
 | |
| >aus unrühigen Träumen erwachte
 | |
| >2 arguments:
 | |
| >fand er sich in seinem Bett
 | |
| >zu einem ungeheuren Ungeziefer verwandelt.
 | |
| 
 | |
|   alias foo='print This is alias two'
 | |
|   fn() { foo; }
 | |
|   fn
 | |
| 0:Aliases in functions
 | |
| >This is alias one
 | |
| 
 | |
|   foo='Global foo'
 | |
|   traptst() { local foo="Local foo"; trap 'print $foo' EXIT; }
 | |
|   traptst
 | |
| 0:EXIT trap environment
 | |
| >Global foo
 | |
| 
 | |
|   functst() { return 0; print Ha ha; return 1; }
 | |
|   functst
 | |
| 0:return (1)
 | |
| 
 | |
|   functst() { return 1; print Ho ho; return 0; }
 | |
|   functst
 | |
| 1:return (2)
 | |
| 
 | |
|   unfunction functst
 | |
|   fpath=(.)
 | |
|   print "print This is functst." >functst
 | |
|   autoload functst
 | |
|   functst
 | |
| 0:autoloading (1)
 | |
| >This is functst.
 | |
| 
 | |
|   unfunction functst
 | |
|   print "functst() { print This, too, is functst; }; print Hello." >functst
 | |
|   typeset -fu functst
 | |
|   functst
 | |
|   functst
 | |
| 0:autoloading with initialization
 | |
| >Hello.
 | |
| >This, too, is functst
 | |
| 
 | |
|   unfunction functst
 | |
|   print "print Yet another version" >functst
 | |
|   functst() { autoload -X; }
 | |
|   functst
 | |
| 0:autoloading via -X
 | |
| >Yet another version
 | |
| 
 | |
|   chpwd() { print Changed to $PWD; }
 | |
|   cd .
 | |
|   unfunction chpwd
 | |
| 0q:chpwd
 | |
| >Changed to $ZTST_testdir/command.tmp
 | |
| 
 | |
|   chpwd() { print chpwd: changed to $PWD; }
 | |
|   chpwdfn1()  { print chpwdfn1: changed to $PWD; }
 | |
|   chpwdfn2()  { print chpwdfn2: changed to $PWD; }
 | |
|   chpwd_functions=(chpwdfn1 '' chpwdnonexistentfn chpwdfn2)
 | |
|   cd .
 | |
|   unfunction chpwd
 | |
|   unset chpwd_functions
 | |
| 0q:chpwd_functions
 | |
| >chpwd: changed to $ZTST_testdir/command.tmp
 | |
| >chpwdfn1: changed to $ZTST_testdir/command.tmp
 | |
| >chpwdfn2: changed to $ZTST_testdir/command.tmp
 | |
| 
 | |
| # Hard to test periodic, precmd and preexec non-interactively.
 | |
| 
 | |
|   fn() { TRAPEXIT() { print Exit; }; }
 | |
|   fn
 | |
| 0:TRAPEXIT
 | |
| >Exit
 | |
| 
 | |
|   unsetopt DEBUG_BEFORE_CMD
 | |
|   unfunction fn
 | |
|   print 'TRAPDEBUG() {
 | |
|       print Line $LINENO
 | |
|     }
 | |
|     :
 | |
|     unfunction TRAPDEBUG
 | |
|   ' > fn
 | |
|   autoload fn
 | |
|   fn
 | |
|   rm fn
 | |
| 0:TRAPDEBUG
 | |
| >Line 1
 | |
| >Line 1
 | |
| 
 | |
|   unsetopt DEBUG_BEFORE_CMD
 | |
|   unfunction fn
 | |
|   print 'trap '\''print Line $LINENO'\'' DEBUG
 | |
|     :
 | |
|     trap - DEBUG
 | |
|   ' > fn
 | |
|   autoload fn
 | |
|   fn
 | |
|   rm fn
 | |
| 0:trap DEBUG
 | |
| >Line 1
 | |
| >Line 2
 | |
| 
 | |
|   TRAPZERR() { print Command failed; }
 | |
|   true
 | |
|   false
 | |
|   true
 | |
|   false
 | |
|   unfunction TRAPZERR
 | |
| 0:TRAPZERR
 | |
| >Command failed
 | |
| >Command failed
 | |
| 
 | |
|   trap 'print Command failed again.' ZERR
 | |
|   true
 | |
|   false
 | |
|   true
 | |
|   false
 | |
|   trap - ZERR
 | |
| 0:trap ZERR
 | |
| >Command failed again.
 | |
| >Command failed again.
 | |
| 
 | |
|   false
 | |
|   sleep 1000 &
 | |
|   print $?
 | |
|   kill $!
 | |
| 0:Status reset by starting a backgrounded command
 | |
| >0
 | |
| 
 | |
|   { setopt MONITOR } 2>/dev/null
 | |
|   [[ -o MONITOR ]] || print -u $ZTST_fd 'Unable to change MONITOR option'
 | |
|   repeat 2048; do (return 2 |
 | |
|                    return 1 |
 | |
|                    while true; do
 | |
|                              false
 | |
|                              break
 | |
|                            done;
 | |
|                    print "${pipestatus[@]}")
 | |
| 	ZTST_hashmark
 | |
|   done | sort | uniq -c | sed 's/^ *//'
 | |
| 0:Check whether '$pipestatus[]' behaves.
 | |
| >2048 2 1 0
 | |
| F:This test checks for a bug in '$pipestatus[]' handling.  If it breaks then
 | |
| F:the bug is still there or it reappeared. See workers-29973 for details.
 | |
| 
 | |
|   { setopt MONITOR } 2>/dev/null
 | |
|   externFunc() { awk >/dev/null 2>&1; true; }
 | |
|   false | true | false | true | externFunc
 | |
|   echo $pipestatus
 | |
| 0:Check $pipestatus with a known difficult case
 | |
| >1 0 1 0 0
 | |
| F:This similar test was triggering a reproducible failure with pipestatus.
 | |
| 
 | |
|   { unsetopt MONITOR } 2>/dev/null
 | |
|   coproc { read -et 5 || { print -u $ZTST_fd KILLED; kill -HUP -$$ } }
 | |
|   print -u $ZTST_fd 'This test takes 5 seconds to fail...'
 | |
|   { printf "%d\n" {1..20000} } 2>/dev/null | ( read -e )
 | |
|   hang(){ printf "%d\n" {2..20000} | cat }; hang 2>/dev/null | ( read -e )
 | |
|   print -p done
 | |
|   read -et 6 -p
 | |
| 0:Bug regression: piping a shell construct to an external process may hang
 | |
| >1
 | |
| >2
 | |
| >done
 | |
| F:This test checks for a file descriptor leak that could cause the left
 | |
| F:side of a pipe to block on write after the right side has exited
 | |
| 
 | |
|   { setopt MONITOR } 2>/dev/null
 | |
|   if [[ -o MONITOR ]]
 | |
|   then
 | |
|    ( while :; do print "This is a line"; done ) | () : &
 | |
|    sleep 1
 | |
|    jobs -l
 | |
|   else
 | |
|    print -u $ZTST_fd "Skipping pipe leak test, requires MONITOR option"
 | |
|    print "[0] 0 0"
 | |
|   fi
 | |
| 0:Bug regression: piping to anonymous function; piping to backround function
 | |
| *>\[<->\] <-> <->
 | |
| F:This test checks for two different bugs, a parser segfault piping to an
 | |
| F:anonymous function, and a descriptor leak when backgrounding a pipeline
 | |
| 
 | |
|   print "autoload_redir() { print Autoloaded ksh style; } >autoload.log" >autoload_redir
 | |
|   autoload -Uk autoload_redir
 | |
|   autoload_redir
 | |
|   print No output yet
 | |
|   cat autoload.log
 | |
|   functions autoload_redir
 | |
| 0:
 | |
| >No output yet
 | |
| >Autoloaded ksh style
 | |
| >autoload_redir () {
 | |
| >	print Autoloaded ksh style
 | |
| >} > autoload.log
 | |
| 
 | |
| # This tests that we record the status of processes that have already exited
 | |
| # for when we wait for them.
 | |
| #
 | |
| # Actually, we don't guarantee here that the jobs have already exited, but
 | |
| # the order of the waits means it's highly likely we do need to recall a
 | |
| # previous status, barring accidents which shouldn't happen very often.  In
 | |
| # other words, we rely on the test working repeatedly rather than just
 | |
| # once.  The monitor option is irrelevant to the logic, so we'll make
 | |
| # our job easier by turning it off.
 | |
|   { unsetopt MONITOR } 2>/dev/null
 | |
|   (exit 1) &
 | |
|   one=$!
 | |
|   (exit 2) &
 | |
|   two=$!
 | |
|   (exit 3) &
 | |
|   three=$!
 | |
|   wait $three
 | |
|   print $?
 | |
|   wait $two
 | |
|   print $?
 | |
|   wait $one
 | |
|   print $?
 | |
| 0:The status of recently exited background jobs is recorded
 | |
| >3
 | |
| >2
 | |
| >1
 | |
| 
 | |
| # Regression test for workers/34060 (patch in 34065)
 | |
|   setopt ERR_EXIT NULL_GLOB
 | |
|   if false; then :; else echo if:$?; fi
 | |
|   if false; then :; else for x in _*_; do :; done; echo for:$?; fi
 | |
| 0:False "if" condition handled correctly by "for" loops with ERR_EXIT
 | |
| >if:1
 | |
| >for:0
 | |
| 
 | |
| # Regression test for workers/34065 (uses setopt from preceding test)
 | |
|   select x; do :; done; echo $?
 | |
|   select x in; do :; done; echo $?
 | |
|   select x in _*_; do :; done; echo $?
 | |
| 0:The status of "select" is zero when the loop body does not execute
 | |
| >0
 | |
| >0
 | |
| >0
 | |
| 
 | |
| # Regression test for workers/36392
 | |
|   print -u $ZTST_fd 'This test takes 3 seconds and hangs the shell when it fails...'
 | |
|   callfromchld() { true && { print CHLD } }
 | |
|   TRAPCHLD() { callfromchld }
 | |
|   sleep 2 & sleep 3; print OK
 | |
| 0:Background job exit does not affect reaping foreground job
 | |
| >CHLD
 | |
| >OK
 |