]> git.ipfire.org Git - thirdparty/glibc.git/blame - hurd/hurd/fd.h
Update to 2.1.x development version
[thirdparty/glibc.git] / hurd / hurd / fd.h
CommitLineData
28f540f4 1/* File descriptors.
c84142e8
UD
2 Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
28f540f4
RM
19
20#ifndef _HURD_FD_H
21
22#define _HURD_FD_H 1
23#include <features.h>
24
25#include <hurd/hurd_types.h>
26#include <hurd/port.h>
27
28
29/* Structure representing a file descriptor. */
30
31struct hurd_fd
32 {
33 struct hurd_port port; /* io server port. */
34 int flags; /* fcntl flags; locked by port.lock. */
35
36 /* Normal port to the ctty. When `port' is our ctty, this is a port to
37 the same io object but which never returns EBACKGROUND; when not,
38 this is nil. */
39 struct hurd_port ctty;
40 };
41
42
43/* Current file descriptor table. */
44
45extern int _hurd_dtablesize;
46extern struct hurd_fd **_hurd_dtable;
47extern struct mutex _hurd_dtable_lock; /* Locks those two variables. */
48\f
49#include <hurd/signal.h>
50#include <lock-intern.h>
51
52#ifndef _EXTERN_INLINE
53#define _EXTERN_INLINE extern __inline
54#endif
55
56/* Returns the descriptor cell for FD. If FD is invalid or unused, return
57 NULL. The cell is unlocked; when ready to use it, lock it and check for
58 it being unused. */
59
60_EXTERN_INLINE struct hurd_fd *
61_hurd_fd_get (int fd)
62{
63 struct hurd_fd *descriptor;
64
65 __mutex_lock (&_hurd_dtable_lock);
66 if (fd < 0 || fd >= _hurd_dtablesize)
67 descriptor = NULL;
68 else
69 {
70 struct hurd_fd *cell = _hurd_dtable[fd];
71 if (cell == NULL)
72 /* No descriptor allocated at this index. */
73 descriptor = NULL;
74 else
75 {
76 __spin_lock (&cell->port.lock);
77 if (cell->port.port == MACH_PORT_NULL)
78 /* The descriptor at this index has no port in it.
79 This happens if it existed before but was closed. */
80 descriptor = NULL;
81 else
82 descriptor = cell;
83 __spin_unlock (&cell->port.lock);
84 }
85 }
86 __mutex_unlock (&_hurd_dtable_lock);
87
88 return descriptor;
89}
90
91
92/* Evaluate EXPR with the variable `descriptor' bound to a pointer to the
93 file descriptor structure for FD. */
94
95#define HURD_FD_USE(fd, expr) \
96 ({ struct hurd_fd *descriptor = _hurd_fd_get (fd); \
97 descriptor == NULL ? EBADF : (expr); })
98
99/* Evaluate EXPR with the variable `port' bound to the port to FD, and
100 `ctty' bound to the ctty port. */
101
102#define HURD_DPORT_USE(fd, expr) \
103 HURD_FD_USE ((fd), HURD_FD_PORT_USE (descriptor, (expr)))
104
105/* Likewise, but FD is a pointer to the file descriptor structure. */
106
107#define HURD_FD_PORT_USE(fd, expr) \
108 ({ error_t __result; \
109 struct hurd_fd *const __d = (fd); \
110 struct hurd_userlink __ulink, __ctty_ulink; \
111 io_t port, ctty; \
112 void *crit = _hurd_critical_section_lock (); \
113 __spin_lock (&__d->port.lock); \
114 if (__d->port.port == MACH_PORT_NULL) \
115 { \
116 __spin_unlock (&__d->port.lock); \
117 _hurd_critical_section_unlock (crit); \
118 __result = EBADF; \
119 } \
120 else \
121 { \
122 ctty = _hurd_port_get (&__d->ctty, &__ctty_ulink); \
123 port = _hurd_port_locked_get (&__d->port, &__ulink); \
124 _hurd_critical_section_unlock (crit); \
125 __result = (expr); \
126 _hurd_port_free (&__d->port, &__ulink, port); \
127 if (ctty != MACH_PORT_NULL) \
128 _hurd_port_free (&__d->ctty, &__ctty_ulink, ctty); \
129 } \
130 __result; })
131\f
132#include <errno.h>
133
134/* Check if ERR should generate a signal.
135 Returns the signal to take, or zero if none. */
136
137_EXTERN_INLINE error_t
138_hurd_fd_error_signal (error_t err)
139{
140 switch (err)
141 {
142 case EMACH_SEND_INVALID_DEST:
143 case EMIG_SERVER_DIED:
144 /* The server has disappeared! */
145 return SIGLOST;
146 case EPIPE:
147 return SIGPIPE;
148 default:
149 /* Having a default case avoids -Wenum-switch warnings. */
150 return 0;
151 }
152}
153
154/* Handle an error from an RPC on a file descriptor's port. You should
155 always use this function to handle errors from RPCs made on file
93a470c7 156 descriptor ports. Some errors are translated into signals. */
28f540f4
RM
157
158_EXTERN_INLINE error_t
159_hurd_fd_error (int fd, error_t err)
160{
161 int signo = _hurd_fd_error_signal (err);
162 if (signo)
93a470c7
RM
163 {
164 const struct hurd_signal_detail detail
165 = { code: fd, error: err, exc: 0 };
166 _hurd_raise_signal (NULL, signo, &detail);
167 }
28f540f4
RM
168 return err;
169}
170
171/* Handle error code ERR from an RPC on file descriptor FD's port.
172 Set `errno' to the appropriate error code, and always return -1. */
173
174_EXTERN_INLINE int
175__hurd_dfail (int fd, error_t err)
176{
177 errno = _hurd_fd_error (fd, err);
178 return -1;
179}
180\f
181/* Set up *FD to have PORT its server port, doing appropriate ctty magic.
182 Does no locking or unlocking. */
183
184extern void _hurd_port2fd (struct hurd_fd *fd, io_t port, int flags);
185
186/* Allocate a new file descriptor and install PORT in it (doing any
187 appropriate ctty magic); consumes a user reference on PORT. FLAGS are
188 as for `open'; only O_IGNORE_CTTY is meaningful, but all are saved.
189
190 If the descriptor table is full, set errno, and return -1.
191 If DEALLOC is nonzero, deallocate PORT first. */
192
193extern int _hurd_intern_fd (io_t port, int flags, int dealloc);
194
195/* Allocate a new file descriptor in the table and return it, locked. The
196 new descriptor number will be no less than FIRST_FD. If the table is
197 full, set errno to EMFILE and return NULL. If FIRST_FD is negative or
198 bigger than the size of the table, set errno to EINVAL and return NULL. */
199
200extern struct hurd_fd *_hurd_alloc_fd (int *fd_ptr, int first_fd);
201
202/* Allocate a new file descriptor structure and initialize its port cells
203 with PORT and CTTY. (This does not affect the descriptor table.) */
204
205extern struct hurd_fd *_hurd_new_fd (io_t port, io_t ctty);
206
207/* Close a file descriptor, making it available for future reallocation. */
208
209extern error_t _hurd_fd_close (struct hurd_fd *fd);
210
211/* Read and write data from a file descriptor; just like `read' and `write'.
212 If successful, stores the amount actually read or written in *NBYTES. */
213
214extern error_t _hurd_fd_read (struct hurd_fd *fd, void *buf, size_t *nbytes);
215extern error_t _hurd_fd_write (struct hurd_fd *fd,
216 const void *buf, size_t *nbytes);
217
218
219/* Call *RPC on PORT and/or CTTY; if a call on CTTY returns EBACKGROUND,
220 generate SIGTTIN/SIGTTOU or EIO as appropriate. */
221
222extern error_t _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t));
223extern error_t _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t));
224
225
226#endif /* hurd/fd.h */