source: trunk/libs/newlib/src/newlib/libc/stdio/fdopen.c @ 567

Last change on this file since 567 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 3.2 KB
Line 
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley.  The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18/*
19FUNCTION
20<<fdopen>>---turn open file into a stream
21
22INDEX
23        fdopen
24INDEX
25        _fdopen_r
26
27SYNOPSIS
28        #include <stdio.h>
29        FILE *fdopen(int <[fd]>, const char *<[mode]>);
30        FILE *_fdopen_r(struct _reent *<[reent]>,
31                        int <[fd]>, const char *<[mode]>);
32
33DESCRIPTION
34<<fdopen>> produces a file descriptor of type <<FILE *>>, from a
35descriptor for an already-open file (returned, for example, by the
36system subroutine <<open>> rather than by <<fopen>>).
37The <[mode]> argument has the same meanings as in <<fopen>>.
38
39RETURNS
40File pointer or <<NULL>>, as for <<fopen>>.
41
42PORTABILITY
43<<fdopen>> is ANSI.
44*/
45
46#include <_ansi.h>
47#include <reent.h>
48#include <sys/types.h>
49#include <sys/fcntl.h>
50#include <stdio.h>
51#include <errno.h>
52#include "local.h"
53#include <_syslist.h>
54
55FILE *
56_fdopen_r (struct _reent *ptr,
57       int fd,
58       const char *mode)
59{
60  register FILE *fp;
61  int flags, oflags;
62#ifdef HAVE_FCNTL
63  int fdflags, fdmode;
64#endif
65
66  if ((flags = __sflags (ptr, mode, &oflags)) == 0)
67    return 0;
68
69  /* make sure the mode the user wants is a subset of the actual mode */
70#ifdef HAVE_FCNTL
71  if ((fdflags = _fcntl_r (ptr, fd, F_GETFL, 0)) < 0)
72    return 0;
73  fdmode = fdflags & O_ACCMODE;
74  if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE)))
75    {
76      ptr->_errno = EBADF;
77      return 0;
78    }
79#endif
80
81  if ((fp = __sfp (ptr)) == 0)
82    return 0;
83
84  _newlib_flockfile_start (fp);
85
86  fp->_flags = flags;
87  /* POSIX recommends setting the O_APPEND bit on fd to match append
88     streams.  Someone may later clear O_APPEND on fileno(fp), but the
89     stream must still remain in append mode.  Rely on __sflags
90     setting __SAPP properly.  */
91#ifdef HAVE_FCNTL
92  if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
93    _fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND);
94#endif
95  fp->_file = fd;
96  fp->_cookie = (void *) fp;
97
98#undef _read
99#undef _write
100#undef _seek
101#undef _close
102
103  fp->_read = __sread;
104  fp->_write = __swrite;
105  fp->_seek = __sseek;
106  fp->_close = __sclose;
107
108#ifdef __SCLE
109  /* Explicit given mode results in explicit setting mode on fd */
110  if (oflags & O_BINARY)
111    setmode (fp->_file, O_BINARY);
112  else if (oflags & O_TEXT)
113    setmode (fp->_file, O_TEXT);
114  if (__stextmode (fp->_file))
115    fp->_flags |= __SCLE;
116#endif
117
118  _newlib_flockfile_end (fp);
119  return fp;
120}
121
122#ifndef _REENT_ONLY
123
124FILE *
125fdopen (int fd,
126       const char *mode)
127{
128  return _fdopen_r (_REENT, fd, mode);
129}
130
131#endif
Note: See TracBrowser for help on using the repository browser.