1 /* @(#)filereopen.c	1.18 10/11/06 Copyright 1986, 1995-2010 J. Schilling */
2 /*
3  *	open new file on old stream
4  *
5  *	Copyright (c) 1986, 1995-2010 J. Schilling
6  */
7 /*
8  * The contents of this file are subject to the terms of the
9  * Common Development and Distribution License, Version 1.0 only
10  * (the "License").  You may not use this file except in compliance
11  * with the License.
12  *
13  * See the file CDDL.Schily.txt in this distribution for details.
14  * A copy of the CDDL is also available via the Internet at
15  * http://www.opensource.org/licenses/cddl1.txt
16  *
17  * When distributing Covered Code, include this CDDL HEADER in each
18  * file and include the License file CDDL.Schily.txt from this distribution.
19  */
20 
21 #include "schilyio.h"
22 
23 /*
24  * Note that because of a definition in schilyio.h we are using
25  * fseeko()/ftello() instead of fseek()/ftell() if available.
26  */
27 
28 LOCAL	char	*fmtab[] = {
29 			"",	/* 0	FI_NONE				*/
30 			"r",	/* 1	FI_READ				*/
31 			"r+",	/* 2	FI_WRITE		**1)	*/
32 			"r+",	/* 3	FI_READ  | FI_WRITE		*/
33 			"b",	/* 4	FI_NONE  | FI_BINARY		*/
34 			"rb",	/* 5	FI_READ  | FI_BINARY		*/
35 			"r+b",	/* 6	FI_WRITE | FI_BINARY	**1)	*/
36 			"r+b",	/* 7	FI_READ  | FI_WRITE | FI_BINARY	*/
37 
38 /* + FI_APPEND	*/	"",	/* 0	FI_NONE				*/
39 /* ...		*/	"r",	/* 1	FI_READ				*/
40 			"a",	/* 2	FI_WRITE		**1)	*/
41 			"a+",	/* 3	FI_READ  | FI_WRITE		*/
42 			"b",	/* 4	FI_NONE  | FI_BINARY		*/
43 			"rb",	/* 5	FI_READ  | FI_BINARY		*/
44 			"ab",	/* 6	FI_WRITE | FI_BINARY	**1)	*/
45 			"a+b",	/* 7	FI_READ  | FI_WRITE | FI_BINARY	*/
46 		};
47 /*
48  * NOTES:
49  *	1)	there is no fopen() mode that opens for writing
50  *		without creating/truncating at the same time.
51  *
52  *	"w"	will create/trunc files with fopen()
53  *	"a"	will create files with fopen()
54  */
55 
56 EXPORT FILE *
filereopen(name,mode,fp)57 filereopen(name, mode, fp)
58 	const char	*name;
59 	const char 	*mode;
60 	FILE		*fp;
61 {
62 	int	ret = -1;
63 	int	omode = 0;
64 	int	flag = 0;
65 
66 	if (!_cvmod(mode, &omode, &flag))
67 		return ((FILE *)NULL);
68 
69 	/*
70 	 * create/truncate file if necessary
71 	 */
72 	if ((flag & (FI_CREATE | FI_TRUNC)) != 0) {
73 		if ((ret = _openfd(name, omode)) < 0)
74 			return ((FILE *)NULL);
75 		close(ret);
76 	}
77 
78 	fp = freopen(name,
79 		fmtab[flag & (FI_READ | FI_WRITE | FI_BINARY | FI_APPEND)], fp);
80 
81 	if (fp != (FILE *)NULL) {
82 		set_my_flag(fp, 0); /* must clear it if fp is reused */
83 
84 		if (flag & FI_APPEND) {
85 			(void) fseek(fp, (off_t)0, SEEK_END);
86 		}
87 		if (flag & FI_UNBUF) {
88 			setbuf(fp, NULL);
89 			add_my_flag(fp, _JS_IOUNBUF);
90 		}
91 	}
92 	return (fp);
93 }
94