• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * This file has no copyright assigned and is placed in the Public Domain.
3  * This file is part of the mingw-w64 runtime package.
4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5  */
6 #include <stdio.h>
7 #include <io.h>
8 #include <errno.h>
9 #include <internal.h>
10 
11 #define _IOYOURBUF      0x0100
12 #define _IOSETVBUF      0x0400
13 #define _IOFEOF         0x0800
14 #define _IOFLRTN        0x1000
15 #define _IOCTRLZ        0x2000
16 #define _IOCOMMIT       0x4000
17 
18 /* General use macros */
19 
20 #define inuse(s)        ((s)->_flag & (_IOREAD|_IOWRT|_IORW))
21 #define mbuf(s)         ((s)->_flag & _IOMYBUF)
22 #define nbuf(s)         ((s)->_flag & _IONBF)
23 #define ybuf(s)         ((s)->_flag & _IOYOURBUF)
24 #define bigbuf(s)       ((s)->_flag & (_IOMYBUF|_IOYOURBUF))
25 #define anybuf(s)       ((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF))
26 
27 #define _INTERNAL_BUFSIZ    4096
28 #define _SMALL_BUFSIZ       512
29 
30 #define FOPEN           0x01    /* file handle open */
31 #define FEOFLAG         0x02    /* end of file has been encountered */
32 #define FCRLF           0x04    /* CR-LF across read buffer (in text mode) */
33 #define FPIPE           0x08    /* file handle refers to a pipe */
34 #define FNOINHERIT      0x10    /* file handle opened _O_NOINHERIT */
35 #define FAPPEND         0x20    /* file handle opened O_APPEND */
36 #define FDEV            0x40    /* file handle refers to device */
37 #define FTEXT           0x80    /* file handle is in text mode */
38 
39 _CRTIMP __int64 __cdecl _lseeki64(int fh,__int64 pos,int mthd);
40 __int64 __cdecl _ftelli64(FILE *str);
41 
42 #if !defined(__arm__) && !defined(__aarch64__) /* we have F_ARM_ANY(_fseeki64) in msvcrt.def.in */
43 int __cdecl _flush (FILE *str);
44 
_flush(FILE * str)45 int __cdecl _flush (FILE *str)
46 {
47   FILE *stream;
48   int rc = 0; /* assume good return */
49   __int64 nchar;
50 
51   stream = str;
52   if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream)
53       && (nchar = (__int64) (stream->_ptr - stream->_base)) > 0ll)
54   {
55     if ( _write(_fileno(stream), stream->_base, nchar) == nchar) {
56       if (_IORW & stream->_flag)
57         stream->_flag &= ~_IOWRT;
58     } else {
59       stream->_flag |= _IOERR;
60       rc = EOF;
61     }
62   }
63   stream->_ptr = stream->_base;
64   stream->_cnt = 0ll;
65   return rc;
66 }
67 
_fseeki64(FILE * str,__int64 offset,int whence)68 int __cdecl _fseeki64(FILE *str,__int64 offset,int whence)
69 {
70         FILE *stream;
71         /* Init stream pointer */
72         stream = str;
73         errno=0;
74         if(!stream || ((whence != SEEK_SET) && (whence != SEEK_CUR) && (whence != SEEK_END)))
75 	{
76 	  errno=EINVAL;
77 	  return -1;
78         }
79         /* Clear EOF flag */
80         stream->_flag &= ~_IOEOF;
81 
82         if (whence == SEEK_CUR) {
83 	  offset += _ftelli64(stream);
84 	  whence = SEEK_SET;
85 	}
86         /* Flush buffer as necessary */
87         _flush(stream);
88 
89         /* If file opened for read/write, clear flags since we don't know
90            what the user is going to do next. If the file was opened for
91            read access only, decrease _bufsiz so that the next _filbuf
92            won't cost quite so much */
93 
94         if (stream->_flag & _IORW)
95                 stream->_flag &= ~(_IOWRT|_IOREAD);
96         else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) &&
97                   !(stream->_flag & _IOSETVBUF) )
98                 stream->_bufsiz = _SMALL_BUFSIZ;
99 
100         /* Seek to the desired locale and return. */
101 
102         return (_lseeki64(_fileno(stream), offset, whence) == -1ll ? -1 : 0);
103 }
104 
105 int __cdecl (*__MINGW_IMP_SYMBOL(_fseeki64))(FILE *, __int64, int) = _fseeki64;
106 #endif /* !defined(__arm__) && !defined(__aarch64__) */
107 
_ftelli64(FILE * str)108 __int64 __cdecl _ftelli64(FILE *str)
109 {
110         FILE *stream;
111         size_t offset;
112         __int64 filepos;
113         register char *p;
114         char *max;
115         int fd;
116         size_t rdcnt = 0;
117 
118 	errno=0;
119         stream = str;
120         fd = _fileno(stream);
121         if (stream->_cnt < 0ll) stream->_cnt = 0ll;
122     if ((filepos = _lseeki64(fd, 0ll, SEEK_CUR)) < 0L)
123       return -1ll;
124 
125     if (!bigbuf(stream))            /* _IONBF or no buffering designated */
126       return (filepos - (__int64) stream->_cnt);
127 
128     offset = (size_t)(stream->_ptr - stream->_base);
129 
130     if (stream->_flag & (_IOWRT|_IOREAD))
131       {
132         if (_osfile(fd) & FTEXT)
133           for (p = stream->_base; p < stream->_ptr; p++)
134             if (*p == '\n')  /* adjust for '\r' */
135               offset++;
136       }
137       else if (!(stream->_flag & _IORW)) {
138         errno=EINVAL;
139         return -1ll;
140       }
141       if (filepos == 0ll)
142         return ((__int64)offset);
143 
144       if (stream->_flag & _IOREAD)    /* go to preceding sector */
145         {
146           if (stream->_cnt == 0ll)  /* filepos holds correct location */
147             offset = 0ll;
148           else
149             {
150 	          rdcnt = ((size_t) stream->_cnt) + ((size_t) (size_t)(stream->_ptr - stream->_base));
151 		      if (_osfile(fd) & FTEXT) {
152 		        if (_lseeki64(fd, 0ll, SEEK_END) == filepos) {
153 			      max = stream->_base + rdcnt;
154 			    for (p = stream->_base; p < max; p++)
155 			      if (*p == '\n') /* adjust for '\r' */
156 			        rdcnt++;
157 			    if (stream->_flag & _IOCTRLZ)
158 			      ++rdcnt;
159 		      } else {
160 		        _lseeki64(fd, filepos, SEEK_SET);
161 		        if ( (rdcnt <= _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) &&
162 		            !(stream->_flag & _IOSETVBUF))
163 			      rdcnt = _SMALL_BUFSIZ;
164 		        else
165 		          rdcnt = stream->_bufsiz;
166 		        if  (_osfile(fd) & FCRLF)
167 		          ++rdcnt;
168 		      }
169 		    } /* end if FTEXT */
170 	    }
171 	  filepos -= (__int64)rdcnt;
172     } /* end else stream->_cnt != 0 */
173   return (filepos + (__int64)offset);
174 }
175 
176 __int64 __cdecl (*__MINGW_IMP_SYMBOL(_ftelli64))(FILE *) = _ftelli64;
177 
178