From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21755 invoked from network); 27 Jan 2002 22:42:43 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 27 Jan 2002 22:42:43 -0000 Received: (qmail 9974 invoked by alias); 27 Jan 2002 22:42:37 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 16503 Received: (qmail 9961 invoked from network); 27 Jan 2002 22:42:36 -0000 Date: Sun, 27 Jan 2002 17:42:29 -0500 From: Clint Adams To: Bart Schaefer Cc: zsh-workers@sunsite.dk Subject: Re: [tbm@cyrius.com: Bug#130817: zsh's echo doesn't error if device is full] Message-ID: <20020127224229.GB1577@dman.com> References: <20020127202152.GA32151@dman.com> <1020127214609.ZM9457@candle.brasslantern.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1020127214609.ZM9457@candle.brasslantern.com> User-Agent: Mutt/1.3.25i > 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')