Commit | Line | Data |
---|---|---|
0e23f538 TJ |
1 | /* |
2 | The software in this package is distributed under the GNU General | |
3 | Public License version 2 (with a special exception described below). | |
4 | ||
5 | A copy of GNU General Public License (GPL) is included in this distribution, | |
6 | in the file COPYING.GPL. | |
7 | ||
8 | As a special exception, if other files instantiate templates or use macros | |
9 | or inline functions from this file, or you compile this file and link it | |
10 | with other works to produce a work based on this file, this file | |
11 | does not by itself cause the resulting work to be covered | |
12 | by the GNU General Public License. | |
13 | ||
14 | However the source code for this file must still be made available | |
15 | in accordance with section (3) of the GNU General Public License. | |
16 | ||
17 | This exception does not invalidate any other reasons why a work based | |
18 | on this file might be covered by the GNU General Public License. | |
19 | */ | |
e93545dd GE |
20 | #include <stdio.h> |
21 | #include <stdlib.h> | |
22 | #include <unistd.h> | |
23 | #include <sys/stat.h> | |
8d2c81e4 | 24 | #include <errno.h> |
5efd35b1 | 25 | #include <string.h> |
e93545dd GE |
26 | |
27 | #include <oftmpstream.hxx> | |
28 | ||
29 | using namespace std; | |
30 | ||
31 | void fdoutbuf::set_fd(int _fd) { | |
32 | fd = _fd; | |
33 | } | |
34 | ||
35 | int fdoutbuf::overflow (int_type c) { | |
36 | if (fd == -1) | |
37 | return c; | |
38 | ||
39 | if (c != EOF) { | |
40 | char z = c; | |
41 | if (write (fd, &z, 1) != 1) { | |
42 | return EOF; | |
43 | } | |
44 | } | |
45 | return c; | |
46 | } | |
47 | // write multiple characters | |
48 | std::streamsize fdoutbuf::xsputn (const char* s, | |
49 | std::streamsize num) { | |
50 | if (fd == -1) | |
51 | return (num); | |
52 | ||
53 | return write(fd,s,num); | |
54 | } | |
55 | ||
56 | ||
18235d3a RP |
57 | oftmpstream::oftmpstream () |
58 | : ostream(0) | |
59 | , file_mode(0644) | |
60 | { | |
e93545dd GE |
61 | fd = -1; |
62 | rdbuf(&buf); | |
63 | is_open = false; | |
64 | } | |
65 | ||
18235d3a RP |
66 | oftmpstream::oftmpstream (const std::string &name) |
67 | : ostream(0) | |
68 | , file_mode(0644) | |
69 | { | |
e93545dd GE |
70 | fd = -1; |
71 | rdbuf(&buf); | |
72 | is_open = false; | |
73 | ||
74 | open(name); | |
75 | } | |
76 | ||
77 | oftmpstream::~oftmpstream () { | |
78 | close(); | |
79 | } | |
80 | ||
dcdae446 GE |
81 | std::string oftmpstream::get_filename() |
82 | { | |
83 | return realname; | |
84 | } | |
85 | ||
86 | std::string oftmpstream::get_tmp_filename() | |
87 | { | |
88 | return tmpname; | |
89 | } | |
90 | ||
8ac198c4 | 91 | void oftmpstream::open (const string &name) |
e93545dd GE |
92 | { |
93 | if (is_open) | |
94 | close(); | |
95 | ||
96 | realname = name; | |
8ac198c4 | 97 | tmpname=name+".XXXXXX"; |
18235d3a RP |
98 | file_mode= 0644; |
99 | ||
e93545dd GE |
100 | char* chbuf=new char[tmpname.size()+1]; |
101 | tmpname.copy(chbuf,tmpname.size()+1); | |
102 | chbuf[tmpname.size()]=0; | |
103 | fd=mkstemp(chbuf); | |
104 | tmpname=chbuf; | |
105 | delete[] chbuf; | |
106 | ||
107 | if (fd==-1) | |
108 | { | |
109 | string err="error creating temporary file "+tmpname; | |
110 | err+=": "; | |
111 | err+=strerror(errno); | |
112 | throw ios_base::failure(err); | |
113 | } | |
114 | ||
115 | buf.set_fd(fd); | |
116 | is_open = true; | |
117 | } | |
118 | ||
119 | void oftmpstream::close() | |
120 | { | |
121 | if (!is_open) | |
122 | return; | |
123 | ||
18235d3a | 124 | fchmod (fd, file_mode); // fix/change mkstemp permissions |
16d42e06 | 125 | fsync(fd); |
e93545dd GE |
126 | ::close (fd); |
127 | ||
128 | if (rename (tmpname.c_str(), realname.c_str()) != 0) | |
129 | { | |
130 | string err="error renaming temporary file "+tmpname; | |
131 | err+=" to "+realname; | |
132 | err+=": "; | |
133 | err+=strerror(errno); | |
134 | throw ios_base::failure(err); | |
135 | } | |
136 | ||
137 | fd = -1; | |
138 | is_open = false; | |
18235d3a | 139 | file_mode= 0644; |
e93545dd | 140 | } |
18235d3a RP |
141 | |
142 | ||
143 | /** | |
144 | * @brief set file mode for the final file. | |
145 | * @param mode the fin al file mode. | |
146 | * | |
147 | * When called after open(), it determines the file mode which should | |
148 | * be used for the resulting file. | |
149 | */ | |
150 | void oftmpstream::set_file_mode(int mode) | |
151 | { | |
152 | file_mode= mode; | |
153 | } // eo oftmpstream::set_file_mode(int) |