1 // Copyright (C) 2018 Bruce Guenter <bruce@untroubled.org>
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
17 #include "fdbuf.h"
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <string.h>
21 #include <unistd.h>
22
23 ///////////////////////////////////////////////////////////////////////////////
24 // Class fdbuf
25 ///////////////////////////////////////////////////////////////////////////////
fdbuf(int fdesc,bool dc,unsigned bufsz)26 fdbuf::fdbuf(int fdesc, bool dc, unsigned bufsz)
27 : buf(new char[bufsz]),
28 buflength(0),
29 bufstart(0),
30 offset(0),
31 errnum(0),
32 flags(0),
33 bufsize(bufsz),
34 fd(fdesc),
35 do_close(dc)
36 {
37 if(!buf) {
38 flags = flag_error;
39 errnum = errno;
40 }
41 if(fdesc < 0)
42 flags |= flag_closed;
43 #ifdef _REENTRANT
44 pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER;
45 mutex = tmp;
46 pthread_mutex_init(&mutex, 0);
47 #else
48 #ifdef FDBUF_MUTEX_DEBUG
49 mutex_count = 0;
50 #endif
51 #endif
52 }
53
~fdbuf()54 fdbuf::~fdbuf()
55 {
56 close();
57 #ifdef _REENTRANT
58 pthread_mutex_destroy(&mutex);
59 #endif
60 delete buf;
61 }
62
error() const63 bool fdbuf::error() const
64 {
65 return flags & flag_error;
66 }
67
closed() const68 bool fdbuf::closed() const
69 {
70 return flags & flag_closed;
71 }
72
close()73 bool fdbuf::close()
74 {
75 if(do_close && fd >= 0 && !(flags & flag_closed)) {
76 if(::close(fd) == -1) {
77 errnum = errno;
78 flags |= flag_error;
79 return false;
80 }
81 flags |= flag_closed;
82 }
83 return true;
84 }
85
86 #if defined(FDBUF_MUTEX_DEBUG) && !defined(_REENTRANT)
87 {
88 int* null = 0;
89 (*null)++;
90 kill(getpid(), 9);
91 }
92
93 // Debugging code
lock()94 void fdbuf::lock()
95 {
96 if(mutex)
97 abort();
98 ++mutex;
99 }
100
unlock()101 void fdbuf::unlock()
102 {
103 if(mutex != 1)
104 abort();
105 --mutex;
106 }
107 #endif
108