fopenport.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* Copyright (C) 1994-2026 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <https://www.gnu.org/licenses/>. */
  14. #include <hurd.h>
  15. #include <stdio.h>
  16. #include <fcntl.h>
  17. #include <string.h>
  18. /* Read up to N chars into BUF from COOKIE.
  19. Return how many chars were read, 0 for EOF or -1 for error. */
  20. static ssize_t
  21. readio (void *cookie, char *buf, size_t n)
  22. {
  23. mach_msg_type_number_t nread;
  24. error_t err;
  25. char *bufp = buf;
  26. io_t io = (io_t) (uintptr_t) cookie;
  27. nread = n;
  28. if (err = __io_read (io, &bufp, &nread, -1, n))
  29. return __hurd_fail (err);
  30. if (bufp != buf)
  31. {
  32. memcpy (buf, bufp, nread);
  33. __vm_deallocate (__mach_task_self (),
  34. (vm_address_t) bufp, (vm_size_t) nread);
  35. }
  36. return nread;
  37. }
  38. /* Write up to N chars from BUF to COOKIE.
  39. Return how many chars were written or -1 for error. */
  40. static ssize_t
  41. writeio (void *cookie, const char *buf, size_t n)
  42. {
  43. vm_size_t wrote;
  44. error_t err;
  45. io_t io = (io_t) (uintptr_t) cookie;
  46. if (err = __io_write (io, buf, n, -1, &wrote))
  47. return __hurd_fail (err);
  48. return wrote;
  49. }
  50. /* Move COOKIE's file position *POS bytes, according to WHENCE.
  51. The current file position is stored in *POS.
  52. Returns zero if successful, nonzero if not. */
  53. static int
  54. seekio (void *cookie,
  55. off64_t *pos,
  56. int whence)
  57. {
  58. io_t io = (io_t) (uintptr_t) cookie;
  59. error_t err = __io_seek (io, *pos, whence, pos);
  60. return err ? __hurd_fail (err) : 0;
  61. }
  62. /* Close the file associated with COOKIE.
  63. Return 0 for success or -1 for failure. */
  64. static int
  65. closeio (void *cookie)
  66. {
  67. io_t io = (io_t) (uintptr_t) cookie;
  68. error_t error = __mach_port_deallocate (__mach_task_self (),
  69. io);
  70. if (error)
  71. return __hurd_fail (error);
  72. return 0;
  73. }
  74. #include "../libio/libioP.h"
  75. #define fopencookie _IO_fopencookie
  76. static const cookie_io_functions_t funcsio =
  77. { readio, writeio, seekio, closeio };
  78. /* Open a stream on PORT. MODE is as for fopen. */
  79. FILE *
  80. __fopenport (mach_port_t port, const char *mode)
  81. {
  82. int pflags;
  83. int needflags;
  84. error_t err;
  85. const char *m = mode;
  86. switch (*m++)
  87. {
  88. case 'r':
  89. needflags = O_READ;
  90. break;
  91. case 'w':
  92. needflags = O_WRITE;
  93. break;
  94. case 'a':
  95. needflags = O_WRITE|O_APPEND;
  96. break;
  97. default:
  98. return NULL;
  99. }
  100. if (m[0] == '+' || (m[0] == 'b' && m[1] == '+'))
  101. needflags |= O_RDWR;
  102. /* Verify the PORT is valid allows the access MODE specifies. */
  103. if (err = __io_get_openmodes (port, &pflags))
  104. return __hurd_fail (err), NULL;
  105. /* Check the access mode. */
  106. if ((pflags & needflags) != needflags)
  107. return __hurd_fail (EBADF), NULL;
  108. return fopencookie ((void *) (uintptr_t) port,
  109. mode, funcsio);
  110. }
  111. weak_alias (__fopenport, fopenport)