comparison packages/language/c/libc/current/src/stdio/common/stream.cxx @ 2:443894e2e912 ecos-v1_2_1-release

Block commit of eCos version 1.2.1
author jlarmour
date Tue, 11 May 1999 12:24:34 +0000
parents 3111d98ba7b3
children c38311975d4f
comparison
equal deleted inserted replaced
1:72f549f0d891 2:443894e2e912
20 // 20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released 21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998. 22 // September 30, 1998.
23 // 23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created 24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. 25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved.
26 // ------------------------------------------- 26 // -------------------------------------------
27 // 27 //
28 //####COPYRIGHTEND#### 28 //####COPYRIGHTEND####
29 //======================================================================== 29 //========================================================================
30 //#####DESCRIPTIONBEGIN#### 30 //#####DESCRIPTIONBEGIN####
31 // 31 //
32 // Author(s): jlarmour@cygnus.co.uk 32 // Author(s): jlarmour
33 // Contributors: jlarmour@cygnus.co.uk 33 // Contributors: jlarmour
34 // Date: 1998-02-13 34 // Date: 1999-03-16
35 // Purpose: 35 // Purpose:
36 // Description: 36 // Description:
37 // Usage: 37 // Usage:
38 // 38 //
39 //####DESCRIPTIONEND#### 39 //####DESCRIPTIONEND####
44 44
45 #include <pkgconf/libc.h> // Configuration header 45 #include <pkgconf/libc.h> // Configuration header
46 46
47 47
48 // Include the C library? And do we want the stdio stuff? 48 // Include the C library? And do we want the stdio stuff?
49 #if defined(CYGPKG_LIBC) && defined(CYGPKG_LIBC_STDIO) 49 #ifdef CYGPKG_LIBC_STDIO
50 50
51 // INCLUDES 51 // INCLUDES
52 52
53 #include <cyg/infra/cyg_type.h> // Common project-wide type definitions 53 #include <cyg/infra/cyg_type.h> // Common project-wide type definitions
54 #include <stddef.h> // NULL and size_t from compiler 54 #include <cyg/infra/cyg_ass.h> // Assertion infrastructure
55 #include <errno.h> // Error codes 55 #include <stddef.h> // NULL and size_t from compiler
56 #include "clibincl/stringsupp.hxx" // _memcpy() 56 #include <errno.h> // Error codes
57 #include "clibincl/stream.hxx" // Header for this file 57 #include "clibincl/stringsupp.hxx" // _memcpy()
58 #include <cyg/devs/common/iorb.h> // Cyg_IORB 58 #include "clibincl/stream.hxx" // Header for this file
59 #include <cyg/devs/common/table.h> // Device table 59 #include "clibincl/stdiosupp.hxx" // Stdio support functions
60 #include <cyg/io/io.h> // I/O system
61 #include <cyg/io/config_keys.h> // CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
60 62
61 63
62 // FUNCTIONS 64 // FUNCTIONS
63 65
64 Cyg_StdioStream::Cyg_StdioStream(Cyg_Device_Table_t *dev, 66 Cyg_StdioStream::Cyg_StdioStream(cyg_io_handle_t dev,
65 OpenMode open_mode, 67 OpenMode open_mode,
66 cyg_bool append, cyg_bool binary, 68 cyg_bool append, cyg_bool binary,
67 int buffer_mode, cyg_ucount32 buffer_size, 69 int buffer_mode, cyg_ucount32 buffer_size,
68 cyg_uint8 *buffer_addr ) 70 cyg_uint8 *buffer_addr )
69 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 71 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
70 : io_buf( buffer_size, buffer_addr ) 72 : io_buf( buffer_size, buffer_addr )
71 #endif 73 #endif
72 74
73 { 75 {
76
77 CYG_CHECK_DATA_PTR(dev, "Attempt to open invalid device!");
78
74 #ifdef CYGDBG_USE_ASSERTS 79 #ifdef CYGDBG_USE_ASSERTS
75 magic_validity_word = 0xbadbad; 80 magic_validity_word = 0xbadbad;
76 #endif 81 #endif
77 82
78 my_device = dev; 83 my_device = dev;
96 return; 101 return;
97 } // switch 102 } // switch
98 103
99 104
100 if (flags.opened_for_write) { 105 if (flags.opened_for_write) {
106 #if 0
107 // FIXME: need some replacement for this
101 if (!my_device->write_blocking) { 108 if (!my_device->write_blocking) {
102 error = EDEVNOSUPP; 109 error = EDEVNOSUPP;
103 return; 110 return;
104 } // if 111 } // if
105 112 #endif
106 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 113 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
107 flags.last_buffer_op_was_read = false; 114 flags.last_buffer_op_was_read = false;
108 #endif 115 #endif
109 } // if 116 } // if
110 117
111 118
112 if (flags.opened_for_read) { 119 if (flags.opened_for_read) {
120 #if 0
121 // FIXME: need some replacement for this
113 if (!my_device->read_blocking) { 122 if (!my_device->read_blocking) {
114 error = EDEVNOSUPP; 123 error = EDEVNOSUPP;
115 return; 124 return;
116 } // if 125 } // if
126 #endif
117 127
118 // NB also if opened for read AND write, then say last op was read 128 // NB also if opened for read AND write, then say last op was read
119 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 129 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
120 flags.last_buffer_op_was_read = true; 130 flags.last_buffer_op_was_read = true;
121 #endif 131 #endif
152 error = EINVAL; 162 error = EINVAL;
153 return; 163 return;
154 } // switch 164 } // switch
155 165
156 // one way of checking the buffer was set up correctly 166 // one way of checking the buffer was set up correctly
157 if (io_buf.get_buffer_size()==-1) { 167 if (flags.buffering && io_buf.get_buffer_size()==-1) {
158 error = ENOMEM; 168 error = ENOMEM;
159 return; 169 return;
160 } 170 }
161 171
162 #endif 172 #endif
163 173
174 #if 0 // FIXME - Need to set binary mode.
164 if (my_device->open) { 175 if (my_device->open) {
165 error = (*my_device->open)( my_device->cookie, 176 error = (*my_device->open)( my_device->cookie,
166 binary ? CYG_DEVICE_OPEN_MODE_RAW 177 binary ? CYG_DEVICE_OPEN_MODE_RAW
167 : CYG_DEVICE_OPEN_MODE_TEXT ); 178 : CYG_DEVICE_OPEN_MODE_TEXT );
168 if (error != ENOERR) 179 if (error != ENOERR)
169 return; // keep error code the same 180 return; // keep error code the same
170 } // if 181 } // if
171 182
183 #endif
172 184
173 #ifdef CYGDBG_USE_ASSERTS 185 #ifdef CYGDBG_USE_ASSERTS
174 magic_validity_word = 0x7b4321ce; 186 magic_validity_word = 0x7b4321ce;
175 #endif 187 #endif
176 188
180 192
181 Cyg_ErrNo 193 Cyg_ErrNo
182 Cyg_StdioStream::refill_read_buffer( void ) 194 Cyg_StdioStream::refill_read_buffer( void )
183 { 195 {
184 Cyg_ErrNo read_err; 196 Cyg_ErrNo read_err;
185 Cyg_IORB iorb; 197 cyg_uint8 *buffer;
198 cyg_uint32 len;
186 199
187 CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); 200 CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
188 201
189 if (!lock_me()) 202 if (!lock_me())
190 return EBADF; // assume file is now invalid 203 return EBADF; // assume file is now invalid
211 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 224 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
212 // we're now reading 225 // we're now reading
213 flags.last_buffer_op_was_read = true; 226 flags.last_buffer_op_was_read = true;
214 227
215 if (flags.buffering) { 228 if (flags.buffering) {
216 iorb.buffer_length = 229 len = io_buf.get_buffer_addr_to_write( (cyg_uint8**)&buffer );
217 io_buf.get_buffer_addr_to_write( (cyg_uint8**)&iorb.buffer ); 230 if (!len) { // no buffer space available
231 unlock_me();
232 return ENOERR; // isn't an error, just needs user to read out data
233 } // if
218 } 234 }
219 else 235 else
220 #endif 236 #endif
221 237
222 if (!flags.readbuf_char_in_use) { 238 if (!flags.readbuf_char_in_use) {
223 iorb.buffer_length = 1; 239 len = 1;
224 iorb.buffer = &readbuf_char; 240 buffer = &readbuf_char;
225 } 241 }
242 else {
243 // no buffer space available
244 unlock_me();
245 return ENOERR; // isn't an error, just needs user to read out data
246 } // else
247
248 read_err = cyg_io_read(my_device, buffer, &len);
249
250
251 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
252 if (flags.buffering)
253 io_buf.set_bytes_written( len );
226 else 254 else
227 iorb.buffer_length = 0; 255 #endif
228 256 flags.readbuf_char_in_use = len ? 1 : 0;
229 if (!iorb.buffer_length) { // no buffer space available
230 unlock_me();
231 return ENOERR; // isn't an error, just needs user to read out data
232 } // if
233
234 read_err = (*my_device->read_blocking)( my_device->cookie, &iorb );
235
236
237 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
238 if (flags.buffering)
239 io_buf.set_bytes_written( iorb.xferred_length );
240 else
241 #endif
242 flags.readbuf_char_in_use = iorb.xferred_length ? 1 : 0;
243 257
244 unlock_me(); 258 unlock_me();
245 259
246 if (read_err == ENOERR) { 260 if (read_err == ENOERR) {
247 if (iorb.xferred_length == 0) 261 if (len == 0)
248 read_err = EAGAIN; 262 read_err = EAGAIN;
249 } // if 263 } // if
250 264
251 return read_err; 265 return read_err;
252 } // refill_read_buffer() 266 } // refill_read_buffer()
285 Cyg_ErrNo err; 299 Cyg_ErrNo err;
286 300
287 // this should really only be called after refill_read_buffer, but 301 // this should really only be called after refill_read_buffer, but
288 // just in case 302 // just in case
289 err = flush_output_unlocked(); 303 err = flush_output_unlocked();
304 if (ENOERR == err)
305 err = cyg_libc_stdio_flush_all_but(this);
290 306
291 if (err != ENOERR) { 307 if (err != ENOERR) {
292 unlock_me(); 308 unlock_me();
293 return err; 309 return err;
294 } 310 }
341 // this should really only be called after refill_read_buffer, but just 357 // this should really only be called after refill_read_buffer, but just
342 // in case 358 // in case
343 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 359 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
344 if (flags.buffering) 360 if (flags.buffering)
345 err = flush_output_unlocked(); 361 err = flush_output_unlocked();
362 if (ENOERR == err)
363 err = cyg_libc_stdio_flush_all_but(this);
346 364
347 if (err != ENOERR) 365 if (err != ENOERR)
348 return err; 366 return err;
349 367
350 // we're now reading 368 // we're now reading
460 478
461 Cyg_ErrNo 479 Cyg_ErrNo
462 Cyg_StdioStream::flush_output_unlocked( void ) 480 Cyg_StdioStream::flush_output_unlocked( void )
463 { 481 {
464 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 482 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
465 Cyg_IORB iorb;
466 Cyg_ErrNo write_err=ENOERR; 483 Cyg_ErrNo write_err=ENOERR;
484 cyg_uint8 *buffer;
485 cyg_uint32 len;
467 486
468 CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); 487 CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
469 488
470 if ( flags.last_buffer_op_was_read ) 489 if ( flags.last_buffer_op_was_read )
471 return ENOERR; 490 return ENOERR;
476 495
477 // shortcut if nothing to do 496 // shortcut if nothing to do
478 if (io_buf.get_buffer_space_used() == 0) 497 if (io_buf.get_buffer_space_used() == 0)
479 return ENOERR; 498 return ENOERR;
480 499
481 iorb.buffer_length = 500 len = io_buf.get_buffer_addr_to_read( (cyg_uint8 **)&buffer );
482 io_buf.get_buffer_addr_to_read( (cyg_uint8 **)&iorb.buffer ); 501
483 502 CYG_ASSERT( len > 0,
484 CYG_ASSERT( iorb.buffer_length > 0,
485 "There should be data to read but there isn't!"); 503 "There should be data to read but there isn't!");
486 504
487 write_err = (*my_device->write_blocking)( my_device->cookie, &iorb ); 505 write_err = cyg_io_write(my_device, buffer, &len);
506
507 // since we're doing a concerted flush, we tell the I/O layer to
508 // flush too, otherwise output may just sit there forever
509 if (!write_err)
510 write_err = cyg_io_get_config(my_device,
511 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,
512 NULL, NULL);
488 513
489 // we've just read it all, so just wipe it out 514 // we've just read it all, so just wipe it out
490 io_buf.drain_buffer(); 515 io_buf.drain_buffer();
491 516
492 return write_err; 517 return write_err;
528 553
529 flags.last_buffer_op_was_read = false; 554 flags.last_buffer_op_was_read = false;
530 555
531 if (!flags.buffering) { 556 if (!flags.buffering) {
532 #endif 557 #endif
533 Cyg_IORB iorb; 558 cyg_uint32 len = buffer_length;
534 iorb.buffer = (char *)buffer; 559
535 iorb.buffer_length = buffer_length; 560 write_err = cyg_io_write(my_device, buffer, &len);
536 561
537 write_err = (*my_device->write_blocking)( my_device->cookie, 562 *bytes_written = len;
538 &iorb );
539
540 *bytes_written = iorb.xferred_length;
541 563
542 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO 564 #ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
543 } // if 565 } // if
544 else { 566 else {
545 cyg_ucount32 bytes_available; 567 cyg_ucount32 bytes_available;
616 638
617 return write_err; 639 return write_err;
618 } // write() 640 } // write()
619 641
620 642
621 #endif // if defined(CYGPKG_LIBC) && defined(CYGPKG_LIBC_STDIO) 643 #endif // ifdef CYGPKG_LIBC_STDIO
622 644
623 // EOF stream.cxx 645 // EOF stream.cxx