libi2ncommon: (reinhard) added pointer_func and signalfunc modules.
[libi2ncommon] / src / oftmpstream.cpp
CommitLineData
e93545dd
GE
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <sys/stat.h>
8d2c81e4 5#include <errno.h>
e93545dd
GE
6
7#include <oftmpstream.hxx>
8
9using namespace std;
10
11void fdoutbuf::set_fd(int _fd) {
12 fd = _fd;
13}
14
15int fdoutbuf::overflow (int_type c) {
16 if (fd == -1)
17 return c;
18
19 if (c != EOF) {
20 char z = c;
21 if (write (fd, &z, 1) != 1) {
22 return EOF;
23 }
24 }
25 return c;
26}
27// write multiple characters
28std::streamsize fdoutbuf::xsputn (const char* s,
29 std::streamsize num) {
30 if (fd == -1)
31 return (num);
32
33 return write(fd,s,num);
34}
35
36
18235d3a
RP
37oftmpstream::oftmpstream ()
38: ostream(0)
39, file_mode(0644)
40{
e93545dd
GE
41 fd = -1;
42 rdbuf(&buf);
43 is_open = false;
44}
45
18235d3a
RP
46oftmpstream::oftmpstream (const std::string &name)
47: ostream(0)
48, file_mode(0644)
49{
e93545dd
GE
50 fd = -1;
51 rdbuf(&buf);
52 is_open = false;
53
54 open(name);
55}
56
57oftmpstream::~oftmpstream () {
58 close();
59}
60
dcdae446
GE
61std::string oftmpstream::get_filename()
62{
63 return realname;
64}
65
66std::string oftmpstream::get_tmp_filename()
67{
68 return tmpname;
69}
70
8ac198c4 71void oftmpstream::open (const string &name)
e93545dd
GE
72{
73 if (is_open)
74 close();
75
76 realname = name;
8ac198c4 77 tmpname=name+".XXXXXX";
18235d3a
RP
78 file_mode= 0644;
79
e93545dd
GE
80 char* chbuf=new char[tmpname.size()+1];
81 tmpname.copy(chbuf,tmpname.size()+1);
82 chbuf[tmpname.size()]=0;
83 fd=mkstemp(chbuf);
84 tmpname=chbuf;
85 delete[] chbuf;
86
87 if (fd==-1)
88 {
89 string err="error creating temporary file "+tmpname;
90 err+=": ";
91 err+=strerror(errno);
92 throw ios_base::failure(err);
93 }
94
95 buf.set_fd(fd);
96 is_open = true;
97}
98
99void oftmpstream::close()
100{
101 if (!is_open)
102 return;
103
104 fsync(fd);
18235d3a 105 fchmod (fd, file_mode); // fix/change mkstemp permissions
e93545dd
GE
106 ::close (fd);
107
108 if (rename (tmpname.c_str(), realname.c_str()) != 0)
109 {
110 string err="error renaming temporary file "+tmpname;
111 err+=" to "+realname;
112 err+=": ";
113 err+=strerror(errno);
114 throw ios_base::failure(err);
115 }
116
117 fd = -1;
118 is_open = false;
18235d3a 119 file_mode= 0644;
e93545dd 120}
18235d3a
RP
121
122
123/**
124 * @brief set file mode for the final file.
125 * @param mode the fin al file mode.
126 *
127 * When called after open(), it determines the file mode which should
128 * be used for the resulting file.
129 */
130void oftmpstream::set_file_mode(int mode)
131{
132 file_mode= mode;
133} // eo oftmpstream::set_file_mode(int)