1 /* Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
21 #include <sys/types.h>
26 extern __io_read_fn __stdio_read
;
27 extern __io_write_fn __stdio_write
;
28 extern __io_seek_fn __stdio_seek
;
29 extern __io_close_fn __stdio_close
;
30 extern __io_fileno_fn __stdio_fileno
;
33 /* Check ERR for wanting to generate a signal. */
36 fd_fail (struct hurd_fd
*fd
, error_t err
)
38 int signo
= _hurd_fd_error_signal (err
);
41 const struct hurd_signal_detail detail
42 = { code
: __stdio_fileno (fd
), error
: err
, exc
: 0 };
43 _hurd_raise_signal (NULL
, signo
, &detail
);
50 /* Read up to N chars into BUF from COOKIE.
51 Return how many chars were read, 0 for EOF or -1 for error. */
53 __stdio_read (cookie
, buf
, n
)
59 struct hurd_fd
*fd
= cookie
;
62 return __hurd_fail (EBADF
);
64 if (err
= _hurd_fd_read (fd
, buf
, &n
, -1))
65 return fd_fail (fd
, err
);
70 /* Write up to N chars from BUF to COOKIE.
71 Return how many chars were written or -1 for error. */
73 __stdio_write (cookie
, buf
, n
)
80 struct hurd_fd
*fd
= cookie
;
83 return __hurd_fail (EBADF
);
89 if (err
= _hurd_fd_write (fd
, buf
, &wrote
, -1))
90 return fd_fail (fd
, err
);
98 /* Move COOKIE's file position *POS bytes, according to WHENCE.
99 The current file position is stored in *POS.
100 Returns zero if successful, nonzero if not. */
102 __stdio_seek (cookie
, pos
, whence
)
108 struct hurd_fd
*fd
= cookie
;
110 return __hurd_fail (EBADF
);
111 err
= HURD_FD_PORT_USE (fd
, __io_seek (port
, *pos
, whence
, pos
));
112 return err
? fd_fail (fd
, err
) : 0;
115 /* Close the file associated with COOKIE.
116 Return 0 for success or -1 for failure. */
118 __stdio_close (cookie
)
121 error_t error
= cookie
? _hurd_fd_close (cookie
) : EBADF
;
122 return error
? fd_fail (cookie
, error
) : 0;
127 modeflags (__io_mode m
)
145 /* Open FILENAME with the mode in M. */
147 __stdio_open (filename
, m
, cookieptr
)
148 const char *filename
;
156 flags
= modeflags (m
);
157 port
= __file_name_lookup (filename
, flags
, 0666 & ~_hurd_umask
);
158 if (port
== MACH_PORT_NULL
)
162 d
= _hurd_alloc_fd (NULL
, 0);
165 _hurd_port2fd (d
, port
, flags
);
166 __spin_unlock (&d
->port
.lock
);
175 /* Open FILENAME with the mode in M. Use the same magic cookie
176 already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN. */
178 __stdio_reopen (filename
, m
, cookieptr
, closefn
)
179 const char *filename
;
182 __io_close_fn closefn
;
188 if (closefn
!= __stdio_close
)
190 /* The old cookie is Not Of The Body.
191 Just close it and do a normal open. */
192 (*closefn
) (*cookieptr
);
193 return __stdio_open (filename
, m
, cookieptr
);
196 /* Open a new port on the file. */
197 flags
= modeflags (m
);
198 port
= __file_name_lookup (filename
, flags
, 0666 & ~_hurd_umask
);
200 /* Install the new port in the same file descriptor slot the old cookie
201 points to. If opening the file failed, PORT will be MACH_PORT_NULL
202 and installing it in the descriptor will have the effect of closing
203 the old descriptor. */
207 __spin_lock (&d
->port
.lock
);
208 _hurd_port2fd (d
, port
, flags
);
209 __spin_unlock (&d
->port
.lock
);
212 return port
== MACH_PORT_NULL
? -1 : 0;
216 /* Write a message to the error output.
217 Try hard to make it really get out. */
219 __stdio_errmsg (msg
, len
)
224 mach_msg_type_number_t wrote
;
226 server
= __getdport (2);
227 __io_write (server
, msg
, len
, -1, &wrote
);
228 __mach_port_deallocate (__mach_task_self (), server
);
232 /* Return the POSIX.1 file descriptor associated with COOKIE,
233 or -1 for errors. If COOKIE does not relate to any POSIX.1 file
234 descriptor, this should return -1 with errno set to EOPNOTSUPP. */
236 __stdio_fileno (cookie
)
242 return __hurd_fail (EBADF
);
244 __mutex_lock (&_hurd_dtable_lock
);
245 for (fd
= 0; fd
< _hurd_dtablesize
; ++fd
)
246 if (_hurd_dtable
[fd
] == cookie
)
248 __mutex_unlock (&_hurd_dtable_lock
);
251 __mutex_unlock (&_hurd_dtable_lock
);
253 /* This should never happen, because this function should not be
254 installed as a stream's __fileno function unless that stream's cookie
255 points to a file descriptor. */