arnied, arnielizer, arniesetup, generate, info_mqueue_ui, libncfcheck: (tomj) compile...
[libi2ncommon] / src / insocketstream.hxx
1 /***************************************************************************
2               insocketstream.hxx  -  C++ streambuffer wrapper 
3                              -------------------
4     begin                : Sun Nov 10 2002
5     copyright            : (C) 2002 by Intra2net AG
6     email                : intranator@intra2net.com
7  ***************************************************************************/
8
9 #ifndef _INSOCKETSTREAM
10 #define _INSOCKETSTREAM
11
12 #include <string>
13 #include <sstream>
14 #include <streambuf>
15 #include <stdio.h>
16 #include <errno.h>
17
18 #include <sys/socket.h>
19 #include <sys/un.h>
20 #include <unistd.h>
21
22 #include "exception.hxx"
23
24 // ATTENTION: A lot of mysterious STL bugs occured
25 //            with a "real" buffer (buffer larger than 1 byte and up to 100 bytes)
26 //            -> Keep it slow and working!
27
28 class insocketstream : public std::streambuf
29 {
30    protected:
31       char buffer;
32       int sock;
33
34    public:
35       insocketstream(std::string unixsocket)
36       {
37          sock=socket(AF_UNIX,SOCK_STREAM,0);
38          if (sock == -1)
39          {
40             std::ostringstream os;
41             os << "can't open socket: " << strerror(errno);
42             throw EXCEPTION (insocketstream_error, os.str());
43          }
44          
45          struct sockaddr_un server_adr;
46          server_adr.sun_family=AF_UNIX;
47          strncpy(server_adr.sun_path,unixsocket.c_str(),sizeof(server_adr.sun_path));
48          server_adr.sun_path[sizeof(server_adr.sun_path)]=0;
49          
50          if(connect(sock,(struct sockaddr *) &server_adr, sizeof(server_adr)))
51          {
52             std::ostringstream os;
53             os << "can't connect to socket: " << strerror(errno);
54             throw EXCEPTION (insocketstream_error, os.str());
55          }         
56          
57          setg (&buffer, &buffer, &buffer);      // force underflow
58       }
59
60       ~insocketstream()
61       {
62          if (sock != -1)
63          {
64             shutdown(sock,SHUT_RDWR);
65             close(sock);
66          }
67         
68          sock = -1;
69       }
70    
71    protected:
72       virtual int_type underflow()
73       {
74          if (gptr() < egptr())
75             return std::streambuf::traits_type::to_int_type(*gptr());
76          
77          int nbytes=::read(sock,&buffer,1);
78          
79          if (nbytes==-1)
80          {
81             if (errno == EINTR)
82                return std::streambuf::traits_type::to_int_type(*gptr());
83             else
84             {
85                std::ostringstream os;
86                os << "error reading form socket: " << strerror(errno);
87                throw EXCEPTION (insocketstream_error, os.str());
88             }         
89          }
90          if (nbytes==0)
91             return EOF;
92                   
93          setg (&buffer, &buffer, &buffer+sizeof(char));
94          return std::streambuf::traits_type::to_int_type(*gptr());
95       }
96 }; 
97
98 #endif