Bug Summary

File:stlport/unxlngi6.pro/misc/build/STLport-4.5/src/fstream.cpp
Location:line 183, column 5
Description:The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

1/*
2 * Copyright (c) 1999
3 * Silicon Graphics Computer Systems, Inc.
4 *
5 * Copyright (c) 1999
6 * Boris Fomitchev
7 *
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
10 *
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
16 *
17 */
18
19
20# include "stlport_prefix.h"
21
22# if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS)
23# include <time.h>
24// For sunpro, it chokes if time.h is included through stat.h
25# endif
26
27#include <fstream>
28
29#ifdef __CYGWIN__
30# define __int64 long long
31#endif
32
33#if defined (_STLP_USE_UNIX_IO)
34extern "C" {
35// open/close/read/write
36# include <sys/stat.h> // For stat
37# include <sys/mman.h> // For mmap
38
39// on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this
40# if defined (__hpux) && defined (__GNUC__4)
41# undef _INCLUDE_POSIX1C_SOURCE
42# endif
43
44# include <unistd.h>
45# include <fcntl.h>
46}
47# ifdef __APPLE__
48# include <sys/sysctl.h>
49# endif
50#elif defined (_STLP_USE_WIN32_IO)
51# define WIN32_LEAN_AND_MEAN
52# include <windows.h>
53
54# ifdef __BORLANDC__
55# if (__BORLANDC__ > 0x530)
56# include <cfcntl.h> // For _O_RDONLY, etc
57# else
58# include <fcntl.h> // For _O_RDONLY, etc
59# endif
60# include <sys/stat.h> // For _fstat
61# elif !defined(__STL_WINCE)
62# include <io.h> // For _get_osfhandle
63# include <fcntl.h> // For _O_RDONLY, etc
64# include <sys/stat.h> // For _fstat
65# endif
66
67# define _TEXTBUF_SIZE 0x1000
68#elif defined (_STLP_USE_UNIX_EMULATION_IO)
69# if defined( __MSL__ )
70# include <unistd.h>
71# else
72# include <io.h>
73# endif
74# include <fcntl.h>
75# include <sys/stat.h>
76
77#elif defined (_STLP_USE_STDIO_IO)
78# include <cstdio>
79
80# if !(defined(__MRC__) || defined(__SC__) || defined(__ISCPP__) )
81extern "C" {
82# include <sys/stat.h>
83}
84# endif
85# if defined( __MSL__ )
86# include <unix1.h>
87# endif
88# if defined(__ISCPP__)
89# include <c_locale_is/filestat.h>
90# endif
91# if defined(__BEOS__) && defined(__INTEL__)
92# include <fcntl.h>
93# include <sys/stat.h> // For _fstat
94# define _S_IREAD S_IREAD0400
95# define _S_IWRITE S_IWRITE0200
96# define _S_IFREG S_IFREG0100000
97# endif
98#else
99#error "Configure i/o !"
100#endif
101
102// map permission masks
103#if defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
104# ifndef S_IRUSR0400
105# define S_IRUSR0400 _S_IREAD
106# define S_IWUSR0200 _S_IWRITE
107# define S_IRGRP(0400 >> 3) _S_IREAD
108# define S_IWGRP(0200 >> 3) _S_IWRITE
109# define S_IROTH((0400 >> 3) >> 3) _S_IREAD
110# define S_IWOTH((0200 >> 3) >> 3) _S_IWRITE
111# endif
112# ifndef O_RDONLY00
113# define O_RDONLY00 _O_RDONLY
114# define O_WRONLY01 _O_WRONLY
115# define O_RDWR02 _O_RDWR
116# define O_APPEND02000 _O_APPEND
117# define O_CREAT0100 _O_CREAT
118# define O_TRUNC01000 _O_TRUNC
119# define O_TEXT _O_TEXT
120# define O_BINARY _O_BINARY
121# endif
122
123# ifdef __MSL__
124# define _O_TEXT 0x0
125# if !defined( O_TEXT )
126# define O_TEXT _O_TEXT
127# endif
128# define _S_IFREG S_IFREG0100000
129# define S_IREAD0400 S_IRUSR0400
130# define S_IWRITE0200 S_IWUSR0200
131# define S_IEXEC0100 S_IXUSR0100
132# define _S_IWRITE S_IWRITE0200
133# define _S_IREAD S_IREAD0400
134# define _open open
135# define _lseek lseek
136# define _close close
137# define _read read
138# define _write write
139# endif
140
141#endif
142
143#ifndef O_ACCMODE0003
144# define O_ACCMODE0003 (O_RDONLY00|O_WRONLY01|O_RDWR02)
145#endif
146
147#include "fstream_impl.h"
148
149# ifdef _STLP_LONG_LONGlong long
150# define ULL(x)((unsigned long long)x) ((unsigned _STLP_LONG_LONGlong long)x)
151// # elif defined (_MSC_VER) || defined (__BORLANDC__)
152// # define ULL(x) ((__int64)x)
153# elif defined(__MRC__) || defined(__SC__) //*TY 02/25/2000 - added support for MPW compilers
154# include <Math64.h>
155# define ULL(x)((unsigned long long)x) (U64SetU(x))
156# elif defined(__ISCPP__)
157# include "uint64.h"
158# else
159# error "there should be some long long type on the system!"
160# endif
161
162__SGI_BEGIN_NAMESPACEnamespace _SgI {
163
164#if !defined(__MSL__) && !defined(__MRC__) && !defined(__SC__) //*TY 04/15/2000 - exclude mpw compilers also
165ios_base::openmode flag_to_openmode(int mode)
166{
167 ios_base::openmode ret;
1
Variable 'ret' declared without an initial value
168
169 switch(mode & O_ACCMODE0003) {
2
'Default' branch taken. Execution continues on line 182
170
171 case O_RDONLY00:
172 ret = ios_base::in; break;
173
174 case O_WRONLY01:
175 ret = ios_base::out; break;
176
177 case O_RDWR02:
178 ret = ios_base::in | ios_base::out; break;
179
180 }
181
182 if (mode & O_APPEND02000)
3
Assuming 'mode' is & 1024
4
Taking true branch
183 ret |= ios_base::app;
5
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
184
185# ifdef _STLP_USE_WIN32_IO
186 if (mode & O_BINARY)
187 ret |= ios_base::binary;
188# endif // _MSC_VER
189
190 return ret;
191
192}
193# endif /* MSL */
194
195// Helper functions for _Filebuf_base.
196
197bool __is_regular_file(_STLP_fd fd) {
198
199#if defined (_STLP_UNIX1)
200
201 struct stat buf;
202 return fstat(fd, &buf) == 0 && S_ISREG(buf.st_mode)((((buf.st_mode)) & 0170000) == (0100000));
203
204#elif defined(__MRC__) || defined(__SC__) //*TY 02/25/2000 - added support for MPW compilers
205
206 #pragma unused(fd)
207 return true; // each file is a regular file under mac os, isn't it? (we don't have fstat())
208
209#elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
210
211 struct stat buf;
212 return fstat(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0 ;
213
214# elif defined (_STLP_USE_WIN32_IO)
215
216 return (GetFileType(fd) & ~FILE_TYPE_REMOTE) == FILE_TYPE_DISK;
217
218#else
219 (void)fd; // dwa 4/27/00 - suppress unused parameter warning
220 return false;
221
222#endif
223}
224
225// Number of characters in the file.
226streamoff __file_size(_STLP_fd fd) {
227 streamoff ret = 0;
228
229#if defined (_STLP_UNIX1)
230
231 struct stat buf;
232 if(fstat(fd, &buf) == 0 && S_ISREG(buf.st_mode)((((buf.st_mode)) & 0170000) == (0100000)))
233 ret = buf.st_size > 0 ? buf.st_size : 0;
234
235#elif defined(__MRC__) || defined(__SC__) //*TY 02/25/2000 - added support for MPW compilers
236
237 #pragma unused(fd)
238
239#elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
240
241 struct stat buf;
242 if(fstat(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0)
243 ret = buf.st_size > 0 ? buf.st_size : 0;
244
245# elif defined (_STLP_USE_WIN32_IO)
246
247 LARGE_INTEGER li;
248 li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart);
249 if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR )
250 {
251 ret = 0;
252 } else
253 ret = li.QuadPart;
254
255# else
256 (void)fd; // dwa 4/27/00 - suppress unused parameter warning
257# endif
258
259 return ret;
260}
261
262
263// Visual C++ and Intel use this, but not Metrowerks
264// Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version
265#if (!defined(__MSL__) && defined( _MSC_VER ) && defined(_WIN32)) || \
266 (defined(__MINGW32__) && defined(__MSVCRT__))
267
268// fcntl(fileno, F_GETFL) for Microsoft library
269// 'semi-documented' defines:
270#define IOINFO_L2E 5
271#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
272#define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \
273 ((i) & (IOINFO_ARRAY_ELTS - 1)) )
274#define FAPPEND02000 0x20 // O_APPEND flag
275#define FTEXT 0x80 // O_TEXT flag
276// end of 'semi-documented' defines
277
278// fbp : empirical
279#define F_WRITABLE 0x04
280
281// 'semi-documented' internal structure
282extern "C" {
283 struct ioinfo {
284 long osfhnd; // the real os HANDLE
285 char osfile; // file handle flags
286 char pipech; // pipe buffer
287# ifdef _MT
288 // multi-threaded locking
289 int lockinitflag;
290 CRITICAL_SECTION lock;
291# endif /* _MT */
292 };
293#ifdef __MINGW32__
294 __MINGW_IMPORT ioinfo * __pioinfo[];
295#else
296 extern _CRTIMP ioinfo * __pioinfo[];
297#endif
298
299} // extern "C"
300// end of 'semi-documented' declarations
301
302ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
303 char dosflags = 0;
304
305 dosflags = _pioinfo(fd)->osfile;
306 // end of 'semi-documented' stuff
307 int mode = 0;
308
309 if (dosflags & FAPPEND02000)
310 mode |= O_APPEND02000;
311 if (dosflags & FTEXT)
312 mode |= O_TEXT;
313 else
314 mode |= O_BINARY;
315
316 // we have to guess
317# ifdef __macintosh
318 DWORD dummy, dummy2;
319 if (WriteFile(oshandle, &dummy2, 0, &dummy, 0))
320 mode |= O_RDWR02;
321 else
322 mode |= O_RDONLY00;
323# else
324 // on Windows, this seems to work...
325 if (dosflags & F_WRITABLE)
326 mode |= O_RDWR02;
327 else
328 mode |= O_RDONLY00;
329# endif
330
331 return flag_to_openmode(mode);
332}
333
334#endif // _MSC_VER
335
336__SGI_END_NAMESPACE}
337
338// All version of Unix have mmap and lseek system calls. Some also have
339// longer versions of thos system calls to accommodate 64-bit offsets.
340// If we're on a Unix system, define some macros to encapsulate those
341// differences.
342#ifdef _STLP_USE_UNIX_IO
343# ifdef __sgi /* IRIX */
344# define LSEEKlseek lseek64
345# define MMAPmmap mmap64
346# else
347# define LSEEKlseek lseek
348# define MMAPmmap mmap
349# endif
350
351#ifndef MAP_FAILED((void *) -1) /* MMAP failure return code */
352# define MAP_FAILED((void *) -1) -1
353#endif
354
355#elif defined (_STLP_USE_UNIX_EMULATION_IO)
356# define LSEEKlseek _lseek
357#endif
358
359
360_STLP_BEGIN_NAMESPACEnamespace _STL {
361
362size_t
363_Filebuf_base::_M_page_size = 4096;
364
365_Filebuf_base::_Filebuf_base()
366 : _M_file_id((_STLP_fd)-1),
367 _M_openmode(0),
368 _M_is_open(false),
369 _M_should_close(false)
370{
371 if (!_M_page_size)
372#if defined (_STLP_UNIX1) && !defined(__DJGPP)
373# if defined (__APPLE__)
374 {
375 int mib[2];
376 size_t pagesize, len;
377 mib[0] = CTL_HW;
378 mib[1] = HW_PAGESIZE;
379 len = sizeof(pagesize);
380 sysctl(mib, 2, &pagesize, &len, NULL__null, 0);
381 _M_page_size = pagesize;
382 }
383# elif defined(__DJGPP)
384 _M_page_size = BUFSIZ8192;
385# else
386 _M_page_size = sysconf(_SC_PAGESIZE_SC_PAGESIZE);
387# endif
388# elif defined (_STLP_USE_WIN32_IO)
389 {
390 SYSTEM_INFO SystemInfo;
391 GetSystemInfo(&SystemInfo);
392 _M_page_size = SystemInfo.dwPageSize;
393 // might be .dwAllocationGranularity
394 }
395 // _M_CRLF_trans_buf = 0,
396 // _M_trans_buf_end=0,
397 _M_view_id = 0;
398#endif
399
400 if (_M_page_size <=0 )
401 _M_page_size = 4096;
402
403}
404
405
406// Return the size of the file. This is a wrapper for stat.
407// Returns zero if the size cannot be determined or is ill-defined.
408streamoff
409_Filebuf_base::_M_file_size()
410{
411 return _SgI::__file_size(_M_file_id);
412}
413
414bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
415 long permission)
416{
417 _STLP_fd file_no;
418
419 if (_M_is_open)
420 return false;
421
422#if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
423
424 int flags = 0;
425
426 // Unix makes no distinction between text and binary files.
427 switch(openmode & (~ios_base::ate & ~ios_base::binary)) {
428 case ios_base::out:
429 case ios_base::out | ios_base::trunc:
430 flags = O_WRONLY01 | O_CREAT0100 | O_TRUNC01000;
431 break;
432 case ios_base::out | ios_base::app:
433 flags = O_WRONLY01 | O_CREAT0100 | O_APPEND02000;
434 break;
435 case ios_base::in:
436 flags = O_RDONLY00;
437 permission = 0; // Irrelevant unless we're writing.
438 break;
439 case ios_base::in | ios_base::out:
440 flags = O_RDWR02;
441 break;
442 case ios_base::in | ios_base::out | ios_base::trunc:
443 flags = O_RDWR02 | O_CREAT0100 | O_TRUNC01000;
444 break;
445 default: // The above are the only combinations of
446 return false; // flags allowed by the C++ standard.
447 }
448
449# if defined (_STLP_USE_UNIX_EMULATION_IO)
450
451 if (openmode & ios_base::binary)
452 flags |= O_BINARY;
453 else
454 flags |= O_TEXT;
455
456 file_no = _open(name, flags, permission);
457
458# else
459
460 file_no = open(name, flags, permission);
461
462# endif /* _STLP_USE_UNIX_EMULATION_IO */
463
464 if (file_no < 0)
465 return false;
466
467 _M_is_open = true;
468
469 if (openmode & ios_base::ate)
470 if (LSEEKlseek(file_no, 0, SEEK_END2) == -1)
471 _M_is_open = false;
472
473#elif defined (_STLP_USE_STDIO_IO)
474 // use FILE-based i/o
475 const char* flags;
476
477 switch(openmode & (~ios_base::ate)) {
478 case ios_base::out:
479 case ios_base::out | ios_base::trunc:
480 flags = "w";
481 break;
482
483 case ios_base::out | ios_base::binary:
484 case ios_base::out | ios_base::trunc | ios_base::binary:
485 flags = "wb";
486 break;
487
488 case ios_base::out | ios_base::app:
489 flags = "a";
490 break;
491
492 case ios_base::out | ios_base::app | ios_base::binary:
493 flags = "ab";
494 break;
495
496 case ios_base::in:
497 flags = "r";
498 break;
499
500 case ios_base::in | ios_base::binary:
501 flags = "rb";
502 break;
503
504 case ios_base::in | ios_base::out:
505 flags = "r+";
506 break;
507
508 case ios_base::in | ios_base::out | ios_base::binary:
509 flags = "r+b";
510 break;
511
512
513 case ios_base::in | ios_base::out | ios_base::trunc:
514 flags = "w+";
515 break;
516
517 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
518 flags = "w+b";
519 break;
520
521 default: // The above are the only combinations of
522 return false; // flags allowed by the C++ standard.
523 }
524
525 // fbp : TODO : set permissions !
526 (void)permission; // currently unused //*TY 02/26/2000 - added to suppress warning message
527 _M_file = fopen(name, flags);
528
529 if (_M_file) {
530 file_no = fileno(_M_file);
531 }
532 else
533 return false;
534
535 // unset buffering immediately
536 setbuf(_M_file, 0);
537
538 _M_is_open = true;
539
540 if (openmode & ios_base::ate)
541 if (fseek(_M_file, 0, SEEK_END2) == -1)
542 _M_is_open = false;
543
544# elif defined (_STLP_USE_WIN32_IO)
545
546 DWORD dwDesiredAccess, dwShareMode, dwCreationDisposition;
547 bool doTruncate = false;
548
549 switch(openmode & (~ios_base::ate & ~ios_base::binary)) {
550 case ios_base::out:
551 case ios_base::out | ios_base::trunc:
552 dwDesiredAccess = GENERIC_WRITE;
553 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
554 dwCreationDisposition = OPEN_ALWAYS;
555 // boris : even though it is very non-intuitive, standard
556 // requires them both to behave same.
557 doTruncate = true;
558 break;
559
560 case ios_base::out | ios_base::app:
561 dwDesiredAccess = GENERIC_WRITE;
562 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
563 dwCreationDisposition = OPEN_ALWAYS;
564 break;
565 case ios_base::in:
566 dwDesiredAccess = GENERIC_READ;
567 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
568 dwCreationDisposition = OPEN_EXISTING;
569 permission = 0; // Irrelevant unless we're writing.
570 break;
571 case ios_base::in | ios_base::out:
572 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
573 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
574 dwCreationDisposition = OPEN_EXISTING;
575 break;
576 case ios_base::in | ios_base::out | ios_base::trunc:
577 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
578 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
579 dwCreationDisposition = OPEN_ALWAYS;
580 doTruncate = true;
581 break;
582 default: // The above are the only combinations of
583 return false; // flags allowed by the C++ standard.
584 }
585
586 file_no = CreateFileA(name, dwDesiredAccess, dwShareMode, 0,
587 dwCreationDisposition, permission, 0);
588
589 if ( file_no == INVALID_HANDLE_VALUE )
590 return false;
591
592 if ((doTruncate && SetEndOfFile(file_no) == 0) ||
593 ((openmode & ios_base::ate) && SetFilePointer(file_no, 0, NULL__null, FILE_END) == -1)) {
594 CloseHandle(file_no);
595 return false;
596 }
597
598 _M_is_open = true;
599
600#else
601# error "Port!"
602#endif /* __unix */
603
604
605 _M_file_id = file_no;
606 _M_should_close = _M_is_open;
607 _M_openmode = openmode;
608
609 if (_M_is_open)
610 _M_regular_file = _SgI::__is_regular_file(_M_file_id);
611
612 return _M_is_open;
613}
614
615
616bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode)
617{
618 // This doesn't really grant everyone in the world read/write
619 // access. On Unix, file-creation system calls always clear
620 // bits that are set in the umask from the permissions flag.
621# ifdef _STLP_USE_WIN32_IO
622 return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL);
623# elif defined(__MRC__) || defined(__SC__) //*TY 02/26/2000 - added support for MPW compilers
624 return this->_M_open(name, openmode, 0);
625# else
626 return this->_M_open(name, openmode, S_IRUSR0400 | S_IWUSR0200 | S_IRGRP(0400 >> 3) |
627 S_IWGRP(0200 >> 3) | S_IROTH((0400 >> 3) >> 3) | S_IWOTH((0200 >> 3) >> 3));
628# endif
629}
630
631
632// Associated the filebuf with a file descriptor pointing to an already-
633// open file. Mode is set to be consistent with the way that the file
634// was opened.
635bool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) {
636
637 if (_M_is_open || file_no < 0)
638 return false;
639
640# if defined (_STLP_UNIX1)
641 (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
642 int mode ;
643 mode = fcntl(file_no, F_GETFL3);
644
645 if (mode == -1)
646 return false;
647
648 _M_openmode = _SgI::flag_to_openmode(mode);
649
650# elif defined(__MRC__) || defined(__SC__) //*TY 02/26/2000 - added support for MPW compilers
651 (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
652 switch( _iob[file_no]._flag & (_IOREAD|_IOWRT|_IORW) )
653 {
654 case _IOREAD:
655 _M_openmode = ios_base::in; break;
656 case _IOWRT:
657 _M_openmode = ios_base::out; break;
658 case _IORW:
659 _M_openmode = ios_base::in | ios_base::out; break;
660 default:
661 return false;
662 }
663
664# elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
665 (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
666 int mode ;
667 struct stat buf;
668 if (fstat(file_no, &buf) != 0)
669 return false;
670 mode = buf.st_mode;
671
672 switch(mode & (_S_IWRITE | _S_IREAD) ) {
673 case _S_IREAD:
674 _M_openmode = ios_base::in; break;
675 case _S_IWRITE:
676 _M_openmode = ios_base::out; break;
677 case (_S_IWRITE | _S_IREAD):
678 _M_openmode = ios_base::in | ios_base::out; break;
679 default:
680 return false;
681 }
682 // # elif defined(_STLP_USE_WIN32_IO) && defined (_MSC_VER) || (defined(__MINGW32__) && defined(__MSVCRT__))
683# elif (defined(__STL_USE_WIN32_IO) && defined (_MSC_VER) && !defined(__STL_WINCE)) || \
684 (defined(__MINGW32__) && defined(__MSVCRT__))
685
686 if (_M_is_open || file_no == -1)
687 return false;
688
689 HANDLE oshandle = (HANDLE)_get_osfhandle(file_no);
690
691 if ((long)oshandle != -1)
692 file_no = (int)oshandle;
693 else
694 return false;
695
696 if (init_mode != ios_base::__default_mode)
697 _M_openmode = init_mode;
698 else
699 _M_openmode = _SgI::_get_osfflags(file_no, oshandle);
700
701# else
702 (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
703
704 // not available for the API
705 return false;
706
707# endif
708
709
710 _M_is_open = true;
711 _M_file_id = (_STLP_fd)file_no;
712 _M_should_close = false;
713 _M_regular_file = _SgI::__is_regular_file(_M_file_id);
714
715 return true;
716}
717
718bool _Filebuf_base::_M_close() {
719 if (!_M_is_open)
720 return false;
721
722 bool ok;
723
724 if (!_M_should_close)
725 ok = true;
726 else {
727
728# if defined (_STLP_USE_UNIX_IO)
729
730 ok = (close(_M_file_id) == 0);
731
732# elif defined (_STLP_USE_UNIX_EMULATION_IO)
733
734 ok = (_close(_M_file_id) == 0);
735
736# elif defined (_STLP_USE_STDIO_IO)
737
738 ok = (fclose(_M_file) == 0);
739
740# elif defined (_STLP_USE_WIN32_IO)
741
742 if ( _M_file_id != INVALID_HANDLE_VALUE ) {
743 ok = (CloseHandle(_M_file_id) != 0);
744 }
745 else {
746 ok = false;
747 }
748
749# else
750
751 ok = false;
752
753# endif /* _STLP_USE_UNIX_IO */
754 }
755
756 _M_is_open = _M_should_close = false;
757 _M_openmode = 0;
758 return ok;
759}
760
761
762# define _STLP_LF10 10
763# define _STLP_CR13 13
764# define _STLP_CTRLZ26 26
765
766// Read up to n characters into a buffer. Return value is number of
767// characters read.
768ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) {
769# if defined (_STLP_USE_UNIX_IO)
770
771 return read(_M_file_id, buf, n);
772
773# elif defined (_STLP_USE_UNIX_EMULATION_IO)
774
775 return _read(_M_file_id, buf, n);
776
777# elif defined (_STLP_USE_WIN32_IO)
778
779 DWORD NumberOfBytesRead;
780 ReadFile(_M_file_id, (LPVOID)buf, (DWORD)n,
781 &NumberOfBytesRead, 0);
782
783 if ((! (_M_openmode & ios_base::binary)) && NumberOfBytesRead) {
784 // translate CR-LFs to LFs in the buffer
785 char * to = buf, * last = buf + NumberOfBytesRead - 1;
786 char * from;
787 for (from = buf; from <= last && * from != _STLP_CTRLZ26; ++ from ) {
788 if (* from != _STLP_CR13)
789 * to ++ = * from;
790 else { // found CR
791 if (from < last) { // not at buffer end
792 if (* (from + 1) != _STLP_LF10)
793 * to ++ = _STLP_CR13;
794 }
795 else { // last char is CR, peek for LF
796 char peek = ' ';
797 DWORD NumberOfBytesPeeked;
798 ReadFile(_M_file_id, (LPVOID)&peek,
799 1, &NumberOfBytesPeeked, 0);
800 if (NumberOfBytesPeeked)
801 SetFilePointer(_M_file_id,(LONG)-1,0,SEEK_CUR1);
802 if (peek != _STLP_LF10)
803 * to ++ = _STLP_CR13;
804 }
805 } // found CR
806 } // for
807 // seek back to TEXT end of file if hit CTRL-Z
808 if (from <= last) // terminated due to CTRLZ
809 SetFilePointer(_M_file_id,(LONG)((last+1) - from),0,SEEK_CUR1);
810 NumberOfBytesRead = to - buf;
811 }
812 return (ptrdiff_t)NumberOfBytesRead;
813
814# elif defined (_STLP_USE_STDIO_IO)
815
816 return fread(buf, 1, n, _M_file);
817
818# else
819# error "Port!"
820# endif /* __unix */
821}
822
823// Write n characters from a buffer. Return value: true if we managed
824// to write the entire buffer, false if we didn't.
825bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) {
826
827 while (true) {
828 ptrdiff_t written;
829
830# if defined (_STLP_USE_UNIX_IO)
831
832 written = write(_M_file_id, buf, n);
833
834# elif defined (_STLP_USE_UNIX_EMULATION_IO)
835
836 written = _write(_M_file_id, buf, n);
837
838# elif defined (_STLP_USE_WIN32_IO)
839
840 // In append mode, every write does an implicit seek to the end
841 // of the file.
842 if (_M_openmode & ios_base::app)
843 _M_seek( 0, ios_base::end);
844
845 if (_M_openmode & ios_base::binary) {
846 // binary mode
847 DWORD NumberOfBytesWritten;
848 WriteFile(_M_file_id, (LPVOID)buf, (DWORD)n,
849 &NumberOfBytesWritten, 0);
850 written = (ptrdiff_t)NumberOfBytesWritten;
851 }
852 else {
853 char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end
854 char * nextblock = buf, * ptrtextbuf = textbuf;
855 char * endtextbuf = textbuf + _TEXTBUF_SIZE;
856 char * endblock = buf + n;
857 ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE);
858 char * nextlf;
859
860 while ( (nextblocksize > 0) &&
861 (nextlf = (char *)memchr(nextblock, _STLP_LF10, nextblocksize)) != 0) {
862 ptrdiff_t linelength = nextlf - nextblock;
863 memcpy(ptrtextbuf, nextblock, linelength);
864 ptrtextbuf += linelength;
865 nextblock += (linelength + 1);
866 * ptrtextbuf ++ = _STLP_CR13;
867 * ptrtextbuf ++ = _STLP_LF10;
868 nextblocksize = (min) (ptrdiff_t(endblock - nextblock),
869 (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf)));
870 }
871 // write out what's left, > condition is here since for LF at the end ,
872 // endtextbuf may get < ptrtextbuf ...
873 if (nextblocksize > 0) {
874 memcpy(ptrtextbuf, nextblock, nextblocksize);
875 ptrtextbuf += nextblocksize;
876 nextblock += nextblocksize;
877 }
878 // now write out the translated buffer
879 char * writetextbuf = textbuf;
880 for (ptrdiff_t NumberOfBytesToWrite = ptrtextbuf - textbuf;
881 NumberOfBytesToWrite;) {
882 DWORD NumberOfBytesWritten;
883 WriteFile((HANDLE)_M_file_id, (LPVOID)writetextbuf,
884 NumberOfBytesToWrite, &NumberOfBytesWritten, 0);
885 if (NumberOfBytesWritten == NumberOfBytesToWrite)
886 break;
887 if (!NumberOfBytesWritten) // write shortfall
888 return false;
889 writetextbuf += NumberOfBytesWritten;
890 NumberOfBytesToWrite -= NumberOfBytesWritten;
891 }
892 // count non-translated characters
893 written = (nextblock - buf);
894 }
895
896# elif defined (_STLP_USE_STDIO_IO)
897
898 written = fwrite(buf, 1, n, _M_file);
899
900# else
901# error "Port!"
902# endif /* __unix */
903
904 if (n == written)
905 return true;
906 else if (written > 0 && written < n) {
907 n -= written;
908 buf += written;
909 }
910 else
911 return false;
912 }
913}
914
915
916#ifdef _STLP_USE_WIN32_IO
917# define STL_SEEK_SET0 FILE_BEGIN
918# define STL_SEEK_CUR1 FILE_CURRENT
919# define STL_SEEK_END2 FILE_END
920#else
921# define STL_SEEK_SET0 SEEK_SET0
922# define STL_SEEK_CUR1 SEEK_CUR1
923# define STL_SEEK_END2 SEEK_END2
924#endif
925
926// Wrapper for lseek or the like.
927streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir)
928{
929 streamoff result = -1;
930
931 int whence;
932
933 switch(dir) {
934 case ios_base::beg:
935 if (offset < 0 /* || offset > _M_file_size() */ )
936 return streamoff(-1);
937 whence = STL_SEEK_SET0;
938 break;
939 case ios_base::cur:
940 whence = STL_SEEK_CUR1;
941 break;
942 case ios_base::end:
943 if (/* offset > 0 || */ -offset > _M_file_size() )
944 return streamoff(-1);
945 whence = STL_SEEK_END2;
946 break;
947 default:
948 return streamoff(-1);
949 }
950
951#if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
952
953 result = LSEEKlseek(_M_file_id, offset, whence);
954
955#elif defined (_STLP_USE_STDIO_IO)
956
957 result = fseek(_M_file, offset, whence);
958
959#elif defined (_STLP_USE_WIN32_IO)
960
961 LARGE_INTEGER li;
962 li.QuadPart = offset;
963 li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence);
964 if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
965 result = -1; // Error
966 else
967 result = li.QuadPart;
968
969#else
970# error "Port!"
971#endif
972
973 return result;
974}
975
976
977// Attempts to memory-map len bytes of the current file, starting
978// at position offset. Precondition: offset is a multiple of the
979// page size. Postcondition: return value is a null pointer if the
980// memory mapping failed. Otherwise the return value is a pointer to
981// the memory-mapped file and the file position is set to offset.
982void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) {
983 void* base;
984#if defined (_STLP_UNIX1) && !defined(__DJGPP)
985 base = MMAPmmap(0, len, PROT_READ0x1, MAP_PRIVATE0x02, _M_file_id, offset);
986 if (base != (void*)MAP_FAILED((void *) -1)) {
987 if (LSEEKlseek(_M_file_id, offset + len, SEEK_SET0) < 0) {
988 this->_M_unmap(base, len);
989 base = 0;
990 }
991 } else
992 base =0;
993
994#elif defined (_STLP_USE_WIN32_IO)
995
996 _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 ,
997 PAGE_READONLY, 0 /* len >> 32 */ ,
998 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size
999 0);
1000
1001 if (_M_view_id) {
1002# if 0
1003 printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n",
1004 _M_view_id, _M_file_id, GetLastError(),
1005 (int)cur_filesize, ULL(offset)((unsigned long long)offset) & 0xffffffff, len);
1006# endif
1007
1008 base = MapViewOfFile(_M_view_id, FILE_MAP_READ, ULL(offset)((unsigned long long)offset)>>32,
1009 ULL(offset)((unsigned long long)offset) & 0xffffffff, len);
1010 // check if mapping succeded and is usable
1011 if (base ==0 || _M_seek(offset+len, ios_base::beg) < 0) {
1012 this->_M_unmap(base, len);
1013 base = 0;
1014 }
1015 } else
1016 base = 0;
1017#else
1018 (void)len; //*TY 02/26/2000 - unused variables
1019 (void)offset; //*TY 02/26/2000 -
1020 base = 0;
1021#endif
1022 return base;
1023}
1024
1025void _Filebuf_base::_M_unmap(void* base, streamoff len) {
1026 // precondition : there is a valid mapping at the moment
1027#if defined (_STLP_UNIX1) && !defined(__DJGPP)
1028 munmap((char*)base, len);
1029#elif defined (_STLP_USE_WIN32_IO)
1030 if ( base != NULL__null )
1031 UnmapViewOfFile(base);
1032 // destroy view handle as well
1033 if ( _M_view_id != NULL__null )
1034 CloseHandle(_M_view_id);
1035 _M_view_id = 0;
1036 base = 0;
1037#else
1038 (void)len; //*TY 02/26/2000 - unused variables
1039 (void)base; //*TY 02/26/2000 -
1040#endif
1041}
1042
1043// fbp : let us map 1 MB maximum, just be sure not to trash VM
1044# define MMAP_CHUNK0x100000UL 0x100000UL
1045
1046int _STLP_CALL
1047_Underflow<char, char_traits<char> >::_M_doit (basic_filebuf<char, char_traits<char> >* __this)
1048{
1049 if (!__this->_M_in_input_mode) {
1050 if (!__this->_M_switch_to_input_mode())
1051 return traits_type::eof();
1052 }
1053
1054 else if (__this->_M_in_putback_mode) {
1055 __this->_M_exit_putback_mode();
1056 if (__this->gptr() != __this->egptr()) {
1057 int_type __c = traits_type::to_int_type(*__this->gptr());
1058 return __c;
1059 }
1060 }
1061
1062 // If it's a disk file, and if the internal and external character
1063 // sequences are guaranteed to be identical, then try to use memory
1064 // mapped I/O. Otherwise, revert to ordinary read.
1065 if (__this->_M_base.__regular_file()
1066 && __this->_M_always_noconv
1067 && __this->_M_base._M_in_binary_mode()) {
1068 // If we've mmapped part of the file already, then unmap it.
1069 if (__this->_M_mmap_base)
1070 __this->_M_base._M_unmap(__this->_M_mmap_base, __this->_M_mmap_len);
1071 __this->_M_mmap_base = 0;
1072 __this->_M_mmap_len = 0;
1073
1074 // Determine the position where we start mapping. It has to be
1075 // a multiple of the page size.
1076 streamoff __cur = __this->_M_base._M_seek(0, ios_base::cur);
1077 streamoff __size = __this->_M_base._M_file_size();
1078 if (__size > 0 && __cur >= 0 && __cur < __size) {
1079 streamoff __offset = (__cur / __this->_M_base.__page_size())
1080 * __this->_M_base.__page_size();
1081 streamoff __remainder = __cur - __offset;
1082
1083 __this->_M_mmap_len = __size - __offset;
1084
1085 if (__this->_M_mmap_len > MMAP_CHUNK0x100000UL)
1086 __this->_M_mmap_len = MMAP_CHUNK0x100000UL;
1087
1088 if ((__this->_M_mmap_base =
1089 __this->_M_base._M_mmap(__offset, __this->_M_mmap_len)) != 0) {
1090 __this->setg((char*) __this->_M_mmap_base,
1091 (char*) __this->_M_mmap_base + __remainder,
1092 (char*) __this->_M_mmap_base + __this->_M_mmap_len);
1093 return traits_type::to_int_type(*__this->gptr());
1094 }
1095 } else /* size > 0 ... */ {
1096 // There is nothing to map. We unmapped the file above, now zap pointers.
1097 __this->_M_mmap_base = 0;
1098 __this->_M_mmap_len = 0;
1099 }
1100 }
1101
1102 return __this->_M_underflow_aux();
1103}
1104
1105
1106//----------------------------------------------------------------------
1107// Force instantiation of filebuf and fstream classes.
1108#if !defined(_STLP_NO_FORCE_INSTANTIATE)
1109
1110template class basic_filebuf<char, char_traits<char> >;
1111template class basic_ifstream<char, char_traits<char> >;
1112template class basic_ofstream<char, char_traits<char> >;
1113template class basic_fstream<char, char_traits<char> >;
1114
1115# ifndef _STLP_NO_WCHAR_T
1116template class _Underflow<wchar_t, char_traits<wchar_t> >;
1117template class basic_filebuf<wchar_t, char_traits<wchar_t> >;
1118template class basic_ifstream<wchar_t, char_traits<wchar_t> >;
1119template class basic_ofstream<wchar_t, char_traits<wchar_t> >;
1120template class basic_fstream<wchar_t, char_traits<wchar_t> >;
1121# endif /* _STLP_NO_WCHAR_T */
1122
1123#endif
1124
1125_STLP_END_NAMESPACE}
1126
1127// Local Variables:
1128// mode:C++
1129// End:
1130