update for HEAD-2003021201
[reactos.git] / lib / crtdll / stdio / filbuf.c
1 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
2 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
3 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
4
5 #include <msvcrt/stdio.h>
6 #include <msvcrt/sys/types.h>
7 #include <msvcrt/stdlib.h>
8 #include <msvcrt/string.h>
9 #include <msvcrt/internal/file.h>
10 #include <msvcrt/io.h>
11 #include <msvcrt/wchar.h>
12 #include <msvcrt/errno.h>
13
14 int _readcnv(int fn, void *buf, size_t siz  );
15
16 int
17 _filbuf(FILE *f)
18 {
19   int size;
20   char c;
21
22  
23   if ( !OPEN4READING(f)) {
24         __set_errno (EINVAL);
25         return EOF;
26   }
27
28
29   if (f->_flag&(_IOSTRG|_IOEOF))
30     return EOF;
31   f->_flag &= ~_IOUNGETC;
32
33   if (f->_base==NULL && (f->_flag&_IONBF)==0) {
34     size = 4096;
35     if ((f->_base = malloc(size+1)) == NULL)
36     {
37         // error ENOMEM
38       f->_flag |= _IONBF;
39       f->_flag &= ~(_IOFBF|_IOLBF);
40     }
41     else
42     {
43       f->_flag |= _IOMYBUF;
44       f->_bufsiz = size;
45     }
46   }
47
48
49   if (f->_flag&_IONBF)
50     f->_base = &c;
51
52
53 // fush stdout before reading from stdin 
54   if (f == stdin) {
55     if (stdout->_flag&_IOLBF)
56       fflush(stdout);
57     if (stderr->_flag&_IOLBF)
58       fflush(stderr);
59   }
60
61 // if we have a dirty stream we flush it
62   if ( (f->_flag &_IODIRTY) == _IODIRTY )
63          fflush(f);
64
65
66
67   f->_cnt = _read(fileno(f), f->_base, f->_flag & _IONBF ? 1 : f->_bufsiz  );
68   f->_flag |= _IOAHEAD;
69
70   if(__is_text_file(f) && f->_cnt>0)
71   {
72     /* truncate text file at Ctrl-Z */
73     char *cz=memchr(f->_base, 0x1A, f->_cnt);
74     if(cz)
75     {
76       int newcnt = cz - f->_base;
77       lseek(fileno(f), -(f->_cnt - newcnt), SEEK_CUR);
78       f->_cnt = newcnt;
79     }
80   }
81
82   f->_ptr = f->_base;
83
84   if (f->_flag & _IONBF) 
85      f->_base = NULL; // statically allocated buffer for sprintf
86   
87
88 //check for error
89   if (--f->_cnt < 0) {
90     if (f->_cnt == -1) {
91       f->_flag |= _IOEOF;
92     } else
93       f->_flag |= _IOERR;
94     f->_cnt = 0;
95
96 // should set errno 
97
98     return EOF;
99   }
100
101   f->_cnt--;
102   return *f->_ptr++ & 0377;
103 }
104
105 wint_t  _filwbuf(FILE *fp)
106 {
107         return (wint_t )_filbuf(fp);
108 }
109
110 // convert the carriage return line feed pairs
111
112 int _readcnv(int fn, void *buf, size_t siz  )
113 {
114         char *bufp = (char *)buf;
115         int _bufsiz = siz;
116         int cr = 0;
117         int n;
118
119         n = _read(fn, buf, siz  );
120
121         while (_bufsiz > 0) {
122                 if (*bufp == '\r') 
123                         cr++;
124                 else if ( cr != 0 ) 
125                         *bufp = *(bufp + cr);
126                 bufp++;
127                 _bufsiz--;
128         }
129         return n + cr;
130 }
131