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