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

Re: [tbm@xxxxxxxxxx: Bug#130817: zsh's echo doesn't error if device is full]



> There are a number of places in bin_print() that look something like:
> 
>     if (fout != stdout)
> 	fclose(fout);
> 
> Try changing all of those to the equivalent of:
> 
>     if (((fout != stdout) ? fclose(fout) : fflush(fout)) != 0) {
> 	zwarnnam(name, "write error: %e", NULL, 0);
> 	ret = 1;
>     }

That did the trick.  Patch is bloated with reindentation.

Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.65
diff -u -r1.65 builtin.c
--- Src/builtin.c	2002/01/26 21:03:36	1.65
+++ Src/builtin.c	2002/01/27 22:40:59
@@ -241,7 +241,7 @@
 	/* while arguments look like options ... */
 	while (arg &&
 	       ((sense = (*arg == '-')) ||
-		 ((flags & BINF_PLUSOPTS) && *arg == '+')) &&
+		((flags & BINF_PLUSOPTS) && *arg == '+')) &&
 	       ((flags & BINF_PLUSOPTS) || !atoi(arg))) {
 	    /* unrecognised options to echo etc. are not really options */
 	    if (flags & BINF_ECHOPTS) {
@@ -296,7 +296,7 @@
 	    }
 	    arg = (char *) ugetnode(args);
 	    /* for the "print" builtin, the options after -R are treated as
-	    options to "echo" and -f takes an extra argument */
+	       options to "echo" and -f takes an extra argument */
 	    if (flags & BINF_PRINTOPTS) {
 		if (ops['R'] && !ops['f']) {
 		    optstr = "ne";
@@ -448,13 +448,13 @@
     /* Take arguments literally -- do not glob */
     queue_signals();
     for (; *argv; argv++) {
-	    if ((hn = ht->getnode2(ht, *argv))) {
-		scanfunc(hn, 0);
-	    } else {
-		zwarnnam(name, "no such hash table element: %s", *argv, 0);
-		returnval = 1;
-	    }
+	if ((hn = ht->getnode2(ht, *argv))) {
+	    scanfunc(hn, 0);
+	} else {
+	    zwarnnam(name, "no such hash table element: %s", *argv, 0);
+	    returnval = 1;
 	}
+    }
     unqueue_signals();
     return returnval;
 }
@@ -524,19 +524,19 @@
 	}
 	args++;
     }
-    doneoptions:
+ doneoptions:
     inittyptab();
 
     /* Show the parameters, possibly with values */
     queue_signals();
     if (!hadopt && !*args)
 	scanhashtable(paramtab, 1, 0, 0, paramtab->printnode,
-	    hadplus ? PRINT_NAMEONLY : 0);
+		      hadplus ? PRINT_NAMEONLY : 0);
 
     if (array && !*args) {
 	/* display arrays */
 	scanhashtable(paramtab, 1, PM_ARRAY, 0, paramtab->printnode,
-	    hadplus ? PRINT_NAMEONLY : 0);
+		      hadplus ? PRINT_NAMEONLY : 0);
     }
     if (!*args && !hadend) {
 	unqueue_signals();
@@ -608,7 +608,7 @@
     LinkList l;
 
     /* with the -v option, provide a numbered list of directories, starting at
-    zero */
+       zero */
     queue_signals();
     if (ops['v']) {
 	LinkNode node;
@@ -716,7 +716,7 @@
 	} while (*++s);
 	for (s = *argv; *++s; ops[STOUC(*s)] = 1);
     }
-  brk:
+ brk:
     chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
     queue_signals();
     zpushnode(dirstack, ztrdup(pwd));
@@ -865,8 +865,8 @@
     dest = buf;
 #endif
     nocdpath = dest[0] == '.' &&
-		(dest[1] == '/' || !dest[1] || (dest[1] == '.' &&
-				    (dest[2] == '/' || !dest[2])));
+	(dest[1] == '/' || !dest[1] || (dest[1] == '.' &&
+					(dest[2] == '/' || !dest[2])));
 
     /*
      * If we have an absolute path, use it as-is only
@@ -884,7 +884,7 @@
 	    if (!(*pp)[0] || ((*pp)[0] == '.' && (*pp)[1] == '\0'))
 		hasdot = 1;
     /* if there is no . in cdpath (or it is not being used), try the directory
-    as-is (i.e. from .) */
+       as-is (i.e. from .) */
     if (!hasdot) {
 	if ((ret = cd_try_chdir(NULL, dest, hard)))
 	    return ret;
@@ -892,7 +892,7 @@
 	    eno = errno;
     }
     /* if cdpath is being used, try given directory relative to each element in
-    cdpath in turn */
+       cdpath in turn */
     if (!nocdpath)
 	for (pp = cdpath; *pp; pp++) {
 	    if ((ret = cd_try_chdir(*pp, dest, hard))) {
@@ -916,8 +916,8 @@
     }
 
     /* If we got here, it means that we couldn't chdir to any of the
-    multitudinous possible paths allowed by zsh.  We've run out of options!
-    Add more here! */
+       multitudinous possible paths allowed by zsh.  We've run out of options!
+       Add more here! */
     zwarnnam(cnam, "%e: %s", dest, eno);
     return NULL;
 }
@@ -1045,7 +1045,7 @@
     }
 
     /* shift around the pwd variables, to make oldpwd and pwd relate to the
-    current (i.e. new) pwd */
+       current (i.e. new) pwd */
     zsfree(oldpwd);
     oldpwd = pwd;
     setjobpwd();
@@ -1074,7 +1074,7 @@
     /* handle directory stack sizes out of range */
     if (dirstacksize > 0) {
 	int remove = countlinknodes(dirstack) -
-		     (dirstacksize < 2 ? 2 : dirstacksize);
+	    (dirstacksize < 2 ? 2 : dirstacksize);
 	while (remove-- >= 0)
 	    zsfree(remnode(dirstack, lastnode(dirstack)));
     }
@@ -1116,7 +1116,7 @@
 #ifdef HAVE_SUPERROOT
     /* allow /.. segments to remain */
     while (*src == '/' && src[1] == '.' && src[2] == '.' &&
-      (!src[3] || src[3] == '/')) {
+	   (!src[3] || src[3] == '/')) {
 	*dest++ = '/';
 	*dest++ = '.';
 	*dest++ = '.';
@@ -1137,7 +1137,7 @@
 		src++;
 	}
 	/* if we are at the end of the input path, remove a trailing / (if it
-	exists), and return ct */
+	   exists), and return ct */
 	if (!*src) {
 	    while (dest > d0 + 1 && dest[-1] == '/')
 		dest--;
@@ -1303,7 +1303,7 @@
     /* default values of first and last, and range checking */
     if (first == -1) {
 	first = ops['l']? addhistnum(curline.histnum,-16,0)
-			: addhistnum(curline.histnum,-1,0);
+	    : addhistnum(curline.histnum,-1,0);
     }
     if (last == -1)
 	last = ops['l']? addhistnum(curline.histnum,-1,0) : first;
@@ -1329,8 +1329,8 @@
 	retval = 1;
 	fil = gettempname();
 	if (((tempfd = open(fil, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600))
-	    == -1) ||
-		((out = fdopen(tempfd, "w")) == NULL)) {
+	     == -1) ||
+	    ((out = fdopen(tempfd, "w")) == NULL)) {
 	    unqueue_signals();
 	    zwarnnam("fc", "can't open temp file: %e", NULL, errno);
 	} else {
@@ -1407,7 +1407,7 @@
 	/* loop over occurences of oldstr in s, replacing them with newstr */
 	while ((newpos = (char *)strstr(oldpos, oldstr))) {
 	    newmem = (char *) zhalloc(1 + (newpos - s)
-			+ strlen(newstr) + strlen(newpos + strlen(oldstr)));
+				      + strlen(newstr) + strlen(newpos + strlen(oldstr)));
 	    ztrncpy(newmem, s, newpos - s);
 	    strcat(newmem, newstr);
 	    oldpos = newmem + strlen(newmem);
@@ -1473,7 +1473,7 @@
 			ent->flags & HIST_FOREIGN? '*' : ' ');
 	    }
 	    /* output actual time (and possibly date) of execution of the
-	    command, if required */
+	       command, if required */
 	    if (d) {
 		struct tm *ltm;
 		ltm = localtime(&ent->stim);
@@ -1579,7 +1579,7 @@
 	*s = '\0';
 	asg.value = s + 1;
     } else {
-    /* didn't find `=', so we only have a name */
+	/* didn't find `=', so we only have a name */
 	asg.value = NULL;
     }
     return &asg;
@@ -1634,8 +1634,8 @@
     tc = 0;
     if (usepm || newspecial) {
 	int chflags = ((off & pm->flags) | (on & ~pm->flags)) &
-	     (PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_HASHED|
-	      PM_ARRAY|PM_TIED|PM_AUTOLOAD);
+	    (PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_HASHED|
+	     PM_ARRAY|PM_TIED|PM_AUTOLOAD);
 	/* keep the parameter if just switching between floating types */
 	if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT)))
 	    usepm = 0;
@@ -2237,7 +2237,7 @@
 		    scanmatchtable(shfunctab, pprog, 0, DISABLED,
 				   shfunctab->printnode, pflags);
 		} else {
-		/* apply the options to all functions matching the glob pattern */
+		    /* apply the options to all functions matching the glob pattern */
 		    for (i = 0; i < shfunctab->hsize; i++) {
 			for (shf = (Shfunc) shfunctab->nodes[i]; shf;
 			     shf = (Shfunc) shf->next)
@@ -2347,7 +2347,7 @@
 			/* record pointer to next, since we may free this one */
 			next = (Param) pm->next;
 			if ((!(pm->flags & PM_RESTRICTED) ||
-			    unset(RESTRICTED)) &&
+			     unset(RESTRICTED)) &&
 			    pattry(pprog, pm->nam)) {
 			    unsetparam_pm(pm, 0, 1);
 			    match++;
@@ -2840,7 +2840,7 @@
 	    /* The argument is of the form foo=bar and we are not *
 	     * forcing a listing with -L, so define an alias      */
 	    aliastab->addnode(aliastab, ztrdup(asg->name),
-		createaliasnode(ztrdup(asg->value), flags1));
+			      createaliasnode(ztrdup(asg->value), flags1));
 	} else if ((a = (Alias) aliastab->getnode(aliastab, asg->name))) {
 	    /* display alias if appropriate */
 	    if (!haveflags ||
@@ -2899,25 +2899,25 @@
     char **first, *curarg, *flagch = "0+- #", save, nullstr = '\0';
     zlong count;
     FILE *fout = stdout;
-
+    
     mnumber mnumval;
     double doubleval;
     int intval;
     zlong zlongval;
     zulong zulongval;
     char *stringval;
-
+    
     if (func == BIN_PRINTF) auxdata = *args++;
     if (auxdata)
 	fmt = getkeystring(auxdata, &flen, ops['b'] ? 2 : 0, &nnl);
     first = args;
-
+    
     /* -m option -- treat the first argument as a pattern and remove
      * arguments not matching */
     if (ops['m']) {
 	Patprog pprog;
 	char **t, **p;
-
+	
 	tokenize(*args);
 	if (!(pprog = patcompile(*args, PAT_STATIC, NULL))) {
 	    untokenize(*args);
@@ -2940,7 +2940,7 @@
 	    unmetafy(args[n], &len[n]);
 	else
 	    args[n] = getkeystring(args[n], &len[n], ops['b'] ? 2 :
-				    (func != BIN_ECHO && !ops['e']), &nnl);
+				   (func != BIN_ECHO && !ops['e']), &nnl);
 	/* -P option -- interpret as a prompt sequence */
 	if(ops['P']) {
 	    /*
@@ -2949,14 +2949,14 @@
 	     * instead.
 	     */
 	    char *str = unmetafy(promptexpand(metafy(args[n], len[n],
-				   META_NOALLOC), 0, NULL, NULL), &len[n]);
+						     META_NOALLOC), 0, NULL, NULL), &len[n]);
 	    args[n] = dupstring(str);
 	    free(str);
 	}
 	/* -D option -- interpret as a directory, and use ~ */
 	if(ops['D']) {
 	    Nameddir d;
-
+	    
 	    queue_signals();
 	    d = finddir(args[n]);
 	    if(d) {
@@ -2969,7 +2969,7 @@
 	    unqueue_signals();
 	}
     }
-
+    
     /* -o and -O -- sort the arguments */
     if (ops['o']) {
 	if (fmt && !*args) return 0;
@@ -3074,9 +3074,11 @@
 	    } while (*ap);
 	    fputc(ops['N'] ? '\0' : '\n', fout);
 	}
-	if (fout != stdout)
-	    fclose(fout);
-	return 0;
+	if (((fout != stdout) ? fclose(fout) : fflush(fout)) != 0) {
+            zwarnnam(name, "write error: %e", NULL, errno);
+            ret = 1;
+        }
+	return ret;
     }
     
     /* normal output */
@@ -3088,9 +3090,12 @@
 	}
 	if (!(ops['n'] || nnl))
 	    fputc(ops['N'] ? '\0' : '\n', fout);
-	if (fout != stdout)
-	    fclose(fout);
-	return 0;
+	if (((fout != stdout) ? fclose(fout) : fflush(fout)) != 0) {
+            zwarnnam(name, "write error: %e", NULL, errno);
+            ret = 1;
+	}
+	
+	return ret;
     }
     
     /* printf style output */
@@ -3128,7 +3133,7 @@
 		    DPUTS(narg <= 0, "specified zero or negative arg");
 		    if (narg > argc) {
 		    	zwarnnam(name, "%d: argument specifier out of range",
-			    0, narg);
+				 0, narg);
 			return 1;
 		    } else {
 		    	if (narg > maxarg) maxarg = narg;
@@ -3158,8 +3163,8 @@
 		    	c = endptr + 1;
 			if (narg > argc || narg <= 0) {
 		    	    zwarnnam(name,
-			    	"%d: argument specifier out of range",
-				0, narg);
+				     "%d: argument specifier out of range",
+				     0, narg);
 			    return 1;
 			} else {
 		    	    if (narg > maxarg) maxarg = narg;
@@ -3185,8 +3190,8 @@
 			    c = endptr + 1;
 			    if (narg > argc || narg <= 0) {
 		    		zwarnnam(name,
-				    "%d: argument specifier out of range",
-				    0, narg);
+					 "%d: argument specifier out of range",
+					 0, narg);
 				return 1;
 			    } else {
 		    		if (narg > maxarg) maxarg = narg;
@@ -3274,8 +3279,9 @@
 		}
 		zwarnnam(name, "%s: invalid directive", start, 0);
 		if (*c) c[1] = save;
-		if (fout != stdout)
-		    fclose(fout);
+		if (((fout != stdout) ? fclose(fout) : fflush(fout)) != 0) {
+	            zwarnnam(name, "write error: %e", NULL, errno);
+	        }
 		return 1;
 	    }
 
@@ -3302,7 +3308,7 @@
 			    ret = 1;
 			}
 			print_val(zlongval)
-			break;
+			    break;
 		    case 2:
 			if (curarg) {
 			    mnumval = matheval(curarg);
@@ -3315,7 +3321,7 @@
 			    ret = 1;
 			}
 			print_val(doubleval)
-			break;
+			    break;
 		    case 3:
 #ifdef ZSH_64_BIT_UTYPE
  		    	*d++ = 'l';
@@ -3328,7 +3334,7 @@
 			    ret = 1;
 			}
 			print_val(zulongval)
-		    }
+			    }
 		}
 	    }
 	    if (maxarg && (args - first > maxarg))
@@ -3336,11 +3342,13 @@
 	}
 
     	if (maxarg) args = first + maxarg;
-    /* if there are remaining args, reuse format string */
+	/* if there are remaining args, reuse format string */
     } while (*args && args != first && !ops['r']);
 
-    if (fout != stdout)
-	fclose(fout);
+    if (((fout != stdout) ? fclose(fout) : fflush(fout)) != 0) {
+        zwarnnam(name, "write error: %e", NULL, errno);
+        ret = 1;
+    }
     return ret;
 }
 
@@ -3450,7 +3458,7 @@
     /* check for legality */
     if(opch == ':' || !(p = memchr(optstr, opch, lenoptstr))) {
 	p = "?";
-err:
+    err:
 	zsfree(zoptarg);
 	setsparam(var, ztrdup(p));
 	if(quiet) {
@@ -3620,7 +3628,7 @@
 	}
     }
     if (from_where == 2 || (in_exit++ && from_where))
-	    return;
+	return;
 
     if (isset(MONITOR)) {
 	/* send SIGHUP to any jobs left running  */
@@ -3954,9 +3962,9 @@
     }
 
     /* All possible special types of input have been exhausted.  Take one line,
-    and assign words to the parameters until they run out.  Leftover words go
-    onto the last parameter.  If an array is specified, all the words become
-    separate elements of the array. */
+       and assign words to the parameters until they run out.  Leftover words go
+       onto the last parameter.  If an array is specified, all the words become
+       separate elements of the array. */
 
     zbuforig = zbuf = (!ops['z']) ? NULL :
 	(nonempty(bufstack)) ? (char *) getlinknode(bufstack) : ztrdup("");
@@ -4070,7 +4078,7 @@
 	for (;;) {
 	    c = zread(izle, &readchar);
 	    /* \ at the end of a line introduces a continuation line, except in
-	    raw mode (-r option) */
+	       raw mode (-r option) */
 	    if (bslash && c == '\n') {
 		bslash = 0;
 		continue;
@@ -4147,8 +4155,8 @@
     /* use zbuf if possible */
     if (zbuf) {
 	/* If zbuf points to anything, it points to the next character in the
-	buffer.  This may be a null byte to indicate EOF.  If reading from the
-	buffer, move on the buffer pointer. */
+	   buffer.  This may be a null byte to indicate EOF.  If reading from the
+	   buffer, move on the buffer pointer. */
 	if (*zbuf == Meta)
 	    return zbuf++, STOUC(*zbuf++ ^ 32);
 	else
@@ -4170,21 +4178,21 @@
 #if defined(EAGAIN) || defined(EWOULDBLOCK)
 	    if (!retry && readfd == 0 && (
 # ifdef EAGAIN
-		    errno == EAGAIN
+		errno == EAGAIN
 #  ifdef EWOULDBLOCK
-		    ||
+		||
 #  endif /* EWOULDBLOCK */
 # endif /* EAGAIN */
 # ifdef EWOULDBLOCK
-		    errno == EWOULDBLOCK
+		errno == EWOULDBLOCK
 # endif /* EWOULDBLOCK */
 		) && setblock_stdin()) {
 		retry = 1;
 		continue;
 	    } else
 #endif /* EAGAIN || EWOULDBLOCK */
-	    if (errno == EINTR && !(errflag || retflag || breaks || contflag))
-		continue;
+		if (errno == EINTR && !(errflag || retflag || breaks || contflag))
+		    continue;
 	    break;
 	}
 	return EOF;
@@ -4456,10 +4464,10 @@
 	int whomask, umaskop, mask;
 
 	/* More than one symbolic argument may be used at once, each separated
-	by commas. */
+	   by commas. */
 	for (;;) {
 	    /* First part of the argument -- who does this apply to?
-	    u=owner, g=group, o=other. */
+	       u=owner, g=group, o=other. */
 	    whomask = 0;
 	    while (*s == 'u' || *s == 'g' || *s == 'o' || *s == 'a')
 		if (*s == 'u')



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