libi2ncommon: (gerd) add get_filename functions to oftempstream
[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
37oftmpstream::oftmpstream () : ostream(0) {
38 fd = -1;
39 rdbuf(&buf);
40 is_open = false;
41}
42
8ac198c4 43oftmpstream::oftmpstream (const std::string &name) : ostream(0) {
e93545dd
GE
44 fd = -1;
45 rdbuf(&buf);
46 is_open = false;
47
48 open(name);
49}
50
51oftmpstream::~oftmpstream () {
52 close();
53}
54
dcdae446
GE
55std::string oftmpstream::get_filename()
56{
57 return realname;
58}
59
60std::string oftmpstream::get_tmp_filename()
61{
62 return tmpname;
63}
64
8ac198c4 65void oftmpstream::open (const string &name)
e93545dd
GE
66{
67 if (is_open)
68 close();
69
70 realname = name;
8ac198c4 71 tmpname=name+".XXXXXX";
e93545dd
GE
72
73 char* chbuf=new char[tmpname.size()+1];
74 tmpname.copy(chbuf,tmpname.size()+1);
75 chbuf[tmpname.size()]=0;
76 fd=mkstemp(chbuf);
77 tmpname=chbuf;
78 delete[] chbuf;
79
80 if (fd==-1)
81 {
82 string err="error creating temporary file "+tmpname;
83 err+=": ";
84 err+=strerror(errno);
85 throw ios_base::failure(err);
86 }
87
88 buf.set_fd(fd);
89 is_open = true;
90}
91
92void oftmpstream::close()
93{
94 if (!is_open)
95 return;
96
97 fsync(fd);
98 fchmod (fd, 0644); // fix mkstemp permissions
99 ::close (fd);
100
101 if (rename (tmpname.c_str(), realname.c_str()) != 0)
102 {
103 string err="error renaming temporary file "+tmpname;
104 err+=" to "+realname;
105 err+=": ";
106 err+=strerror(errno);
107 throw ios_base::failure(err);
108 }
109
110 fd = -1;
111 is_open = false;
112}