fopencookie.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
  2. *
  3. * GNU Library General Public License (LGPL) version 2 or later.
  4. *
  5. * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
  6. */
  7. #include <features.h>
  8. #ifdef __USE_GNU
  9. #include "_stdio.h"
  10. #ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
  11. #error no custom streams!
  12. #endif
  13. /* NOTE: GLIBC difference!!! -- fopencookie
  14. * According to the info pages, glibc allows seeking within buffers even if
  15. * no seek function is supplied. We don't. */
  16. /* NOTE: GLIBC difference!!! -- fopencookie
  17. * When compiled without large file support, the offset pointer for the
  18. * cookie_seek function is off_t * and not off64_t * as for glibc. */
  19. /* NOTE: GLIBC difference!!! -- fopencookie (bcc only)
  20. * Since bcc doesn't support passing of structs, we define fopencookie as a
  21. * macro in terms of _fopencookie which takes a struct * for the io functions
  22. * instead.
  23. */
  24. /* Currently no real reentrancy issues other than a possible double close(). */
  25. #ifndef __BCC__
  26. FILE *fopencookie(void * __restrict cookie, const char * __restrict mode,
  27. cookie_io_functions_t io_functions)
  28. #else
  29. FILE *_fopencookie(void * __restrict cookie, const char * __restrict mode,
  30. register cookie_io_functions_t *io_functions)
  31. #endif
  32. {
  33. FILE *stream;
  34. _IO_cookie_file_t *new_f;
  35. new_f = malloc(sizeof(_IO_cookie_file_t));
  36. if (new_f == NULL) {
  37. return NULL;
  38. }
  39. new_f->__fp.__modeflags = __FLAG_FREEFILE;
  40. #ifdef __STDIO_BUFFERS
  41. new_f->__fp.__bufstart = NULL; /* We allocate a buffer below. */
  42. #endif
  43. #ifdef __UCLIBC_HAS_THREADS__
  44. /* We only initialize the mutex in the non-freopen case. */
  45. STDIO_INIT_MUTEX(new_f->__fp.__lock);
  46. #endif
  47. /* Fake an fdopen guaranteed to pass the _stdio_fopen basic agreement
  48. * check without an fcntl call. */
  49. stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, &new_f->__fp, INT_MAX);
  50. if (stream) {
  51. stream->__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES;
  52. #ifndef __BCC__
  53. new_f->__gcs = io_functions;
  54. #else
  55. new_f->__gcs.read = io_functions->read;
  56. new_f->__gcs.write = io_functions->write;
  57. new_f->__gcs.seek = io_functions->seek;
  58. new_f->__gcs.close = io_functions->close;
  59. #endif
  60. new_f->__cookie = cookie;
  61. __STDIO_STREAM_VALIDATE(stream);
  62. }
  63. return stream;
  64. }
  65. #ifndef __BCC__
  66. libc_hidden_def(fopencookie)
  67. #endif
  68. #endif