1 /* Copyright (C) 1994, 1995, 1996, 1997 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 /* Check ERR for wanting to generate a signal. */
28 int __stdio_fileno (void *);
31 fd_fail (struct hurd_fd
*fd
, error_t err
)
33 int signo
= _hurd_fd_error_signal (err
);
36 const struct hurd_signal_detail detail
37 = { code
: __stdio_fileno (fd
), error
: err
, exc
: 0 };
38 _hurd_raise_signal (NULL
, signo
, &detail
);
45 /* Read up to N chars into BUF from COOKIE.
46 Return how many chars were read, 0 for EOF or -1 for error. */
48 __stdio_read (cookie
, buf
, n
)
54 struct hurd_fd
*fd
= cookie
;
57 return __hurd_fail (EBADF
);
59 if (err
= _hurd_fd_read (fd
, buf
, &n
))
60 return fd_fail (fd
, err
);
65 /* Write up to N chars from BUF to COOKIE.
66 Return how many chars were written or -1 for error. */
68 __stdio_write (cookie
, buf
, n
)
75 struct hurd_fd
*fd
= cookie
;
78 return __hurd_fail (EBADF
);
84 if (err
= _hurd_fd_write (fd
, buf
, &wrote
))
85 return fd_fail (fd
, err
);
93 /* Move COOKIE's file position *POS bytes, according to WHENCE.
94 The current file position is stored in *POS.
95 Returns zero if successful, nonzero if not. */
97 __stdio_seek (cookie
, pos
, whence
)
103 struct hurd_fd
*fd
= cookie
;
105 return __hurd_fail (EBADF
);
106 err
= HURD_FD_PORT_USE (fd
, __io_seek (port
, *pos
, whence
, pos
));
107 return err
? fd_fail (fd
, err
) : 0;
110 /* Close the file associated with COOKIE.
111 Return 0 for success or -1 for failure. */
113 __stdio_close (cookie
)
116 error_t error
= cookie
? _hurd_fd_close (cookie
) : EBADF
;
117 return error
? fd_fail (cookie
, error
) : 0;
122 modeflags (__io_mode m
)
140 /* Open FILENAME with the mode in M. */
142 __stdio_open (filename
, m
, cookieptr
)
143 const char *filename
;
151 flags
= modeflags (m
);
152 port
= __file_name_lookup (filename
, flags
, 0666 & ~_hurd_umask
);
153 if (port
== MACH_PORT_NULL
)
157 d
= _hurd_alloc_fd (NULL
, 0);
160 _hurd_port2fd (d
, port
, flags
);
161 __spin_unlock (&d
->port
.lock
);
170 /* Open FILENAME with the mode in M. Use the same magic cookie
171 already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN. */
173 __stdio_reopen (filename
, m
, cookieptr
, closefn
)
174 const char *filename
;
177 __io_close_fn closefn
;
183 if (closefn
!= __stdio_close
)
185 /* The old cookie is Not Of The Body.
186 Just close it and do a normal open. */
187 (*closefn
) (*cookieptr
);
188 return __stdio_open (filename
, m
, cookieptr
);
191 /* Open a new port on the file. */
192 flags
= modeflags (m
);
193 port
= __file_name_lookup (filename
, flags
, 0666 & ~_hurd_umask
);
195 /* Install the new port in the same file descriptor slot the old cookie
196 points to. If opening the file failed, PORT will be MACH_PORT_NULL
197 and installing it in the descriptor will have the effect of closing
198 the old descriptor. */
202 __spin_lock (&d
->port
.lock
);
203 _hurd_port2fd (d
, port
, flags
);
204 __spin_unlock (&d
->port
.lock
);
207 return port
== MACH_PORT_NULL
? -1 : 0;
211 /* Write a message to the error output.
212 Try hard to make it really get out. */
214 __stdio_errmsg (msg
, len
)
219 mach_msg_type_number_t wrote
;
221 server
= __getdport (2);
222 __io_write (server
, msg
, len
, -1, &wrote
);
223 __mach_port_deallocate (__mach_task_self (), server
);
227 /* Return the POSIX.1 file descriptor associated with COOKIE,
228 or -1 for errors. If COOKIE does not relate to any POSIX.1 file
229 descriptor, this should return -1 with errno set to EOPNOTSUPP. */
231 __stdio_fileno (cookie
)
237 return __hurd_fail (EBADF
);
239 __mutex_lock (&_hurd_dtable_lock
);
240 for (fd
= 0; fd
< _hurd_dtablesize
; ++fd
)
241 if (_hurd_dtable
[fd
] == cookie
)
243 __mutex_unlock (&_hurd_dtable_lock
);
246 __mutex_unlock (&_hurd_dtable_lock
);
248 /* This should never happen, because this function should not be
249 installed as a stream's __fileno function unless that stream's cookie
250 points to a file descriptor. */