1 /* stdio on a Mach device port.
2 Translates \n to \r\n on output, echos and translates \r to \n on input.
3 Copyright (C) 1992, 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
23 #include <device/device.h>
33 mach_msg_type_number_t nread
;
36 if (f
->__buffer
== NULL
)
44 to_read
= f
->__bufsize
;
50 err
= device_read_inband ((device_t
) f
->__cookie
, 0, f
->__target
,
51 to_read
, buffer
, &nread
);
56 f
->__bufp
= f
->__get_limit
= f
->__put_limit
= f
->__buffer
;
62 err
= device_write_inband ((device_t
) f
->__cookie
, 0, f
->__target
,
63 buffer
, nread
, (int *) &to_read
);
65 /* Translate LF to CR. */
68 for (p
= memchr (buffer
, '\r', nread
); p
;
69 p
= memchr (p
+ 1, '\r', (buffer
+ nread
) - (p
+ 1)))
73 if (f
->__buffer
== NULL
)
74 return (unsigned char) c
;
76 f
->__get_limit
= f
->__buffer
+ nread
;
77 f
->__bufp
= f
->__buffer
;
78 f
->__put_limit
= f
->__buffer
+ (f
->__mode
.__write
? f
->__bufsize
: 0);
79 return (unsigned char) *f
->__bufp
++;
85 output (FILE *f
, int c
)
87 inline void write_some (const char *p
, size_t to_write
)
93 if (err
= device_write ((device_t
) f
->__cookie
, 0,
94 f
->__target
, (char *)p
,
103 f
->__target
+= wrote
;
107 if (f
->__buffer
!= NULL
)
109 if (f
->__put_limit
== f
->__buffer
)
111 /* Prime the stream for writing. */
112 f
->__put_limit
= f
->__buffer
+ f
->__bufsize
;
113 f
->__bufp
= f
->__buffer
;
116 *f
->__bufp
++ = (unsigned char) c
;
122 /* Write out the buffer. */
124 write_some (f
->__buffer
, f
->__bufp
- f
->__buffer
);
126 f
->__bufp
= f
->__buffer
;
129 if (c
!= EOF
&& !ferror (f
))
131 if (f
->__linebuf
&& (unsigned char) c
== '\n')
133 static const char nl
= '\n';
137 *f
->__bufp
++ = (unsigned char) c
;
144 output (FILE *f
, int c
)
146 void write_some (const char *p
, size_t to_write
)
154 thiswrite
= to_write
;
155 if (thiswrite
> IO_INBAND_MAX
)
156 thiswrite
= IO_INBAND_MAX
;
158 if (err
= device_write_inband ((device_t
) f
->__cookie
, 0,
159 f
->__target
, p
, thiswrite
, &wrote
))
167 f
->__target
+= wrote
;
170 void write_crlf (void)
172 static const char crlf
[] = "\r\n";
173 write_some (crlf
, 2);
176 if (f
->__buffer
== NULL
)
178 /* The stream is unbuffered. */
184 char cc
= (unsigned char) c
;
191 if (f
->__put_limit
== f
->__buffer
)
193 /* Prime the stream for writing. */
194 f
->__put_limit
= f
->__buffer
+ f
->__bufsize
;
195 f
->__bufp
= f
->__buffer
;
198 *f
->__bufp
++ = (unsigned char) c
;
204 /* Search for newlines (LFs) in the buffer. */
206 char *start
= f
->__buffer
, *p
= start
;
208 while (!ferror (f
) && (p
= memchr (p
, '\n', f
->__bufp
- start
)))
210 /* Found one. Replace it with a CR and write out through that CR. */
213 write_some (start
, p
+ 1 - start
);
215 /* Change it back to an LF; the next iteration will write it out
216 first thing. Start the next searching iteration one char later. */
222 /* Write the remainder of the buffer. */
225 write_some (start
, f
->__bufp
- start
);
228 f
->__bufp
= f
->__buffer
;
230 if (c
!= EOF
&& !ferror (f
))
232 if (f
->__linebuf
&& (unsigned char) c
== '\n')
235 *f
->__bufp
++ = (unsigned char) c
;
240 dealloc_ref (void *cookie
)
242 if (mach_port_deallocate (mach_task_self (), (mach_port_t
) cookie
))
252 mach_open_devstream (mach_port_t dev
, const char *mode
)
256 if (mach_port_mod_refs (mach_task_self (), dev
, MACH_PORT_RIGHT_SEND
, 1))
262 stream
= fopencookie ((void *) dev
, mode
, __default_io_functions
);
265 mach_port_deallocate (mach_task_self (), dev
);
269 stream
->__room_funcs
.__input
= input
;
270 stream
->__room_funcs
.__output
= output
;
271 stream
->__io_funcs
.__close
= dealloc_ref
;
272 stream
->__io_funcs
.__seek
= NULL
; /* Cannot seek. */
273 stream
->__io_funcs
.__fileno
= NULL
; /* No corresponding POSIX.1 fd. */