1e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/*
2e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1999
3e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Silicon Graphics Computer Systems, Inc.
4e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
5e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1999
6e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Boris Fomitchev
7e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
8e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * This material is provided "as is", with absolutely no warranty expressed
9e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * or implied. Any use is at your own risk.
10e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
11e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to use or copy this software for any purpose is hereby granted
12e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * without fee, provided the above notices are retained on all copies.
13e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to modify the code and to distribute modified code is granted,
14e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * provided the above notices are retained, and a notice that the code was
15e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * modified is included with the above copyright notice.
16e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
17e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott */
18e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
19e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined  (__SUNPPRO_CC)  && !defined (_STLP_NO_NEW_C_HEADERS)
20e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  include <time.h>
21e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// For sunpro, it chokes if time.h is included through stat.h
22e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
23e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
24e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <fstream>
25e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
26e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#ifdef __CYGWIN__
27e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define __int64 long long
28e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
29e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
30e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottextern "C" {
31e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// open/close/read/write
32e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <sys/stat.h>           // For stat
33e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_CRAY) && ! defined (__EMX__)
34e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  include <sys/mman.h>           // For mmap
35e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
36e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
37e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//  on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this
38e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__hpux) && defined (__GNUC__)
39e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  undef _INCLUDE_POSIX1C_SOURCE
40e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
41e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
42e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <unistd.h>
43e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <fcntl.h>
44e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
45e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
46e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#ifdef __APPLE__
47e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  include <sys/sysctl.h>
48e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
49e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
50e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottconst _STLP_fd INVALID_STLP_FD = -1;
51e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
52e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#ifndef O_ACCMODE
53e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
54e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
55e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
56e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Compare with streamoff definition in stl/char_traits.h!
57e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
58e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    (!defined(_LARGEFILE_SOURCE) && !defined (_LARGEFILE64_SOURCE))
59e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define FSTAT fstat
60e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define STAT  stat
61e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define LSEEK lseek
62e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define MMAP  mmap
63e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define OPEN  open
64e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else
65e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define FSTAT fstat64
66e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define STAT  stat64
67e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define LSEEK lseek64
68e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define MMAP  mmap64
69e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define OPEN  open64
70e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
71e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
72e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#ifndef MAP_FAILED /* MMAP failure return code */
73e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  define MAP_FAILED -1
74e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
75e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
76e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_BEGIN_NAMESPACE
77e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic ios_base::openmode flag_to_openmode(int mode)
79e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
80e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  ios_base::openmode ret = ios_base::__default_mode;
81e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
82e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  switch ( mode & O_ACCMODE ) {
83e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case O_RDONLY:
84e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      ret = ios_base::in;
85e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
86e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case O_WRONLY:
87e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      ret = ios_base::out;
88e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
89e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case O_RDWR:
90e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      ret = ios_base::in | ios_base::out;
91e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
92e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
94e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if ( mode & O_APPEND )
95e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    ret |= ios_base::app;
96e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return ret;
98e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
99e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
100e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_MOVE_TO_PRIV_NAMESPACE
101e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
102e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Helper functions for _Filebuf_base.
103e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
104e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool __is_regular_file(_STLP_fd fd) {
105e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  struct STAT buf;
106e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode);
107e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
108e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
109e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Number of characters in the file.
110e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic streamoff __file_size(_STLP_fd fd) {
111e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  streamoff ret = 0;
112e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
113e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  struct STAT buf;
114e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode))
115e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    ret = buf.st_size > 0 ? buf.st_size : 0;
116e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
117e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return ret;
118e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
119e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
120e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_MOVE_TO_STD_NAMESPACE
121e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
122e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottsize_t _Filebuf_base::_M_page_size = 4096;
123e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
124e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_Filebuf_base::_Filebuf_base()
125e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  : _M_file_id(INVALID_STLP_FD),
126e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _M_openmode(0),
127e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _M_is_open(false),
128e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _M_should_close(false)
129e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{}
130e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
131e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _Filebuf_base::_S_initialize()
132e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
133e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__APPLE__)
134e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  int mib[2];
135e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  size_t pagesize, len;
136e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  mib[0] = CTL_HW;
137e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  mib[1] = HW_PAGESIZE;
138e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  len = sizeof(pagesize);
139e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  sysctl(mib, 2, &pagesize, &len, NULL, 0);
140e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_page_size = pagesize;
141e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#elif defined (__DJGPP) && defined (_CRAY)
142e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_page_size = BUFSIZ;
143e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else
144e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_page_size = sysconf(_SC_PAGESIZE);
145e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
146e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
147e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
148e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Return the size of the file.  This is a wrapper for stat.
149e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Returns zero if the size cannot be determined or is ill-defined.
150e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstreamoff _Filebuf_base::_M_file_size()
151e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
152e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return _STLP_PRIV __file_size(_M_file_id);
153e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
154e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
155e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottbool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
156e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                            long permission)
157e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
158e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _STLP_fd file_no;
159e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
160e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (_M_is_open)
161e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return false;
162e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
163e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  int flags = 0;
164e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
165e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  // Unix makes no distinction between text and binary files.
166e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  switch ( openmode & (~ios_base::ate & ~ios_base::binary) ) {
167e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::out:
168e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::out | ios_base::trunc:
169e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      flags = O_WRONLY | O_CREAT | O_TRUNC;
170e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
171e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::app:
172e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::out | ios_base::app:
173e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      flags = O_WRONLY | O_CREAT | O_APPEND;
174e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
175e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::in:
176e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      flags = O_RDONLY;
177e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      permission = 0;             // Irrelevant unless we're writing.
178e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
179e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::in | ios_base::out:
180e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      flags = O_RDWR;
181e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
182e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::in | ios_base::out | ios_base::trunc:
183e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      flags = O_RDWR | O_CREAT | O_TRUNC;
184e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
185e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::in | ios_base::app:
186e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::in | ios_base::out | ios_base::app:
187e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      flags = O_RDWR | O_CREAT | O_APPEND;
188e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
189e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    default:                      // The above are the only combinations of
190e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      return false;               // flags allowed by the C++ standard.
191e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
192e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
193e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  file_no = OPEN(name, flags, permission);
194e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
195e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (file_no < 0)
196e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return false;
197e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
198e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_is_open = true;
199e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
200e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if ((openmode & (ios_base::ate | ios_base::app)) && (LSEEK(file_no, 0, SEEK_END) == -1)) {
201e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _M_is_open = false;
202e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
203e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
204e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_file_id = file_no;
205e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_should_close = _M_is_open;
206e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_openmode = openmode;
207e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
208e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (_M_is_open)
209e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
210e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
211e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return (_M_is_open != 0);
212e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
213e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
214e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
215e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottbool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode)
216e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
217e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  // This doesn't really grant everyone in the world read/write
218e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  // access.  On Unix, file-creation system calls always clear
219e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  // bits that are set in the umask from the permissions flag.
220e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |
221e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                                       S_IWGRP | S_IROTH | S_IWOTH);
222e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
223e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
224e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Associated the filebuf with a file descriptor pointing to an already-
225e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// open file.  Mode is set to be consistent with the way that the file
226e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// was opened.
227e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottbool _Filebuf_base::_M_open(int file_no, ios_base::openmode)
228e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
229e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (_M_is_open || file_no < 0)
230e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return false;
231e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
232e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  int mode = fcntl(file_no, F_GETFL);
233e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
234e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (mode == -1)
235e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return false;
236e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
237e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_openmode = flag_to_openmode(mode);
238e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_file_id = file_no;
239e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
240e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_is_open = true;
241e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_should_close = false;
242e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
243e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return true;
244e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
245e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
246e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottbool _Filebuf_base::_M_close()
247e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
248e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (!_M_is_open)
249e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return false;
250e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
251e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  bool ok = _M_should_close ? (close(_M_file_id) == 0) : true;
252e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
253e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_is_open = _M_should_close = false;
254e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _M_openmode = 0;
255e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return ok;
256e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
257e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
258e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Read up to n characters into a buffer.  Return value is number of
259e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// characters read.
260e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n)
261e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
262e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return read(_M_file_id, buf, n);
263e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
264e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
265e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Write n characters from a buffer.  Return value: true if we managed
266e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// to write the entire buffer, false if we didn't.
267e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottbool _Filebuf_base::_M_write(char* buf, ptrdiff_t n)
268e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
269e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  for (;;) {
270e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    ptrdiff_t written = write(_M_file_id, buf, n);
271e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
272e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    if (n == written) {
273e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      return true;
274e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    }
275e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
276e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    if (written > 0 && written < n) {
277e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      n -= written;
278e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      buf += written;
279e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    } else {
280e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      return false;
281e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    }
282e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
283e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
284e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
285e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Wrapper for lseek or the like.
286e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstreamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir)
287e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
288e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  int whence;
289e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
290e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  switch ( dir ) {
291e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::beg:
292e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      if (offset < 0 /* || offset > _M_file_size() */ )
293e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott        return streamoff(-1);
294e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      whence = SEEK_SET;
295e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
296e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::cur:
297e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      whence = SEEK_CUR;
298e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
299e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    case ios_base::end:
300e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      if (/* offset > 0 || */  -offset > _M_file_size() )
301e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott        return streamoff(-1);
302e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      whence = SEEK_END;
303e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      break;
304e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    default:
305e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      return streamoff(-1);
306e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
307e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
308e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return LSEEK(_M_file_id, offset, whence);
309e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
310e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
311e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Attempts to memory-map len bytes of the current file, starting
312e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// at position offset.  Precondition: offset is a multiple of the
313e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// page size.  Postcondition: return value is a null pointer if the
314e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// memory mapping failed.  Otherwise the return value is a pointer to
315e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// the memory-mapped file and the file position is set to offset.
316e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid* _Filebuf_base::_M_mmap(streamoff offset, streamoff len)
317e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
318e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  void* base;
319e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (__DJGPP) && !defined (_CRAY)
320e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset);
321e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (base != (void*)MAP_FAILED) {
322e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) {
323e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      this->_M_unmap(base, len);
324e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      base = 0;
325e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    }
326e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  } else
327e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    base =0;
328e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else
329e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _STLP_MARK_PARAMETER_AS_UNUSED(&offset)
330e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _STLP_MARK_PARAMETER_AS_UNUSED(&len)
331e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  base = 0;
332e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
333e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return base;
334e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
335e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
336e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _Filebuf_base::_M_unmap(void* base, streamoff len)
337e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{
338e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  // precondition : there is a valid mapping at the moment
339e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (__DJGPP) && !defined (_CRAY)
340e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  munmap((char*)base, len);
341e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else
342e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _STLP_MARK_PARAMETER_AS_UNUSED(&len)
343e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _STLP_MARK_PARAMETER_AS_UNUSED(base)
344e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
345e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
346e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
347e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_END_NAMESPACE
348