2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: filebuf.C /main/9 1996/10/04 10:44:52 drk $ */
26 #include <sys/types.h>
29 #if !defined(hpux) && !defined(__osf__) && !defined(USL) && \
30 !defined(linux) && !defined(CSRG_BASED) && !defined(sun)
37 #include "utility/c_filebuf.h"
47 /////////////////////////////////////////////
48 // only current_pos is used.
49 /////////////////////////////////////////////
51 filebuf::filebuf(int __fd) :
52 _fd(__fd), _prev_action(-1), _name(0),
53 current_pos(0), new_pos(0), default_new_pos(0)
58 if ( fstat(_fd, &statbuf ) == 0 ) {
59 if ( BIT_TEST( statbuf.st_mode, S_IRUSR) )
62 if ( BIT_TEST( statbuf.st_mode, S_IWUSR) )
69 filebuf::filebuf(const char* name, int mode, int protect) :
70 _fd(-1), _prev_action(-1), _name(strdup(name)),
71 current_pos(0), new_pos(0), default_new_pos(0)
73 open(name, mode, protect);
76 int filebuf::open(const char* name, int mode, int protect)
79 _name && strcmp(name, _name) == 0 &&
87 delete _name; _name = strdup(name);
93 if ( BIT_TEST(mode, ios::app) || BIT_TEST(mode, ios::out) ) {
94 if ( BIT_TEST(mode, ios::in) )
99 if ( BIT_TEST(mode, ios::in) )
103 if ( BIT_TEST(mode, ios::trunc) ||
105 BIT_TEST(mode, ios::trunc) &&
106 !(BIT_TEST(mode, ios::in)||BIT_TEST(mode, ios::app))
111 //fprintf(stderr, "flag=%x\n", flag);
113 _fd = ::open(name, flag);
116 //fprintf(stderr, "use O_CREAT\n");
118 _fd = ::open(name, flag, protect);
122 //fprintf(stderr, "filebuf::open OK, name = %s, fd = %d, this = %d\n", name, _fd, (void*)this);
130 if ( _prev_action == streambuf::PUT )
138 int filebuf::is_open()
140 return (_fd>=0) ? 1 : 0;
143 void filebuf::notify(int action_t)
145 if ( _prev_action == -1 ) {
146 _prev_action = action_t;
148 if ( _prev_action != action_t )
152 void filebuf::_notify(int action_t)
154 switch ( action_t ) {
156 //////////////////////////////////////////////////////////////
157 // previous action was PUT. Now calculate the number of chars
158 // that have been put and write them out.
160 // Note: put_ptr always starts at base. And at this time,
163 //////////////////////////////////////////////////////////////
168 //////////////////////////////////////////////////////////////
169 // previous action was a GET.
171 // Note: get_ptr always starts at base.
173 //////////////////////////////////////////////////////////////
180 _prev_action = action_t;
183 int filebuf::_write(char* ptr, int size)
185 //fprintf(stderr, "_write() size = %d, fd = %d\n", size, _fd);
187 int _written_size = ::write(_fd, ptr, size);
188 if ( _written_size != size ) {
189 //fprintf(stderr, "fwrite only writes %d bytes\n.", size - _written_size);
192 return _written_size;
195 int filebuf::overflow()
197 // write to the file if possible and clean the buffer
199 if ( !BIT_TEST(_mode, ios::out) && !BIT_TEST(_mode, ios::app) )
202 if ( _size == 0 ) return 0;
204 if ( BIT_TEST(_mode, ios::app) ) {
205 if ( _seek(0L, SEEK_END) != 0 ) return EOF;
207 if ( _seek() != 0 ) return EOF;
211 if ( get_ptr + _size <= end ) {
212 ok = _write(get_ptr, _size);
214 int l = end - get_ptr;
216 ok = _write(get_ptr, l);
219 ok = _write(base, _size - l);
222 if ( ok == EOF ) return EOF;
224 current_pos += _size;
231 int filebuf::underflow()
233 // get more from the file if possible
235 if ( !BIT_TEST(_mode, ios::in) )
238 if ( _seek() != 0 ) return EOF;
240 _size = ::read(_fd, base, _capacity);
242 //fprintf(stderr, "read in _underflow() this = %d, _size = %d, current_pos = %d, fd = %d\n", (void*)this, _size, current_pos, _fd);
248 put_ptr = base + _size;
251 current_pos += _size;
258 //fprintf(stderr, "_seek() [1] current_pos= %d\n", current_pos);
259 if ( ::lseek(_fd, current_pos, SEEK_SET) == -1 ) {
260 fprintf(stderr, "lseek failed. current_pos= %ld\n", current_pos);
266 int filebuf::_seek(streampos pos, int whence)
269 //fprintf(stderr, "_seek() [2]: pos= %d, whence=%d\n", pos, whence);
271 if ( ::lseek(_fd, pos, whence) == -1 ) {
272 fprintf(stderr, "lseek failed. pos= %ld, whence=%d\n", pos, whence);
278 int filebuf::seekg(long delta)
280 if ( _prev_action == streambuf::PUT )
292 if ( overflow() == EOF )
295 if ( ::fsync(_fd) != 0 )