First work on Pipe class
[metaproxy-moved-to-github.git] / src / pipe.cpp
1
2 /* $Id: pipe.cpp,v 1.1 2005-11-07 12:32:01 adam Exp $
3    Copyright (c) 2005, Index Data.
4
5 %LICENSE%
6  */
7 #include "config.hpp"
8
9 #if HAVE_UNISTD_H
10 #include <unistd.h>
11 #endif
12
13 #ifdef WIN32
14 #include <winsock.h>
15 #else
16 #include <netinet/in.h>
17 #include <netdb.h>
18 #include <arpa/inet.h>
19 #include <netinet/tcp.h>
20 #endif
21
22 #if HAVE_SYS_SOCKET_H
23 #include <sys/socket.h>
24 #endif
25 #if HAVE_SYS_SELECT_H
26 #include <sys/select.h>
27 #endif
28
29 #include <boost/thread/thread.hpp>
30 #include <boost/thread/mutex.hpp>
31 #include <boost/thread/condition.hpp>
32
33 #include <stdio.h>
34
35 #include <deque>
36
37 #include <yaz++/socket-observer.h>
38 #include <yaz/log.h>
39
40 #include "pipe.hpp"
41
42 namespace yp2 {
43     class Pipe::Rep : public boost::noncopyable {
44         friend class Pipe;
45         Rep();
46         int m_fd[2];
47         int m_socket;
48     };
49 }
50
51 using namespace yp2;
52
53 Pipe::Rep::Rep()
54 {
55     m_fd[0] = m_fd[1] = -1;
56     m_socket = -1;
57 }
58
59 Pipe::Pipe(int port_to_use) : m_p(new Rep)
60 {
61     if (port_to_use)
62     {
63         m_p->m_socket = socket(AF_INET, SOCK_STREAM, 0);
64         if (m_p->m_socket < 0)
65             throw Pipe::Error("could not create socket");
66
67         m_p->m_fd[1] = socket(AF_INET, SOCK_STREAM, 0);
68         if (m_p->m_fd[1] < 0)
69             throw Pipe::Error("could not create socket");
70         
71         struct sockaddr_in add;
72         add.sin_family = AF_INET;
73         add.sin_port = htons(port_to_use);
74         add.sin_addr.s_addr = INADDR_ANY;
75         struct sockaddr *addr = ( struct sockaddr *) &add;
76         
77         if (bind(m_p->m_socket, addr, sizeof(struct sockaddr_in)))
78             throw Pipe::Error("could not bind on socket");
79         
80         if (listen(m_p->m_socket, 3) < 0)
81             throw Pipe::Error("could not listen on socket");
82
83         struct sockaddr caddr;
84         socklen_t caddr_len = sizeof(caddr);
85         m_p->m_fd[0] = accept(m_p->m_socket, &caddr, &caddr_len);
86         if (m_p->m_fd[0] < 0)
87             throw Pipe::Error("could not accept on socket");
88         
89         if (connect(m_p->m_fd[1], addr, sizeof(addr)) < 0)
90             throw Pipe::Error("could not connect to socket");
91     }
92     else
93     {
94         m_p->m_socket = 0;
95         pipe(m_p->m_fd);
96     }
97 }
98
99 Pipe::~Pipe()
100 {
101     if (m_p->m_fd[0] != -1)
102         close(m_p->m_fd[0]);
103     if (m_p->m_fd[1] != -1)
104         close(m_p->m_fd[1]);
105     if (m_p->m_socket != -1)
106         close(m_p->m_socket);
107 }
108
109 int &Pipe::read_fd() const
110 {
111     return m_p->m_fd[0];
112 }
113
114 int &Pipe::write_fd() const
115 {
116     return m_p->m_fd[1];
117 }
118
119 /*
120  * Local variables:
121  * c-basic-offset: 4
122  * indent-tabs-mode: nil
123  * c-file-style: "stroustrup"
124  * End:
125  * vim: shiftwidth=4 tabstop=8 expandtab
126  */
127