2 /* $Id: pipe.cpp,v 1.2 2005-11-07 21:57:10 adam Exp $
3 Copyright (c) 2005, Index Data.
17 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <netinet/tcp.h>
26 #include <sys/socket.h>
29 #include <sys/select.h>
32 #include <boost/thread/thread.hpp>
33 #include <boost/thread/mutex.hpp>
34 #include <boost/thread/condition.hpp>
40 #include <yaz++/socket-observer.h>
46 class Pipe::Rep : public boost::noncopyable {
59 m_fd[0] = m_fd[1] = -1;
63 bool Pipe::Rep::nonblock(int s)
66 if (ioctlsocket(s, FIONBIO, &tru) < 0)
69 if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
72 signal (SIGPIPE, SIG_IGN);
78 Pipe::Pipe(int port_to_use) : m_p(new Rep)
82 // create server socket
83 m_p->m_socket = socket(AF_INET, SOCK_STREAM, 0);
84 if (m_p->m_socket < 0)
85 throw Pipe::Error("could not create socket");
87 unsigned long one = 1;
88 if (setsockopt(m_p->m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)
89 &one, sizeof(one)) < 0)
90 throw Pipe::Error("setsockopt error");
93 struct sockaddr_in add;
94 add.sin_family = AF_INET;
95 add.sin_port = htons(port_to_use);
96 add.sin_addr.s_addr = INADDR_ANY;
97 struct sockaddr *addr = ( struct sockaddr *) &add;
99 if (bind(m_p->m_socket, addr, sizeof(struct sockaddr_in)))
100 throw Pipe::Error("could not bind on socket");
102 if (listen(m_p->m_socket, 3) < 0)
103 throw Pipe::Error("could not listen on socket");
107 tmpadd = (unsigned) inet_addr("127.0.0.1");
109 memcpy(&add.sin_addr.s_addr, &tmpadd, sizeof(struct in_addr));
111 throw Pipe::Error("inet_addr failed");
113 m_p->m_fd[1] = socket(AF_INET, SOCK_STREAM, 0);
114 if (m_p->m_fd[1] < 0)
115 throw Pipe::Error("could not create socket");
117 m_p->nonblock(m_p->m_fd[1]);
119 if (connect(m_p->m_fd[1], addr, sizeof(*addr)) < 0 &&
120 errno != EINPROGRESS)
122 fprintf(stderr, "errno=%d[%s] tmpadd=%x\n",
123 errno, strerror(errno), tmpadd);
124 throw Pipe::Error("could not connect to socket");
128 struct sockaddr caddr;
129 socklen_t caddr_len = sizeof(caddr);
130 m_p->m_fd[0] = accept(m_p->m_socket, &caddr, &caddr_len);
131 if (m_p->m_fd[0] < 0)
132 throw Pipe::Error("could not accept on socket");
137 FD_SET(m_p->m_fd[1], &write_set);
138 int r = select(m_p->m_fd[1]+1, 0, &write_set, 0, 0);
140 throw Pipe::Error("could not complete connect");
142 close(m_p->m_socket);
153 if (m_p->m_fd[0] != -1)
155 if (m_p->m_fd[1] != -1)
157 if (m_p->m_socket != -1)
158 close(m_p->m_socket);
161 int &Pipe::read_fd() const
166 int &Pipe::write_fd() const
174 * indent-tabs-mode: nil
175 * c-file-style: "stroustrup"
177 * vim: shiftwidth=4 tabstop=8 expandtab