entered into RCS
[kopensolaris-gnu/glibc.git] / hurd / fopenport.c
1 /* Copyright (C) 1994 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <ansidecl.h>
20 #include <hurd.h>
21 #include <stdio.h>
22 #include <fcntl.h>
23
24
25 /* Read up to N chars into BUF from COOKIE.
26    Return how many chars were read, 0 for EOF or -1 for error.  */
27 static ssize_t
28 readio (void *cookie, char *buf, size_t n)
29 {
30   unsigned int nread;
31   error_t err;
32   char *bufp = buf;
33
34   nread = n;
35   if (err = __io_read ((io_t) cookie, &bufp, &nread, -1, n))
36     return __hurd_fail (err);
37
38   if (bufp != buf)
39     {
40       memcpy (buf, bufp, nread);
41       __vm_deallocate (__mach_task_self (),
42                        (vm_address_t) bufp, (vm_size_t) nread);
43     }
44
45   return nread;
46 }
47
48 /* Write up to N chars from BUF to COOKIE.
49    Return how many chars were written or -1 for error.  */
50 static ssize_t
51 writeio (void *cookie, const char *buf, size_t n)
52 {
53   unsigned int wrote;
54   error_t err;
55
56   if (err = __io_write ((io_t) cookie, buf, n, -1, &wrote))
57     return __hurd_fail (err);
58
59   return wrote;
60 }
61
62 /* Move COOKIE's file position *POS bytes, according to WHENCE.
63    The current file position is stored in *POS.
64    Returns zero if successful, nonzero if not.  */
65 static int
66 seekio (void *cookie, fpos_t *pos, int whence)
67 {
68   error_t error = __io_seek ((file_t) cookie, *pos, whence, pos);
69   if (error)
70     return __hurd_fail (error);
71   return 0;
72 }
73
74 /* Close the file associated with COOKIE.
75    Return 0 for success or -1 for failure.  */
76 static int
77 closeio (void *cookie)
78 {
79   error_t error = __mach_port_deallocate (__mach_task_self (),
80                                           (mach_port_t) cookie);
81   if (error)
82     return __hurd_fail (error);
83   return 0;
84 }
85
86 static const __io_functions funcsio = { readio, writeio, seekio, closeio };
87 \f
88
89 /* Defined in fopen.c.  */
90 extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr));
91
92
93 /* Open a stream on PORT.  MODE is as for fopen.  */
94
95 FILE *
96 __fopenport (mach_port_t port, const char *mode)
97 {
98   register FILE *stream;
99   __io_mode m;
100   int pflags;
101   error_t err;
102
103   if (!__getmode (mode, &m))
104     return NULL;
105
106   /* Verify the PORT is valid allows the access MODE specifies.  */
107
108   if (err = __io_get_openmodes (port, &pflags))
109     return __hurd_fail (err), NULL;
110
111   /* Check the access mode.  */
112   if ((m.__read && !(pflags & O_READ)) || (m.__write && !(pflags & O_WRITE)))
113     {
114       errno = EBADF;
115       return NULL;
116     }
117
118   stream = __newstream ();
119   if (stream == NULL)
120     return NULL;
121
122   stream->__cookie = (PTR) port;
123   stream->__mode = m;
124   stream->__io_funcs = funcsio;
125   stream->__room_funcs = __default_room_functions;
126   stream->__seen = 1;
127
128   return stream;
129 }