os/ossrv/genericopenlibs/cstdlib/LSTDIO/FREOPEN.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* FREOPEN.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1990-1999 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     4
 * All rights reserved.
sl@0
     5
 */
sl@0
     6
sl@0
     7
/*
sl@0
     8
 * Copyright (c) 1990 The Regents of the University of California.
sl@0
     9
 * All rights reserved.
sl@0
    10
 *
sl@0
    11
 * Redistribution and use in source and binary forms are permitted
sl@0
    12
 * provided that the above copyright notice and this paragraph are
sl@0
    13
 * duplicated in all such forms and that any documentation,
sl@0
    14
 * advertising materials, and other materials related to such
sl@0
    15
 * distribution and use acknowledge that the software was developed
sl@0
    16
 * by the University of California, Berkeley.  The name of the
sl@0
    17
 * University may not be used to endorse or promote products derived
sl@0
    18
 * from this software without specific prior written permission.
sl@0
    19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
sl@0
    20
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
sl@0
    21
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
sl@0
    22
 */
sl@0
    23
sl@0
    24
/*
sl@0
    25
FUNCTION
sl@0
    26
<<freopen>>---open a file using an existing file descriptor
sl@0
    27
sl@0
    28
INDEX
sl@0
    29
	freopen
sl@0
    30
sl@0
    31
ANSI_SYNOPSIS
sl@0
    32
	#include <stdio.h>
sl@0
    33
	FILE *freopen(const char *<[file]>, const char *<[mode]>,
sl@0
    34
		      FILE *<[fp]>);
sl@0
    35
sl@0
    36
TRAD_SYNOPSIS
sl@0
    37
	#include <stdio.h>
sl@0
    38
	FILE *freopen(<[file]>, <[mode]>, <[fp]>)
sl@0
    39
	char *<[file]>;
sl@0
    40
	char *<[mode]>;
sl@0
    41
	FILE *<[fp]>;
sl@0
    42
sl@0
    43
DESCRIPTION
sl@0
    44
Use this variant of <<fopen>> if you wish to specify a particular file
sl@0
    45
descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for
sl@0
    46
the file.
sl@0
    47
sl@0
    48
If <[fp]> was associated with another file or stream, <<freopen>>
sl@0
    49
closes that other file or stream (but ignores any errors while closing
sl@0
    50
it).
sl@0
    51
sl@0
    52
<[file]> and <[mode]> are used just as in <<fopen>>.
sl@0
    53
sl@0
    54
RETURNS
sl@0
    55
If successful, the result is the same as the argument <[fp]>.  If the
sl@0
    56
file cannot be opened as specified, the result is <<NULL>>.
sl@0
    57
sl@0
    58
PORTABILITY
sl@0
    59
ANSI C requires <<freopen>>.
sl@0
    60
sl@0
    61
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
sl@0
    62
<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
sl@0
    63
*/
sl@0
    64
sl@0
    65
#include <time.h>
sl@0
    66
#include <stdio_r.h>
sl@0
    67
#include <fcntl.h>
sl@0
    68
#include <stdlib_r.h>
sl@0
    69
#include "LOCAL.H"
sl@0
    70
#include <errno.h>
sl@0
    71
sl@0
    72
/*
sl@0
    73
 * Re-direct an existing, open (probably) file to some other file.
sl@0
    74
 */
sl@0
    75
sl@0
    76
#define MaxFullName 255
sl@0
    77
sl@0
    78
/**
sl@0
    79
Reopen a stream with a different file and mode.
sl@0
    80
@return If the file has been succesfully reopened the function returns a pointer to the file.
sl@0
    81
Otherwise a NULL pointer is returned.
sl@0
    82
@param file name of the file to be opened. 
sl@0
    83
This paramenter must follow operating system's specifications and can include a path 
sl@0
    84
if the system supports it.
sl@0
    85
@param mode type of access requested.
sl@0
    86
@param fp pointer to open file that has to be reopened.
sl@0
    87
*/
sl@0
    88
EXPORT_C FILE * freopen (const char *file, const char *mode, FILE *fp)
sl@0
    89
{
sl@0
    90
  	wchar_t _wfile[MaxFullName+1];	
sl@0
    91
	wchar_t _wmode[MaxFullName+1];
sl@0
    92
	struct _reent *ptr;
sl@0
    93
sl@0
    94
	if ((-1 != mbstowcs(_wfile, file, MaxFullName)) && 
sl@0
    95
		(-1 != mbstowcs(_wmode, mode, MaxFullName)))
sl@0
    96
	{
sl@0
    97
		return wfreopen(_wfile, _wmode, fp);
sl@0
    98
	}
sl@0
    99
sl@0
   100
	CHECK_INIT (fp);
sl@0
   101
	ptr = fp->_data;
sl@0
   102
	ptr->_errno = EILSEQ;
sl@0
   103
	return NULL;
sl@0
   104
}
sl@0
   105
sl@0
   106
EXPORT_C FILE * wfreopen (const wchar_t *file, const wchar_t *mode, FILE *fp)
sl@0
   107
{
sl@0
   108
  register int f;
sl@0
   109
  int isopen, flags, oflags, e;
sl@0
   110
  struct _reent *ptr;
sl@0
   111
sl@0
   112
  CHECK_INIT (fp);
sl@0
   113
  ptr = fp->_data;
sl@0
   114
sl@0
   115
  if ((flags = __sflags (ptr, mode, &oflags)) == 0)
sl@0
   116
    {
sl@0
   117
      (void) fclose (fp);
sl@0
   118
      return NULL;
sl@0
   119
    }
sl@0
   120
sl@0
   121
  /*
sl@0
   122
   * Remember whether the stream was open to begin with, and
sl@0
   123
   * which file descriptor (if any) was associated with it.
sl@0
   124
   * If it was attached to a descriptor, defer closing it,
sl@0
   125
   * so that, e.g., freopen("/dev/stdin", "r", stdin) works.
sl@0
   126
   * This is unnecessary if it was not a Unix file.
sl@0
   127
   */
sl@0
   128
sl@0
   129
  if (fp->_flags == 0)
sl@0
   130
    {
sl@0
   131
      fp->_flags = __SEOF;	/* hold on to it */
sl@0
   132
      isopen = 0;
sl@0
   133
    }
sl@0
   134
  else
sl@0
   135
    {
sl@0
   136
      if (fp->_flags & __SWR)
sl@0
   137
	(void) fflush (fp);
sl@0
   138
      /* if close is NULL, closing is a no-op, hence pointless */
sl@0
   139
      isopen = fp->_close != NULL;
sl@0
   140
      if (fp->_file < 0 && isopen)
sl@0
   141
	{
sl@0
   142
	  (void) (*fp->_close) (fp->_cookie);
sl@0
   143
	  isopen = 0;
sl@0
   144
	}
sl@0
   145
    }
sl@0
   146
sl@0
   147
  /*
sl@0
   148
   * Now get a new descriptor to refer to the new file.
sl@0
   149
   */
sl@0
   150
sl@0
   151
  f = _wopen_r (ptr, (wchar_t *)file, oflags, 0666);
sl@0
   152
  if (f < 0 && isopen)
sl@0
   153
    {
sl@0
   154
      /*
sl@0
   155
       * May have used up all descriptors, so close the old
sl@0
   156
       * and try again.
sl@0
   157
       */
sl@0
   158
      (void) (*fp->_close) (fp->_cookie);
sl@0
   159
      isopen = 0;
sl@0
   160
      f = _wopen_r (ptr, (wchar_t *) file, oflags, 0666);
sl@0
   161
    }
sl@0
   162
  e = ptr->_errno;
sl@0
   163
sl@0
   164
  /*
sl@0
   165
   * Finish closing fp.  Even if the open succeeded above,
sl@0
   166
   * we cannot keep fp->_base: it may be the wrong size.
sl@0
   167
   * This loses the effect of any setbuffer calls,
sl@0
   168
   * but stdio has always done this before.
sl@0
   169
   */
sl@0
   170
sl@0
   171
  if (isopen)
sl@0
   172
    (void) (*fp->_close) (fp->_cookie);
sl@0
   173
  if (fp->_flags & __SMBF)
sl@0
   174
    _free_r (ptr, (char *) fp->_bf._base);
sl@0
   175
  fp->_w = 0;
sl@0
   176
  fp->_r = 0;
sl@0
   177
  fp->_p = NULL;
sl@0
   178
  fp->_bf._base = NULL;
sl@0
   179
  fp->_bf._size = 0;
sl@0
   180
  fp->_lbfsize = 0;
sl@0
   181
  if (HASUB (fp))
sl@0
   182
    FREEUB (fp);
sl@0
   183
  fp->_ub._size = 0;
sl@0
   184
  if (HASLB (fp))
sl@0
   185
    FREELB (fp);
sl@0
   186
  fp->_lb._size = 0;
sl@0
   187
sl@0
   188
  if (f < 0)
sl@0
   189
    {				/* did not get it after all */
sl@0
   190
      fp->_flags = 0;		/* set it free */
sl@0
   191
      ptr->_errno = e;		/* restore in case _close clobbered */
sl@0
   192
      return NULL;
sl@0
   193
    }
sl@0
   194
sl@0
   195
  fp->_flags = (short)flags;
sl@0
   196
  fp->_file = (short)f;
sl@0
   197
  fp->_cookie = (void*) fp;
sl@0
   198
  fp->_read = __sread;
sl@0
   199
  fp->_write = __swrite;
sl@0
   200
  fp->_seek = __sseek;
sl@0
   201
  fp->_close = __sclose;
sl@0
   202
  return fp;
sl@0
   203
}