[CRT]
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 13 Oct 2014 17:50:17 +0000 (17:50 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 13 Oct 2014 17:50:17 +0000 (17:50 +0000)
* Update setvbuf() and ungetc().
* Fixes some msvcrt:file tests.
CORE-8540

svn path=/trunk/; revision=64731

reactos/lib/sdk/crt/stdio/file.c

index 4bb99da..1b673bc 100644 (file)
@@ -3674,23 +3674,39 @@ int CDECL _wrename(const wchar_t *oldpath,const wchar_t *newpath)
  */
 int CDECL setvbuf(FILE* file, char *buf, int mode, size_t size)
 {
-  _lock_file(file);
-  if(file->_bufsiz) {
-       free(file->_base);
-       file->_bufsiz = 0;
-       file->_cnt = 0;
-  }
-  if(mode == _IOFBF) {
-       file->_flag &= ~_IONBF;
-       file->_base = file->_ptr = buf;
-       if(buf) {
-               file->_bufsiz = size;
-       }
-  } else {
-       file->_flag |= _IONBF;
-  }
-  _unlock_file(file);
-  return 0;
+    if(!MSVCRT_CHECK_PMT(file != NULL)) return -1;
+    if(!MSVCRT_CHECK_PMT(mode==_IONBF || mode==_IOFBF || mode==_IOLBF)) return -1;
+    if(!MSVCRT_CHECK_PMT(mode==_IONBF || (size>=2 && size<=INT_MAX))) return -1;
+
+    _lock_file(file);
+
+    fflush(file);
+    if(file->_flag & _IOMYBUF)
+        free(file->_base);
+    file->_flag &= ~(_IONBF | _IOMYBUF | _USERBUF);
+    file->_cnt = 0;
+
+    if(mode == _IONBF) {
+        file->_flag |= _IONBF;
+        file->_base = file->_ptr = (char*)&file->_charbuf;
+        file->_bufsiz = 2;
+    }else if(buf) {
+        file->_base = file->_ptr = buf;
+        file->_flag |= _USERBUF;
+        file->_bufsiz = size;
+    }else {
+        file->_base = file->_ptr = malloc(size);
+        if(!file->_base) {
+            file->_bufsiz = 0;
+            _unlock_file(file);
+            return -1;
+        }
+
+        file->_flag |= _IOMYBUF;
+        file->_bufsiz = size;
+    }
+    _unlock_file(file);
+    return 0;
 }
 
 /*********************************************************************
@@ -3798,12 +3814,18 @@ FILE* CDECL tmpfile(void)
  */
 int CDECL ungetc(int c, FILE * file)
 {
-    if (c == EOF)
+    if(!MSVCRT_CHECK_PMT(file != NULL)) return EOF;
+
+    if (c == EOF || !(file->_flag&_IOREAD ||
+                (file->_flag&_IORW && !(file->_flag&_IOWRT))))
         return EOF;
 
     _lock_file(file);
-    if(file->_bufsiz == 0 && alloc_buffer(file))
+    if((!(file->_flag & (_IONBF | _IOMYBUF | _USERBUF))
+                && alloc_buffer(file))
+            || (!file->_cnt && file->_ptr==file->_base))
         file->_ptr++;
+
     if(file->_ptr>file->_base) {
         file->_ptr--;
         if(file->_flag & _IOSTRG) {
@@ -3817,6 +3839,7 @@ int CDECL ungetc(int c, FILE * file)
         }
         file->_cnt++;
         clearerr(file);
+        file->_flag |= _IOREAD;
         _unlock_file(file);
         return c;
     }