/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
- * 2012, 2013
+ * 2012, 2013, 2015
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
#include "sh.h"
-__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.62 2013/10/09 11:59:30 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.62.2.2 2015/03/01 15:43:07 tg Exp $");
/* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */
if (shf->fd >= 0) {
ret = shf_flush(shf);
if (close(shf->fd) < 0)
- ret = EOF;
+ ret = -1;
}
if (shf->flags & SHF_ALLOCS)
afree(shf, shf->areap);
if (shf->fd >= 0) {
ret = shf_flush(shf);
if (close(shf->fd) < 0)
- ret = EOF;
+ ret = -1;
shf->rnleft = 0;
shf->rp = shf->buf;
shf->wnleft = 0;
/*
* Un-read what has been read but not examined, or write what has been
- * buffered. Returns 0 for success, EOF for (write) error.
+ * buffered. Returns 0 for success, -1 for (write) error.
*/
int
shf_flush(struct shf *shf)
{
if (shf->flags & SHF_STRING)
- return ((shf->flags & SHF_WR) ? EOF : 0);
+ return ((shf->flags & SHF_WR) ? -1 : 0);
if (shf->fd < 0)
internal_errorf("%s: %s", "shf_flush", "no fd");
if (shf->flags & SHF_ERROR) {
errno = shf->errnosv;
- return (EOF);
+ return (-1);
}
if (shf->flags & SHF_READING) {
/*
* Write out any buffered data. If currently reading, flushes the read
- * buffer. Returns 0 for success, EOF for (write) error.
+ * buffer. Returns 0 for success, -1 for (write) error.
*/
static int
shf_emptybuf(struct shf *shf, int flags)
if (shf->flags & SHF_ERROR) {
errno = shf->errnosv;
- return (EOF);
+ return (-1);
}
if (shf->flags & SHF_READING) {
*/
if (!(flags & EB_GROW) || !(shf->flags & SHF_DYNAMIC) ||
!(shf->flags & SHF_ALLOCB))
- return (EOF);
+ return (-1);
/* allocate more space for buffer */
nbuf = aresize2(shf->buf, 2, shf->wbsize, shf->areap);
shf->rp = nbuf + (shf->rp - shf->buf);
ntowrite);
shf->wp = shf->buf + ntowrite;
}
- return (EOF);
+ return (-1);
}
buf += n;
ntowrite -= n;
return (ret);
}
-/* Fill up a read buffer. Returns EOF for a read error, 0 otherwise. */
+/* Fill up a read buffer. Returns -1 for a read error, 0 otherwise. */
static int
shf_fillbuf(struct shf *shf)
{
if (shf->flags & (SHF_EOF | SHF_ERROR)) {
if (shf->flags & SHF_ERROR)
errno = shf->errnosv;
- return (EOF);
+ return (-1);
}
- if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == EOF)
- return (EOF);
+ if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == -1)
+ return (-1);
shf->flags |= SHF_READING;
shf->errnosv = errno;
shf->rnleft = 0;
shf->rp = shf->buf;
- return (EOF);
+ return (-1);
}
if ((shf->rnleft = n) == 0)
shf->flags |= SHF_EOF;
/*
* Read a buffer from shf. Returns the number of bytes read into buf, if
- * no bytes were read, returns 0 if end of file was seen, EOF if a read
+ * no bytes were read, returns 0 if end of file was seen, -1 if a read
* error occurred.
*/
ssize_t
while (bsize > 0) {
if (shf->rnleft == 0 &&
- (shf_fillbuf(shf) == EOF || shf->rnleft == 0))
+ (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
break;
ncopy = shf->rnleft;
if (ncopy > bsize)
shf->rnleft -= ncopy;
}
/* Note: fread(3S) returns 0 for errors - this doesn't */
- return (orig_bsize == bsize ? (shf_error(shf) ? EOF : 0) :
+ return (orig_bsize == bsize ? (shf_error(shf) ? -1 : 0) :
orig_bsize - bsize);
}
/*
- * Read up to a newline or EOF. The newline is put in buf; buf is always
+ * Read up to a newline or -1. The newline is put in buf; buf is always
* NUL terminated. Returns NULL on read error or if nothing was read
* before end of file, returns a pointer to the NUL byte in buf
* otherwise.
--bsize;
do {
if (shf->rnleft == 0) {
- if (shf_fillbuf(shf) == EOF)
+ if (shf_fillbuf(shf) == -1)
return (NULL);
if (shf->rnleft == 0) {
*buf = '\0';
return (buf);
}
-/* Returns the char read. Returns EOF for error and end of file. */
+/* Returns the char read. Returns -1 for error and end of file. */
int
shf_getchar(struct shf *shf)
{
if (!(shf->flags & SHF_RD))
internal_errorf("%s: flags 0x%X", "shf_getchar", shf->flags);
- if (shf->rnleft == 0 && (shf_fillbuf(shf) == EOF || shf->rnleft == 0))
- return (EOF);
+ if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
+ return (-1);
--shf->rnleft;
return (*shf->rp++);
}
/*
* Put a character back in the input stream. Returns the character if
- * successful, EOF if there is no room.
+ * successful, -1 if there is no room.
*/
int
shf_ungetc(int c, struct shf *shf)
if (!(shf->flags & SHF_RD))
internal_errorf("%s: flags 0x%X", "shf_ungetc", shf->flags);
- if ((shf->flags & SHF_ERROR) || c == EOF ||
+ if ((shf->flags & SHF_ERROR) || c == -1 ||
(shf->rp == shf->buf && shf->rnleft))
- return (EOF);
+ return (-1);
- if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == EOF)
- return (EOF);
+ if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == -1)
+ return (-1);
if (shf->rp == shf->buf)
shf->rp = shf->buf + shf->rbsize;
* we don't want to modify a string.
*/
if ((int)(shf->rp[-1]) != c)
- return (EOF);
+ return (-1);
shf->flags &= ~SHF_EOF;
shf->rp--;
shf->rnleft++;
}
/*
- * Write a character. Returns the character if successful, EOF if the
+ * Write a character. Returns the character if successful, -1 if the
* char could not be written.
*/
int
if (!(shf->flags & SHF_WR))
internal_errorf("%s: flags 0x%X", "shf_putchar", shf->flags);
- if (c == EOF)
- return (EOF);
+ if (c == -1)
+ return (-1);
if (shf->flags & SHF_UNBUF) {
unsigned char cc = (unsigned char)c;
internal_errorf("%s: %s", "shf_putchar", "no fd");
if (shf->flags & SHF_ERROR) {
errno = shf->errnosv;
- return (EOF);
+ return (-1);
}
while ((n = write(shf->fd, &cc, 1)) != 1)
if (n < 0) {
continue;
shf->flags |= SHF_ERROR;
shf->errnosv = errno;
- return (EOF);
+ return (-1);
}
} else {
/* Flush deals with strings and sticky errors */
- if (shf->wnleft == 0 && shf_emptybuf(shf, EB_GROW) == EOF)
- return (EOF);
+ if (shf->wnleft == 0 && shf_emptybuf(shf, EB_GROW) == -1)
+ return (-1);
shf->wnleft--;
*shf->wp++ = c;
}
}
/*
- * Write a string. Returns the length of the string if successful, EOF
+ * Write a string. Returns the length of the string if successful, -1
* if the string could not be written.
*/
ssize_t
shf_puts(const char *s, struct shf *shf)
{
if (!s)
- return (EOF);
+ return (-1);
return (shf_write(s, strlen(s), shf));
}
-/* Write a buffer. Returns nbytes if successful, EOF if there is an error. */
+/* Write a buffer. Returns nbytes if successful, -1 if there is an error. */
ssize_t
shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
{
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);
+ if (shf_emptybuf(shf, EB_GROW) == -1)
+ return (-1);
/* then write everything into the buffer */
} else {
/* flush deals with sticky errors */
- if (shf_emptybuf(shf, EB_GROW) == EOF)
- return (EOF);
+ if (shf_emptybuf(shf, EB_GROW) == -1)
+ return (-1);
/* write chunks larger than window size directly */
if (nbytes > shf->wbsize) {
ncopy = nbytes;
* Note: fwrite(3) returns 0
* for errors - this doesn't
*/
- return (EOF);
+ return (-1);
}
buf += n;
ncopy -= n;
ssize_t field, precision, len;
unsigned long lnum;
/* %#o produces the longest output */
- char numbuf[(8 * sizeof(long) + 2) / 3 + 1
-#ifdef DEBUG
- /* a NUL for LLVM/Clang scan-build */
- + 1
-#endif
- ];
+ char numbuf[(8 * sizeof(long) + 2) / 3 + 1];
/* this stuff for dealing with the buffer */
ssize_t nwritten = 0;
integral:
flags |= FL_NUMBER;
cp = numbuf + sizeof(numbuf);
-#ifdef DEBUG
- /*
- * this is necessary so Clang 3.2 realises
- * utf_skipcols/shf_putc in the output loop
- * terminate; these values are always ASCII
- * so an out-of-bounds access cannot happen
- * but Clang doesn't know that
- */
- *--cp = '\0';
-#endif
switch (c) {
case 'd':
}
}
len = numbuf + sizeof(numbuf) - (s = cp);
-#ifdef DEBUG
- /* see above comment for Clang 3.2 */
- --len;
-#endif
if (flags & FL_DOT) {
if (precision > len) {
field = precision;
}
}
- return (shf_error(shf) ? EOF : nwritten);
+ return (shf_error(shf) ? -1 : nwritten);
}
#if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST)