| 
					
				 | 
			
			
				@@ -10,6 +10,11 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <unistd.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <priv-vars.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline int __feof_or_error(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return !!(stream->flags & (FILE_ERROR | FILE_EOF)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // where n is in the range of [0, 9] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline char d_to_c(int32_t n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -649,9 +654,19 @@ open_fail: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int fflush(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (__feof_or_error(stream)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (stream->wbuf && stream->wpos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (write(stream->fd, stream->wbuf, stream->wpos) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int ret = write(stream->fd, stream->wbuf, stream->wpos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream->flags |= FILE_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ret == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream->flags |= FILE_EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         stream->wpos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -707,9 +722,13 @@ int fputs(const char* s, FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline int __fillbuf(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // TODO: set EOF flag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if ((stream->rcnt = read(stream->fd, stream->rbuf, stream->rbsz)) >= 2147483648U) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         stream->rcnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stream->flags |= FILE_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stream->rcnt == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stream->flags |= FILE_EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     stream->rpos = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -718,6 +737,9 @@ static inline int __fillbuf(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int getc_unlocked(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (__feof_or_error(stream)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (stream->rbuf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (stream->rpos == stream->rcnt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (__fillbuf(stream) < 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -726,23 +748,34 @@ int getc_unlocked(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return stream->rbuf[stream->rpos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         int c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO: set EOF on error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (read(stream->fd, &c, 1) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int ret = read(stream->fd, &c, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream->flags |= FILE_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ret == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream->flags |= FILE_EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int putc_unlocked(int c, FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (__feof_or_error(stream)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (stream->wbuf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         stream->wbuf[stream->wpos++] = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (stream->wpos == stream->wbsz || c == '\n') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fflush(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (fflush(stream) == EOF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO: set EOF on error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (write(stream->fd, &c, 1) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (write(stream->fd, &c, 1) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream->flags |= FILE_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return c; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -757,3 +790,18 @@ int fgetc(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return getc_unlocked(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int ferror(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return stream->flags & FILE_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int feof(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return stream->flags & FILE_EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void clearerr(FILE* stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stream->flags &= ~FILE_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |