(root)/
glibc-2.38/
hurd/
fopenport.c
       1  /* Copyright (C) 1994-2023 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 Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the 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     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <hurd.h>
      19  #include <stdio.h>
      20  #include <fcntl.h>
      21  #include <string.h>
      22  
      23  /* Read up to N chars into BUF from COOKIE.
      24     Return how many chars were read, 0 for EOF or -1 for error.  */
      25  static ssize_t
      26  readio (void *cookie, char *buf, size_t n)
      27  {
      28    mach_msg_type_number_t nread;
      29    error_t err;
      30    char *bufp = buf;
      31    io_t io = (io_t) (uintptr_t) cookie;
      32  
      33    nread = n;
      34    if (err = __io_read (io, &bufp, &nread, -1, n))
      35      return __hurd_fail (err);
      36  
      37    if (bufp != buf)
      38      {
      39        memcpy (buf, bufp, nread);
      40        __vm_deallocate (__mach_task_self (),
      41  		       (vm_address_t) bufp, (vm_size_t) nread);
      42      }
      43  
      44    return nread;
      45  }
      46  
      47  /* Write up to N chars from BUF to COOKIE.
      48     Return how many chars were written or -1 for error.  */
      49  static ssize_t
      50  writeio (void *cookie, const char *buf, size_t n)
      51  {
      52    vm_size_t wrote;
      53    error_t err;
      54    io_t io = (io_t) (uintptr_t) cookie;
      55  
      56    if (err = __io_write (io, 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,
      67  	off64_t *pos,
      68  	int whence)
      69  {
      70    io_t io = (io_t) (uintptr_t) cookie;
      71    error_t err = __io_seek (io, *pos, whence, pos);
      72    return err ? __hurd_fail (err) : 0;
      73  }
      74  
      75  /* Close the file associated with COOKIE.
      76     Return 0 for success or -1 for failure.  */
      77  static int
      78  closeio (void *cookie)
      79  {
      80    io_t io = (io_t) (uintptr_t) cookie;
      81    error_t error = __mach_port_deallocate (__mach_task_self (),
      82  					  io);
      83    if (error)
      84      return __hurd_fail (error);
      85    return 0;
      86  }
      87  
      88  #include "../libio/libioP.h"
      89  #define fopencookie _IO_fopencookie
      90  static const cookie_io_functions_t funcsio =
      91  { readio, writeio, seekio, closeio };
      92  
      93  
      94  /* Open a stream on PORT.  MODE is as for fopen.  */
      95  
      96  FILE *
      97  __fopenport (mach_port_t port, const char *mode)
      98  {
      99    int pflags;
     100    int needflags;
     101    error_t err;
     102  
     103    const char *m = mode;
     104  
     105    switch (*m++)
     106      {
     107      case 'r':
     108        needflags = O_READ;
     109        break;
     110      case 'w':
     111        needflags = O_WRITE;
     112        break;
     113      case 'a':
     114        needflags = O_WRITE|O_APPEND;
     115        break;
     116      default:
     117        return NULL;
     118    }
     119    if (m[0] == '+' || (m[0] == 'b' && m[1] == '+'))
     120      needflags |= O_RDWR;
     121  
     122    /* Verify the PORT is valid allows the access MODE specifies.  */
     123  
     124    if (err = __io_get_openmodes (port, &pflags))
     125      return __hurd_fail (err), NULL;
     126  
     127    /* Check the access mode.  */
     128    if ((pflags & needflags) != needflags)
     129      return __hurd_fail (EBADF), NULL;
     130  
     131    return fopencookie ((void *) (uintptr_t) port,
     132                        mode, funcsio);
     133  }
     134  weak_alias (__fopenport, fopenport)