Back to index

glibc  2.9
fopenport.c
Go to the documentation of this file.
00001 /* Copyright (C) 1994,95,97,2000,01,02 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <hurd.h>
00020 #include <stdio.h>
00021 #include <fcntl.h>
00022 #include <string.h>
00023 
00024 /* Read up to N chars into BUF from COOKIE.
00025    Return how many chars were read, 0 for EOF or -1 for error.  */
00026 static ssize_t
00027 readio (void *cookie, char *buf, size_t n)
00028 {
00029   mach_msg_type_number_t nread;
00030   error_t err;
00031   char *bufp = buf;
00032 
00033   nread = n;
00034   if (err = __io_read ((io_t) cookie, &bufp, &nread, -1, n))
00035     return __hurd_fail (err);
00036 
00037   if (bufp != buf)
00038     {
00039       memcpy (buf, bufp, nread);
00040       __vm_deallocate (__mach_task_self (),
00041                      (vm_address_t) bufp, (vm_size_t) nread);
00042     }
00043 
00044   return nread;
00045 }
00046 
00047 /* Write up to N chars from BUF to COOKIE.
00048    Return how many chars were written or -1 for error.  */
00049 static ssize_t
00050 writeio (void *cookie, const char *buf, size_t n)
00051 {
00052   mach_msg_type_number_t wrote;
00053   error_t err;
00054 
00055   if (err = __io_write ((io_t) cookie, buf, n, -1, &wrote))
00056     return __hurd_fail (err);
00057 
00058   return wrote;
00059 }
00060 
00061 /* Move COOKIE's file position *POS bytes, according to WHENCE.
00062    The current file position is stored in *POS.
00063    Returns zero if successful, nonzero if not.  */
00064 static int
00065 seekio (void *cookie,
00066 #ifdef USE_IN_LIBIO
00067        _IO_off64_t *pos,
00068 #else
00069        fpos_t *pos,
00070 #endif
00071        int whence)
00072 {
00073   error_t err = __io_seek ((file_t) cookie, *pos, whence, pos);
00074   return err ? __hurd_fail (err) : 0;
00075 }
00076 
00077 /* Close the file associated with COOKIE.
00078    Return 0 for success or -1 for failure.  */
00079 static int
00080 closeio (void *cookie)
00081 {
00082   error_t error = __mach_port_deallocate (__mach_task_self (),
00083                                      (mach_port_t) cookie);
00084   if (error)
00085     return __hurd_fail (error);
00086   return 0;
00087 }
00088 
00089 #ifdef USE_IN_LIBIO
00090 #include "../libio/libioP.h"
00091 #define fopencookie _IO_fopencookie
00092 #else
00093 #define cookie_io_functions_t __io_functions
00094 #endif
00095 static const cookie_io_functions_t funcsio =
00096 { readio, writeio, seekio, closeio };
00097 
00098 
00099 /* Open a stream on PORT.  MODE is as for fopen.  */
00100 
00101 FILE *
00102 __fopenport (mach_port_t port, const char *mode)
00103 {
00104   int pflags;
00105   int needflags;
00106   error_t err;
00107 
00108   const char *m = mode;
00109 
00110   switch (*m++)
00111     {
00112     case 'r':
00113       needflags = O_READ;
00114       break;
00115     case 'w':
00116       needflags = O_WRITE;
00117       break;
00118     case 'a':
00119       needflags = O_WRITE|O_APPEND;
00120       break;
00121     default:
00122       return NULL;
00123   }
00124   if (m[0] == '+' || (m[0] == 'b' && m[1] == '+'))
00125     needflags |= O_RDWR;
00126 
00127   /* Verify the PORT is valid allows the access MODE specifies.  */
00128 
00129   if (err = __io_get_openmodes (port, &pflags))
00130     return __hurd_fail (err), NULL;
00131 
00132   /* Check the access mode.  */
00133   if ((pflags & needflags) != needflags)
00134     {
00135       errno = EBADF;
00136       return NULL;
00137     }
00138 
00139   return fopencookie ((void *) port, mode, funcsio);
00140 }
00141 weak_alias (__fopenport, fopenport)