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 *
filereopen(name,mode,fp)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 }
105