Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / stdio / filereopen.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)filereopen.c     1.15 04/08/08 Copyright 1986, 1995 J. Schilling */
14 /*
15  *      open new file on old stream
16  *
17  *      Copyright (c) 1986, 1995 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include "schilyio.h"
35
36 /*
37  * Note that because of a definition in schilyio.h we are using fseeko()/ftello()
38  * instead of fseek()/ftell() if available.
39  */
40
41 LOCAL   char    *fmtab[] = {
42                         "",     /* 0    FI_NONE                         */
43                         "r",    /* 1    FI_READ                         */
44                         "r+",   /* 2    FI_WRITE                **1)    */
45                         "r+",   /* 3    FI_READ  | FI_WRITE             */
46                         "b",    /* 4    FI_NONE  | FI_BINARY            */
47                         "rb",   /* 5    FI_READ  | FI_BINARY            */
48                         "r+b",  /* 6    FI_WRITE | FI_BINARY    **1)    */
49                         "r+b",  /* 7    FI_READ  | FI_WRITE | FI_BINARY */
50
51 /* + FI_APPEND  */      "",     /* 0    FI_NONE                         */
52 /* ...          */      "r",    /* 1    FI_READ                         */
53                         "a",    /* 2    FI_WRITE                **1)    */
54                         "a+",   /* 3    FI_READ  | FI_WRITE             */
55                         "b",    /* 4    FI_NONE  | FI_BINARY            */
56                         "rb",   /* 5    FI_READ  | FI_BINARY            */
57                         "ab",   /* 6    FI_WRITE | FI_BINARY    **1)    */
58                         "a+b",  /* 7    FI_READ  | FI_WRITE | FI_BINARY */
59                 };
60 /*
61  * NOTES:
62  *      1)      there is no fopen() mode that opens for writing
63  *              without creating/truncating at the same time.
64  *
65  *      "w"     will create/trunc files with fopen()
66  *      "a"     will create files with fopen()
67  */
68
69 EXPORT FILE *
70 filereopen(name, mode, fp)
71         const char      *name;
72         const char      *mode;
73         FILE            *fp;
74 {
75         int     ret;
76         int     omode = 0;
77         int     flag = 0;
78
79         if (!_cvmod(mode, &omode, &flag))
80                 return ((FILE *) NULL);
81
82         /*
83          * create/truncate file if necessary
84          */
85         if ((ret = _openfd(name, omode)) < 0)
86                 return ((FILE *) NULL);
87         close(ret);
88
89         fp = freopen(name,
90                 fmtab[flag & (FI_READ | FI_WRITE | FI_BINARY | FI_APPEND)], fp);
91
92         if (fp != (FILE *) NULL) {
93                 set_my_flag(fp, 0); /* must clear it if fp is reused */
94
95                 if (flag & FI_APPEND) {
96                         (void) fseek(fp, (off_t)0, SEEK_END);
97                 }
98                 if (flag & FI_UNBUF) {
99                         setbuf(fp, NULL);
100                         add_my_flag(fp, _IOUNBUF);
101                 }
102         }
103         return (fp);
104 }