*sigh* this code is interesting: assume you want to output via shf to
a string buffer whose window size is currently 32 (initial), your data is 96 bytes, this routine used to resize the buffer to 64, append your first 64 bytes to it (no matter if there's already something in it) and then writes the remaining bytes to stdio fd instead of the string… if it doesn’t SIGABRT before discovered by wbx@ – thanks – bug inherited from pdksh 5.2.14 (AD 1999)
This commit is contained in:
57
shf.c
57
shf.c
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.35 2009/11/28 14:28:03 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.36 2010/07/19 22:41:04 tg Exp $");
|
||||
|
||||
/* flags to shf_emptybuf() */
|
||||
#define EB_READSW 0x01 /* about to switch to reading */
|
||||
@@ -636,32 +636,45 @@ shf_write(const char *buf, int nbytes, struct shf *shf)
|
||||
shf->wnleft -= ncopy;
|
||||
}
|
||||
if (nbytes > 0) {
|
||||
/* Flush deals with strings and sticky errors */
|
||||
if (shf_emptybuf(shf, EB_GROW) == EOF)
|
||||
return (EOF);
|
||||
if (nbytes > shf->wbsize) {
|
||||
ncopy = nbytes;
|
||||
if (shf->wbsize)
|
||||
ncopy -= nbytes % shf->wbsize;
|
||||
nbytes -= ncopy;
|
||||
while (ncopy > 0) {
|
||||
n = write(shf->fd, buf, ncopy);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR &&
|
||||
!(shf->flags & SHF_INTERRUPT))
|
||||
continue;
|
||||
shf->flags |= SHF_ERROR;
|
||||
shf->errno_ = errno;
|
||||
shf->wnleft = 0;
|
||||
/* Note: fwrite(3S) returns 0 for
|
||||
* errors - this doesn't */
|
||||
if (shf->flags & SHF_STRING) {
|
||||
/* resize buffer until there's enough space left */
|
||||
while (nbytes > shf->wnleft)
|
||||
if (shf_emptybuf(shf, EB_GROW) == EOF)
|
||||
return (EOF);
|
||||
/* then write everything into the buffer */
|
||||
} else {
|
||||
/* flush deals with sticky errors */
|
||||
if (shf_emptybuf(shf, EB_GROW) == EOF)
|
||||
return (EOF);
|
||||
/* write chunks larger than window size directly */
|
||||
if (nbytes > shf->wbsize) {
|
||||
ncopy = nbytes;
|
||||
if (shf->wbsize)
|
||||
ncopy -= nbytes % shf->wbsize;
|
||||
nbytes -= ncopy;
|
||||
while (ncopy > 0) {
|
||||
n = write(shf->fd, buf, ncopy);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR &&
|
||||
!(shf->flags & SHF_INTERRUPT))
|
||||
continue;
|
||||
shf->flags |= SHF_ERROR;
|
||||
shf->errno_ = errno;
|
||||
shf->wnleft = 0;
|
||||
/*
|
||||
* Note: fwrite(3) returns 0
|
||||
* for errors - this doesn't
|
||||
*/
|
||||
return (EOF);
|
||||
}
|
||||
buf += n;
|
||||
ncopy -= n;
|
||||
}
|
||||
buf += n;
|
||||
ncopy -= n;
|
||||
}
|
||||
/* ... and buffer the rest */
|
||||
}
|
||||
if (nbytes > 0) {
|
||||
/* write remaining bytes to buffer */
|
||||
memcpy(shf->wp, buf, nbytes);
|
||||
shf->wp += nbytes;
|
||||
shf->wnleft -= nbytes;
|
||||
|
Reference in New Issue
Block a user