about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog42
-rw-r--r--Completion/Unix/Command/_surfraw74
-rw-r--r--Completion/X/Command/_gv5
-rw-r--r--Doc/Zsh/options.yo16
-rw-r--r--Misc/vcs_info-examples8
-rw-r--r--README10
-rw-r--r--Src/exec.c10
-rw-r--r--Src/hist.c20
-rw-r--r--Src/input.c4
-rw-r--r--Src/mem.c43
-rw-r--r--Src/options.c1
-rw-r--r--Src/pattern.c9
-rw-r--r--Src/watch.c4
-rw-r--r--Src/zsh.h1
-rw-r--r--Test/B07emulate.ztst22
15 files changed, 182 insertions, 87 deletions
diff --git a/ChangeLog b/ChangeLog
index a21b405c8..a35eb6501 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
+2021-04-13  dana  <dana@dana.is>
+
+	* Daniel Shahaf: 48522: README: Clarify _alternative change
+
+2021-04-13  Tim Lee  <progscriptclone@gmail.com>
+
+	* 48525: Misc/vcs_info-examples: vcs_info git docs: ahead/behind
+	commits: Run fewer external programs
+
+2021-04-12  Jun-ichi Takimoto  <takimoto-j@kba.biglobe.ne.jp>
+
+	* 48439: Src/mem.c: remove macros that became unnecessary by 47785
+
+2021-04-11  Oliver Kiddle  <opk@zsh.org>
+
+	* 48504: Src/hist.c, Src/input.c, Src/watch.c:
+	use SEEK_ macros in fseek() calls
+
+	* Michael Stapelberg: 45396: Src/hist.c: readhistfile:
+	avoid thousands of lseek(2) syscalls via ftell()
+
+	* Marc Chantreux: 48466: Completion/Unix/Command/_surfraw:
+	correct indentation and remove tabs and trailing spaces
+
+	* Marc Chantreux: 48445: Completion/Unix/Command/_surfraw:
+	pluralize tags in _surfraw
+
+	* Marc Chantreux: users/26645: Completion/X/Command/_gv:
+	update options in gv completion
+
+2021-04-10  Bart Schaefer  <schaefer@zsh.org>
+
+	* 47913: Doc/Zsh/options.yo, Src/options.c, Src/pattern.c, Src/zsh.h:
+	implement CASE_PATHS option to make NO_CASE_GLOB more sensible
+
 2021-04-10  dana  <dana@dana.is>
 
+	* brian m. carlson: 47794: README, Src/exec.c,
+	Test/B07emulate.ztst: exec: run final pipeline command in a
+	subshell in sh mode
+
+	* unposted (see 48415): README: Document incompatibility
+	caused by workers/43928
+
 	* 48338: Completion/Unix/Command/_git: Support case-insensitive
 	path matching
 
diff --git a/Completion/Unix/Command/_surfraw b/Completion/Unix/Command/_surfraw
index 4838f1e58..d153cd493 100644
--- a/Completion/Unix/Command/_surfraw
+++ b/Completion/Unix/Command/_surfraw
@@ -20,11 +20,11 @@ case $state in
   subcmd)
     args=(
       '-help[display help information]'
-      '*:string:_guard "^-*" "search string"'
+      '*: :_guard "^-*" "search string"'
     )
     case "$words[1]" in
       ask|cia|cnn|deblogs|excite|filesearching|foldoc|happypenguin|slashdot|slinuxdoc|sundocs|sunsolve|xxx)
-        _message -e string 'search string'
+        _message -e strings 'search string'
       ;;
       alioth)
         _arguments $args \
@@ -64,10 +64,10 @@ case $state in
           '*:search string' && ret=0
       ;;
       ctan)
-	_arguments $args \
-	'-name[search by filename]' \
-	'-desc[search descriptions (default)]'\
-	'-doc[search documentation]'
+        _arguments $args \
+          '-name[search by filename]' \
+          '-desc[search descriptions (default)]'\
+          '-doc[search documentation]'
       ;;
       currency)
         _arguments \
@@ -164,8 +164,8 @@ case $state in
           '-doc[view PTS documentation]' && ret=0
       ;;
       debsec)
-        _message -e string 'package name, bug number or CVE ID'
-      ;; 
+        _message -e strings 'package name, bug number or CVE ID'
+      ;;
       deja)
         _arguments $args \
           '-results=-:[number of results to return]' \
@@ -183,7 +183,7 @@ case $state in
       ;;
       ebay)
         _arguments $args \
-          '-country=-:country:(com de uk fr)' \ 
+          '-country=-:country:(com de uk fr)' \
           '-results=-:[number of results to return]:number' && ret=0
       ;;
       etym)
@@ -220,7 +220,7 @@ case $state in
         _deb_packages avail && ret=0
       ;;
       fsfdir)
-	_arguments $args
+        _arguments $args
       ;;
       google)
         _arguments $args \
@@ -229,19 +229,19 @@ case $state in
           '-search=-:topic:(bsd linux mac unclesam)' && ret=0
       ;;
       gutenberg)
-	_arguments $args \
-	  '-title[search titles (default)]'
-	  '-author[search authors]'
-	  '-num[search etext numbers]'
-      ;;       
+        _arguments $args \
+          '-title[search titles (default)]'
+          '-author[search authors]'
+          '-num[search etext numbers]'
+      ;;
       imdb)
         _arguments $args \
           '-category=-:category:(All Titles MyMovies People Characters Quotes Bios Plots)' && ret=0
       ;;
       ixquick)
-	_arguments $args \
-	  '-search=-:search type:(web pics)' \
-	  '-lang=-:language:(english dansk deutsch espanol francais italiano nederlands norsk polski portugues suomi svenska turkce jiantizhongwen nihongo fantizhengwen hangul)'
+        _arguments $args \
+          '-search=-:search type:(web pics)' \
+          '-lang=-:language:(english dansk deutsch espanol francais italiano nederlands norsk polski portugues suomi svenska turkce jiantizhongwen nihongo fantizhengwen hangul)'
       ;;
       jake)
         _arguments $args \
@@ -261,9 +261,9 @@ case $state in
           '-head=:display headlines:(on off)' \
           '-grid=:show results in grid:(on off)' \
           '-spell=:spelling tolerance:(off standard force)' \
-          '*:dictionary word:->dictword' && ret=0
+          '*:dictionary word:->words' && ret=0
 
-        [[ "$state" = dictword ]] && _wanted words expl 'dictionary word' \
+        [[ "$state" = words ]] && _wanted words expl 'dictionary word' \
             compadd $(look "${PREFIX}") && ret=0
       ;;
       netbsd|openbsd)
@@ -386,20 +386,20 @@ case $state in
           :URL:_urls && ret=0
       ;;
       wayback)
-	_arguments $args \
-	  '-syear=-[start search from this year]:year' \
-	  '-smonth=-:[start search from this month]:month:(jan feb mar apr may jun jul aug sep oct nov dec)' \
-	  '-sday=-[start search from this day]:number' \
-	  '-eyear=-[end search in this year]:year' \
-	  '-emonth=-[end search in this month]:month:(jan feb mar apr may jun jul aug sep oct nov dec)' \
-	  '-eday=-[end search in this day]:number' \
-	  '-list[list all pages that match search criteria]' \
-	  '-dups[show dups]' \
-	  '-compare[compare pages]' \
-	  '-pdf[show as PDF]' \
-	  '-alias=-[how to handle site aliases]:alias:(merge show hide)' \
-	  '-redir=-[how to handle redirections]:redir:(hide flag show)' \
-	  '-type=-[file type to search for]:type:(image audio video binary text pdf)'
+        _arguments $args \
+          '-syear=-[start search from this year]:year' \
+          '-smonth=-:[start search from this month]:month:(jan feb mar apr may jun jul aug sep oct nov dec)' \
+          '-sday=-[start search from this day]:number' \
+          '-eyear=-[end search in this year]:year' \
+          '-emonth=-[end search in this month]:month:(jan feb mar apr may jun jul aug sep oct nov dec)' \
+          '-eday=-[end search in this day]:number' \
+          '-list[list all pages that match search criteria]' \
+          '-dups[show dups]' \
+          '-compare[compare pages]' \
+          '-pdf[show as PDF]' \
+          '-alias=-[how to handle site aliases]:alias:(merge show hide)' \
+          '-redir=-[how to handle redirections]:redir:(hide flag show)' \
+          '-type=-[file type to search for]:type:(image audio video binary text pdf)'
       ;;
       wetandwild)
         _arguments \
@@ -422,10 +422,10 @@ case $state in
           '-results=-[specify number of results to return]:number' && ret=0
       ;;
       yubnub)
-        _message -e command 'Yubnub Command'
+        _message -e commands 'Yubnub Command'
       ;;
       *)
-        _message -e string 'search string'
+        _message -e strings 'search string'
       ;;
     esac
   ;;
@@ -434,7 +434,7 @@ case $state in
     local it
     # list the applets
     set -- ${${(f)"$(_call_program elvi surfraw -elvi)"}%%[[:space:]]##-- *}
-    shift # the first line is an header: remove it
+    shift # the first line is a header: remove it
     # then list the bookmarks
     for it in \
       $^xdg_config_dirs/surfraw/bookmarks(Nr) \
diff --git a/Completion/X/Command/_gv b/Completion/X/Command/_gv
index cde8a1c1a..9b11ad31c 100644
--- a/Completion/X/Command/_gv
+++ b/Completion/X/Command/_gv
@@ -28,8 +28,11 @@ _arguments \
   '(--portrait --seascape --upsidedown)--landscape' \
   '(--portrait --landscape --upsidedown)--seascape' \
   '(--portrait --landscape --seascape)--upsidedown' \
-  --{help,spartan} \
   -{h,v} \
+  -{,-}{help,version} \
+  -{,-}{spartan,widgetless,presentation,fullscreen} \
+  -{,-}{infoSilent,infoErrors,infoAll} \
+  -{,-}'password=:password:' \
   '--arguments=:ghostscript arguments:' \
   '--page=:label of first page:' \
   '--media=:page size:(Letter Legal Statement Tabloid Ledger Folio Quarto 10x14 Executive A3 A4 A5 B4 B5)' \
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index 6a1f82b07..6e862fae8 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -474,6 +474,22 @@ item(tt(CASE_MATCH) <D>)(
 Make regular expressions using the tt(zsh/regex) module (including
 matches with tt(=~)) sensitive to case.
 )
+pindex(CASE_PATHS)
+pindex(NO_CASE_PATHS)
+pindex(CASEPATHS)
+pindex(NOCASEPATHS)
+cindex(case-sensitive globbing, option)
+item(tt(CASE_PATHS))(
+If tt(CASE_PATHS) is not set (the default), tt(CASE_GLOB) affects the
+interpretation of em(every) path component, whenever a special
+character appears in em(any) component.  When tt(CASE_PATHS) is set,
+file path components that do em(not) contain special filename
+generation characters are always sensitive to case, thus restricting
+tt(NO_CASE_GLOB) to components that contain globbing characters.
+
+Note that if the filesystem itself is not sensitive to case, then
+tt(CASE_PATHS) has no effect.
+)
 pindex(CSH_NULL_GLOB)
 pindex(NO_CSH_NULL_GLOB)
 pindex(CSHNULLGLOB)
diff --git a/Misc/vcs_info-examples b/Misc/vcs_info-examples
index 94b8a7b5e..d33d0ceed 100644
--- a/Misc/vcs_info-examples
+++ b/Misc/vcs_info-examples
@@ -179,14 +179,10 @@ function +vi-git-st() {
     local ahead behind
     local -a gitstatus
 
-    # for git prior to 1.7
-    # ahead=$(git rev-list origin/${hook_com[branch]}..HEAD | wc -l)
-    ahead=$(git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l)
+    ahead=$(git rev-list --count ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null)
     (( $ahead )) && gitstatus+=( "+${ahead}" )
 
-    # for git prior to 1.7
-    # behind=$(git rev-list HEAD..origin/${hook_com[branch]} | wc -l)
-    behind=$(git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)
+    behind=$(git rev-list --count HEAD..${hook_com[branch]}@{upstream} 2>/dev/null)
     (( $behind )) && gitstatus+=( "-${behind}" )
 
     hook_com[misc]+=${(j:/:)gitstatus}
diff --git a/README b/README
index 1eb38a608..76bf4ec35 100644
--- a/README
+++ b/README
@@ -95,6 +95,10 @@ right thing, but this should be viewed as an unsupported hack.)
 The XTRACE option is now disabled while running user-defined completion
 widgets.  See NEWS.
 
+emulate sh: When zsh emulates sh, the final command in a pipeline is now run in
+a subshell.  This differs from the behavior in the native (zsh) mode, but is
+consistent with most other sh implementations.
+
 Incompatibilities between 5.7.1 and 5.8
 ---------------------------------------
 
@@ -144,6 +148,12 @@ reverse order, from last applied to first applied.
 variables without a preceding '$' sign in shell arithmetic expansion
 and in the double-parentheses and 'let' arithmetic commands.
 
+3) _alternative now correctly handles the same (...) action syntax as
+_arguments; this may necessitate quoting/escaping in calls to _alternative
+and _regex_arguments that wasn't previously required.  See
+https://zsh.org/workers/48414 (commit zsh-5.8-348-g2c000ee7b) for details
+and an example.
+
 Incompatibilities between 5.5.1 and 5.6.2
 ------------------------------------------
 
diff --git a/Src/exec.c b/Src/exec.c
index 2301f85ad..6f09e0d9f 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2901,11 +2901,13 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 	    pushnode(args, dupstring("fg"));
     }
 
-    if ((how & Z_ASYNC) || output) {
+    if ((how & Z_ASYNC) || output ||
+	(last1 == 2 && input && EMULATION(EMULATE_SH))) {
 	/*
-	 * If running in the background, or not the last command in a
-	 * pipeline, we don't need any of the rest of this function to
-	 * affect the state in the main shell, so fork immediately.
+	 * If running in the background, not the last command in a
+	 * pipeline, or the last command in a multi-stage pipeline
+	 * in sh mode, we don't need any of the rest of this function
+	 * to affect the state in the main shell, so fork immediately.
 	 *
 	 * In other cases we may need to process the command line
 	 * a bit further before we make the decision.
diff --git a/Src/hist.c b/Src/hist.c
index 8ab7828e8..42cae030c 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -2589,11 +2589,13 @@ resizehistents(void)
 }
 
 static int
-readhistline(int start, char **bufp, int *bufsiz, FILE *in)
+readhistline(int start, char **bufp, int *bufsiz, FILE *in, int *readbytes)
 {
     char *buf = *bufp;
     if (fgets(buf + start, *bufsiz - start, in)) {
-	int len = start + strlen(buf + start);
+	int len = strlen(buf + start);
+	*readbytes += len;
+	len += start;
 	if (len == start)
 	    return -1;
 	if (buf[len - 1] != '\n') {
@@ -2602,7 +2604,7 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in)
 		    return -1;
 		*bufp = zrealloc(buf, 2 * (*bufsiz));
 		*bufsiz = 2 * (*bufsiz);
-		return readhistline(len, bufp, bufsiz, in);
+		return readhistline(len, bufp, bufsiz, in, readbytes);
 	    }
 	}
 	else {
@@ -2610,7 +2612,7 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in)
 	    if (len > 1 && buf[len - 2] == '\\') {
 		buf[--len - 1] = '\n';
 		if (!feof(in))
-		    return readhistline(len, bufp, bufsiz, in);
+		    return readhistline(len, bufp, bufsiz, in, readbytes);
 	    }
 	}
 	return len;
@@ -2630,7 +2632,7 @@ readhistfile(char *fn, int err, int readflags)
     short *words;
     struct stat sb;
     int nwordpos, nwords, bufsiz;
-    int searching, newflags, l, ret, uselex;
+    int searching, newflags, l, ret, uselex, readbytes;
 
     if (!fn && !(fn = getsparam("HISTFILE")))
 	return;
@@ -2662,7 +2664,7 @@ readhistfile(char *fn, int err, int readflags)
 	pushheap();
 	if (readflags & HFILE_FAST && lasthist.text) {
 	    if (lasthist.fpos < lasthist.fsiz) {
-		fseek(in, lasthist.fpos, 0);
+		fseek(in, lasthist.fpos, SEEK_SET);
 		searching = 1;
 	    }
 	    else {
@@ -2672,13 +2674,15 @@ readhistfile(char *fn, int err, int readflags)
 	} else
 	    searching = 0;
 
+	fpos = ftell(in);
+	readbytes = 0;
 	newflags = HIST_OLD | HIST_READ;
 	if (readflags & HFILE_FAST)
 	    newflags |= HIST_FOREIGN;
 	if (readflags & HFILE_SKIPOLD
 	 || (hist_ignore_all_dups && newflags & hist_skip_flags))
 	    newflags |= HIST_MAKEUNIQUE;
-	while (fpos = ftell(in), (l = readhistline(0, &buf, &bufsiz, in))) {
+	while (fpos += readbytes, readbytes = 0, (l = readhistline(0, &buf, &bufsiz, in, &readbytes))) {
 	    char *pt;
 	    int remeta = 0;
 
@@ -2737,7 +2741,7 @@ readhistfile(char *fn, int err, int readflags)
 		     && histstrcmp(pt, lasthist.text) == 0)
 			searching = 0;
 		    else {
-			fseek(in, 0, 0);
+			fseek(in, 0, SEEK_SET);
 			histfile_linect = 0;
 			searching = -1;
 		    }
diff --git a/Src/input.c b/Src/input.c
index e9989ffe4..f568cc135 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -495,9 +495,9 @@ stuff(char *fn)
 	zerr("can't open %s", fn);
 	return 1;
     }
-    fseek(in, 0, 2);
+    fseek(in, 0, SEEK_END);
     len = ftell(in);
-    fseek(in, 0, 0);
+    fseek(in, 0, SEEK_SET);
     buf = (char *)zalloc(len + 1);
     if (!(fread(buf, len, 1, in))) {
 	zerr("read error on %s", fn);
diff --git a/Src/mem.c b/Src/mem.c
index 25b2bbce7..fb4be47bf 100644
--- a/Src/mem.c
+++ b/Src/mem.c
@@ -1072,11 +1072,6 @@ zrealloc(void *ptr, size_t size)
 # endif
 #endif
 
-#define FREE_RET_T   void
-#define FREE_ARG_T   void *
-#define MALLOC_RET_T void *
-#define MALLOC_ARG_T size_t
-
 /* structure for building free list in blocks holding small blocks */
 
 struct m_shdr {
@@ -1190,8 +1185,8 @@ static struct m_hdr *m_l;
 
 #endif /* ZSH_MEM_DEBUG */
 
-MALLOC_RET_T
-malloc(MALLOC_ARG_T size)
+void *
+malloc(size_t size)
 {
     struct m_hdr *m, *mp, *mt;
     long n, s, os = 0;
@@ -1218,7 +1213,7 @@ malloc(MALLOC_ARG_T size)
 #if 1
 	size = 1;
 #else
-	return (MALLOC_RET_T) m_high;
+	return (void *) m_high;
 #endif
 
     queue_signals();  /* just queue signals rather than handling them */
@@ -1276,7 +1271,7 @@ malloc(MALLOC_ARG_T size)
 #endif
 
 	    unqueue_signals();
-	    return (MALLOC_RET_T) sh;
+	    return (void *) sh;
 	}
 	/* we still want a small block but there were no block with a free
 	   small block of the requested size; so we use the real allocation
@@ -1418,14 +1413,14 @@ malloc(MALLOC_ARG_T size)
 #endif
 
 	unqueue_signals();
-	return (MALLOC_RET_T) (((char *)m) + sizeof(struct m_hdr));
+	return (void *) (((char *)m) + sizeof(struct m_hdr));
     }
 #ifdef ZSH_MEM_DEBUG
     m_m[m->len < (1024 * M_ISIZE) ? (m->len / M_ISIZE) : 1024]++;
 #endif
 
     unqueue_signals();
-    return (MALLOC_RET_T) & m->next;
+    return (void *) & m->next;
 }
 
 /* this is an internal free(); the second argument may, but need not hold
@@ -1632,14 +1627,10 @@ zfree(void *p, int sz)
     unqueue_signals();
 }
 
-FREE_RET_T
-free(FREE_ARG_T p)
+void
+free(void *p)
 {
     zfree(p, 0);		/* 0 means: size is unknown */
-
-#ifdef FREE_DO_RET
-    return 0;
-#endif
 }
 
 /* this one is for strings (and only strings, real strings, real C strings,
@@ -1653,8 +1644,8 @@ zsfree(char *p)
 	zfree(p, strlen(p) + 1);
 }
 
-MALLOC_RET_T
-realloc(MALLOC_RET_T p, MALLOC_ARG_T size)
+void *
+realloc(void *p, size_t size)
 {
     struct m_hdr *m = (struct m_hdr *)(((char *)p) - M_ISIZE), *mt;
     char *r;
@@ -1665,12 +1656,12 @@ realloc(MALLOC_RET_T p, MALLOC_ARG_T size)
 	queue_signals();
 	r = malloc(size);
 	unqueue_signals();
-	return (MALLOC_RET_T) r;
+	return (void *) r;
     }
 
     /* and some systems even do this... */
     if (!p || !size)
-	return (MALLOC_RET_T) p;
+	return p;
 
     queue_signals();  /* just queue signals caught rather than handling them */
 
@@ -1699,17 +1690,17 @@ realloc(MALLOC_RET_T p, MALLOC_ARG_T size)
     free(p);
 
     unqueue_signals();
-    return (MALLOC_RET_T) r;
+    return (void *) r;
 }
 
-MALLOC_RET_T
-calloc(MALLOC_ARG_T n, MALLOC_ARG_T size)
+void *
+calloc(size_t n, size_t size)
 {
     long l;
     char *r;
 
     if (!(l = n * size))
-	return (MALLOC_RET_T) m_high;
+	return (void *) m_high;
 
     /*
      * use realloc() (with a NULL `p` argument it behaves exactly the same
@@ -1721,7 +1712,7 @@ calloc(MALLOC_ARG_T n, MALLOC_ARG_T size)
 
     memset(r, 0, l);
 
-    return (MALLOC_RET_T) r;
+    return (void *) r;
 }
 
 #ifdef ZSH_MEM_DEBUG
diff --git a/Src/options.c b/Src/options.c
index 23935ae18..783022591 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -105,6 +105,7 @@ static struct optname optns[] = {
 {{NULL, "bsdecho",	      OPT_EMULATE|OPT_SH},	 BSDECHO},
 {{NULL, "caseglob",	      OPT_ALL},			 CASEGLOB},
 {{NULL, "casematch",	      OPT_ALL},			 CASEMATCH},
+{{NULL, "casepaths",	      0},			 CASEPATHS},
 {{NULL, "cbases",	      0},			 CBASES},
 {{NULL, "cprecedences",	      OPT_EMULATE|OPT_NONZSH},	 CPRECEDENCES},
 {{NULL, "cdablevars",	      OPT_EMULATE},		 CDABLEVARS},
diff --git a/Src/pattern.c b/Src/pattern.c
index c28f2c9fb..c0e31b78e 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -509,7 +509,7 @@ void
 patcompstart(void)
 {
     patcompcharsset();
-    if (isset(CASEGLOB))
+    if (isset(CASEGLOB) || isset(CASEPATHS))
 	patglobflags = 0;
     else
 	patglobflags = GF_IGNCASE;
@@ -632,6 +632,13 @@ patcompile(char *exp, int inflags, char **endexp)
     p->patmlen = len;
     p->patnpar = patnpar-1;
 
+#ifndef __CYGWIN__  /* The filesystem itself is case-insensitive on Cygwin */
+    if ((patflags & PAT_FILE) && !isset(CASEGLOB) && !(patflags & PAT_PURES)) {
+	p->globflags |= GF_IGNCASE;
+	p->globend |= GF_IGNCASE;
+    }
+#endif
+
     if (!strp) {
 	pscan = (Upat)(patout + startoff);
 
diff --git a/Src/watch.c b/Src/watch.c
index 93b3cb134..c41704315 100644
--- a/Src/watch.c
+++ b/Src/watch.c
@@ -169,9 +169,9 @@ getlogtime(WATCH_STRUCT_UTMP *u, int inout)
 	return u->ut_time;
     if (!(in = fopen(WATCH_WTMP_FILE, "r")))
 	return time(NULL);
-    fseek(in, 0, 2);
+    fseek(in, 0, SEEK_END);
     do {
-	if (fseek(in, ((first) ? -1 : -2) * sizeof(WATCH_STRUCT_UTMP), 1)) {
+	if (fseek(in, ((first) ? -1 : -2) * sizeof(WATCH_STRUCT_UTMP), SEEK_CUR)) {
 	    fclose(in);
 	    return time(NULL);
 	}
diff --git a/Src/zsh.h b/Src/zsh.h
index 490407ad0..af9b4fb67 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2389,6 +2389,7 @@ enum {
     BSDECHO,
     CASEGLOB,
     CASEMATCH,
+    CASEPATHS,
     CBASES,
     CDABLEVARS,
     CDSILENT,
diff --git a/Test/B07emulate.ztst b/Test/B07emulate.ztst
index 7b1592fa9..45c39b51d 100644
--- a/Test/B07emulate.ztst
+++ b/Test/B07emulate.ztst
@@ -276,3 +276,25 @@ F:Some reserved tokens are handled in alias expansion
 0:--emulate followed by other options
 >yes
 >no
+
+  emulate sh -c '
+  foo () {
+    VAR=foo &&
+    echo $VAR | bar &&
+    echo "$VAR"
+  }
+  bar () {
+    tr f b &&
+    VAR="$(echo bar | tr r z)" &&
+    echo "$VAR"
+  }
+  foo
+  '
+  emulate sh -c 'func() { echo | local def="abc"; echo $def;}; func'
+  emulate sh -c 'abc="def"; echo | abc="ghi"; echo $abc'
+0:emulate sh uses subshell for last pipe entry
+>boo
+>baz
+>foo
+>
+>def