about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-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
8 files changed, 49 insertions, 43 deletions
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,