diff options
| author | Andrey A. Chernov <ache@FreeBSD.org> | 2015-11-08 13:37:16 +0000 | 
|---|---|---|
| committer | Andrey A. Chernov <ache@FreeBSD.org> | 2015-11-08 13:37:16 +0000 | 
| commit | 8ebe0f53597789057018d353c2b38b45470ea16e (patch) | |
| tree | 20f498bd623fab85c76c978a69e059c9bda125d0 | |
| parent | 70e3999d1cb81db14d8c144b945943879b103f42 (diff) | |
Notes
| -rw-r--r-- | include/stdio.h | 3 | ||||
| -rw-r--r-- | lib/libc/stdio/fdopen.c | 4 | ||||
| -rw-r--r-- | lib/libc/stdio/findfp.c | 1 | ||||
| -rw-r--r-- | lib/libc/stdio/fmemopen.c | 3 | ||||
| -rw-r--r-- | lib/libc/stdio/fopen.c | 4 | ||||
| -rw-r--r-- | lib/libc/stdio/freopen.c | 5 | ||||
| -rw-r--r-- | lib/libc/stdio/ftell.c | 41 | ||||
| -rw-r--r-- | lib/libc/stdio/stdio.c | 2 | 
8 files changed, 40 insertions, 23 deletions
diff --git a/include/stdio.h b/include/stdio.h index 6d7916aaacb7a..d37ea06d925e2 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -144,6 +144,7 @@ struct __sFILE {  	int	_fl_count;	/* recursive lock count */  	int	_orientation;	/* orientation for fwide() */  	__mbstate_t _mbstate;	/* multibyte conversion state */ +	int	_flags2;	/* additional flags */  };  #ifndef _STDFILE_DECLARED  #define _STDFILE_DECLARED @@ -176,6 +177,8 @@ __END_DECLS  #define	__SALC	0x4000		/* allocate string space dynamically */  #define	__SIGN	0x8000		/* ignore this file in _fwalk */ +#define	__S2OAP	0x0001		/* O_APPEND mode is set */ +  /*   * The following three definitions are for ANSI C, which took them   * from System V, which brilliantly took internal interface macros and diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c index 2e19b9febcd8b..e5d167a317d7b 100644 --- a/lib/libc/stdio/fdopen.c +++ b/lib/libc/stdio/fdopen.c @@ -90,7 +90,9 @@ fdopen(int fd, const char *mode)  	 * O_APPEND bit set, assert __SAPP so that __swrite() caller  	 * will _sseek() to the end before write.  	 */ -	if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) +	if (fdflags & O_APPEND) +		fp->_flags2 |= __S2OAP; +	else if (oflags & O_APPEND)  		fp->_flags |= __SAPP;  	fp->_file = fd;  	fp->_cookie = fp; diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index be196b73c687b..12d36594200fa 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -155,6 +155,7 @@ found:  /*	fp->_fl_mutex = NULL; */ /* once set always set (reused) */  	fp->_orientation = 0;  	memset(&fp->_mbstate, 0, sizeof(mbstate_t)); +	fp->_flags2 = 0;  	return (fp);  } diff --git a/lib/libc/stdio/fmemopen.c b/lib/libc/stdio/fmemopen.c index ebd3596be7751..bcf187d200294 100644 --- a/lib/libc/stdio/fmemopen.c +++ b/lib/libc/stdio/fmemopen.c @@ -149,6 +149,9 @@ fmemopen(void * __restrict buf, size_t size, const char * __restrict mode)  		return (NULL);  	} +	if (mode[0] == 'a') +		f->_flags |= __SAPP; +  	/*  	 * Turn off buffering, so a write past the end of the buffer  	 * correctly returns a short object count. diff --git a/lib/libc/stdio/fopen.c b/lib/libc/stdio/fopen.c index b08e3366ac68d..9ab61ba157a42 100644 --- a/lib/libc/stdio/fopen.c +++ b/lib/libc/stdio/fopen.c @@ -91,7 +91,9 @@ fopen(const char * __restrict file, const char * __restrict mode)  	 * we can do about this.  (We could set __SAPP and check in  	 * fseek and ftell.)  	 */ -	if (oflags & O_APPEND) +	if (oflags & O_APPEND) { +		fp->_flags2 |= __S2OAP;  		(void)_sseek(fp, (fpos_t)0, SEEK_END); +	}  	return (fp);  } diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c index bf3f0304a2ba4..58227fa4b9de3 100644 --- a/lib/libc/stdio/freopen.c +++ b/lib/libc/stdio/freopen.c @@ -186,6 +186,7 @@ finish:  	fp->_lb._size = 0;  	fp->_orientation = 0;  	memset(&fp->_mbstate, 0, sizeof(mbstate_t)); +	fp->_flags2 = 0;  	if (f < 0) {			/* did not get it after all */  		if (isopen) @@ -239,8 +240,10 @@ finish:  	 * we can do about this.  (We could set __SAPP and check in  	 * fseek and ftell.)  	 */ -	if (oflags & O_APPEND) +	if (oflags & O_APPEND) { +		fp->_flags2 |= __S2OAP;  		(void) _sseek(fp, (fpos_t)0, SEEK_END); +	}  	FUNLOCKFILE(fp);  	return (fp);  } diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c index 745d500513d9f..152617f500a03 100644 --- a/lib/libc/stdio/ftell.c +++ b/lib/libc/stdio/ftell.c @@ -88,7 +88,6 @@ _ftello(FILE *fp, fpos_t *offset)  {  	fpos_t pos;  	size_t n; -	int dflags;  	if (fp->_seek == NULL) {  		errno = ESPIPE;			/* historic practice */ @@ -119,29 +118,33 @@ _ftello(FILE *fp, fpos_t *offset)  		}  		if (HASUB(fp))  			pos -= fp->_r;  /* Can be negative at this point. */ -	} else if ((fp->_flags & __SWR) && fp->_p != NULL) { -		dflags = 0; -		if (fp->_flags & __SAPP) -			dflags = O_APPEND; -		else if (fp->_file != -1 && -			 (dflags = _fcntl(fp->_file, F_GETFL)) < 0) -			return (1); -		if ((dflags & O_APPEND) && -		    (pos = _sseek(fp, (fpos_t)0, SEEK_END)) == -1) { -			if ((fp->_flags & __SOPT) || __sflush(fp) || -			    (pos = _sseek(fp, (fpos_t)0, SEEK_CUR)) == -1) -				return (1); -			else { -				*offset = pos; -				return (0); -			} -		} +	} else if ((fp->_flags & __SWR) && fp->_p != NULL && +	    (n = fp->_p - fp->_bf._base) > 0) {  		/*  		 * Writing.  Any buffered characters cause the  		 * position to be greater than that in the  		 * underlying object.  		 */ -		n = fp->_p - fp->_bf._base; +		if ((fp->_flags & __SAPP) || (fp->_flags2 & __S2OAP)) { +			int serrno = errno; + +			errno = 0; +			if ((pos = _sseek(fp, (fpos_t)0, SEEK_END)) == -1) { +				if (errno == ESPIPE || +				    (fp->_flags & __SOPT) || __sflush(fp) || +				    (pos = +				    _sseek(fp, (fpos_t)0, SEEK_CUR)) == -1) +					return (1); +				else { +					errno = serrno; +					*offset = pos; +					return (0); +				} +			} +			errno = serrno; +			/* fp->_p can be changed in _sseek(), recalculate. */ +			n = fp->_p - fp->_bf._base; +		}  		if (pos > OFF_MAX - n) {  			errno = EOVERFLOW;  			return (1); diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c index 44ee0ab412108..5d6fb9ac56442 100644 --- a/lib/libc/stdio/stdio.c +++ b/lib/libc/stdio/stdio.c @@ -117,7 +117,7 @@ _swrite(FILE *fp, char const *buf, int n)  	ret = (*fp->_write)(fp->_cookie, buf, n);  	/* __SOFF removed even on success in case O_APPEND mode is set. */  	if (ret >= 0) { -		if ((fp->_flags & (__SAPP|__SOFF)) == (__SAPP|__SOFF) && +		if ((fp->_flags & __SOFF) && !(fp->_flags2 & __S2OAP) &&  		    fp->_offset <= OFF_MAX - ret)  			fp->_offset += ret;  		else  | 
