18 #ifndef SHEVEK_SERVER_HH
19 #define SHEVEK_SERVER_HH
28 sighandler_t ignore_broken_pipes = ::signal (SIGPIPE, SIG_IGN);
95 template <
typename client,
typename serverdata>
99 {
return sigc::mem_fun (who, &client::read); }
102 typedef typename std::list <Glib::RefPtr <client> >::iterator iterator;
104 typedef typename std::list <Glib::RefPtr <client> >::const_iterator
113 Glib::RefPtr <shevek::fd>
in;
115 Glib::RefPtr <shevek::fd>
out;
119 in->read_lines (server <client, serverdata>
120 ::get_connection_cb_from_friend
121 (dynamic_cast <client *> (
this) ) );
129 Glib::RefPtr <server <client, serverdata> >
get_server () {
return m_server; }
133 friend class server <client, serverdata>;
134 Glib::RefPtr <server <client, serverdata> > m_server;
138 std::list <Glib::RefPtr <client> > m_connections;
139 Glib::RefPtr <socket> m_listener;
142 void l_read (std::string
const &line, Glib::RefPtr <client> conn);
143 void l_connect (Glib::RefPtr <fd> in, Glib::RefPtr <fd> out,
146 void l_delayed_disconnect (
typename std::list <Glib::RefPtr <client> >::iterator conn);
147 void l_error (
typename std::list <Glib::RefPtr <client> >::iterator conn);
150 static Glib::RefPtr <server> create ();
154 void open (std::string
const &port,
bool use_stdio =
true);
156 serverdata &data () {
return m_data; }
158 serverdata
const &data ()
const {
return m_data;}
160 iterator begin () {
return m_connections.begin (); }
162 iterator end () {
return m_connections.end (); }
164 const_iterator begin ()
const {
return m_connections.begin (); }
166 const_iterator end ()
const {
return m_connections.end (); }
170 ~server () { shutdown (); }
173 template <
typename client,
typename serverdata>
174 void server <client, serverdata>::shutdown ()
178 m_listener->disconnect ();
179 m_listener = Glib::RefPtr <socket> ();
181 while (!m_connections.empty () )
182 m_connections.front ()->disconnect ();
185 template <
typename client,
typename serverdata>
186 void server <client, serverdata>::l_read (std::string
const &line,
187 Glib::RefPtr <client> conn)
192 template <
typename client,
typename serverdata>
193 void server <client, serverdata>::l_delayed_disconnect (
typename std::list <Glib::RefPtr <client> >::iterator conn)
195 Glib::RefPtr <telnet> s = Glib::RefPtr <telnet>::cast_dynamic ( (*conn)->in);
198 m_connections.erase (conn);
201 template <
typename client,
typename serverdata>
202 void server <client, serverdata>::l_error (
typename std::list <Glib::RefPtr <client> >::iterator conn)
204 Glib::RefPtr <telnet> s = Glib::RefPtr <telnet>::cast_dynamic ( (*conn)->in);
207 s->signal_disconnect ().connect (sigc::bind (sigc::mem_fun (*
this, &server <client, serverdata>::l_delayed_disconnect), conn) );
212 (*conn)->in->unread ();
213 m_connections.erase (conn);
217 template <
typename client,
typename serverdata>
218 void server <client, serverdata>::l_connect (Glib::RefPtr <fd> in,
219 Glib::RefPtr <fd> out,
222 m_connections.push_back (client::create () );
223 m_connections.back ()->in = in;
224 m_connections.back ()->out = out;
225 m_connections.back ()->m_server = refptr_this <server <client, serverdata> > ();
226 m_connections.back ()->m_self = --m_connections.end ();
227 in->set_error (sigc::bind (sigc::mem_fun (*
this, &server <client, serverdata>::l_error),
228 --m_connections.end () ) );
229 in->set_eof (sigc::bind (sigc::mem_fun (*
this, &server <client, serverdata>::l_error),
230 --m_connections.end () ) );
231 m_connections.back ()->continue_reading ();
232 out->set_error (sigc::bind (sigc::mem_fun (*
this, &server <client, serverdata>::l_error),
233 --m_connections.end () ) );
234 m_connections.back ()->pickup (is_stdio);
237 template <
typename client,
typename serverdata>
238 void server <client, serverdata>::l_pickup ()
241 m_listener->accept (newfd);
242 l_connect (newfd, newfd,
false);
245 template <
typename client,
typename serverdata>
246 server <client, serverdata>::server ()
250 template <
typename client,
typename serverdata>
251 Glib::RefPtr <server <client, serverdata> > server <client, serverdata>::create ()
253 return Glib::RefPtr <server <client, serverdata> > (
new server <client, serverdata> () );
256 template <
typename client,
typename serverdata>
257 void server <client, serverdata>::open (std::string
const &port,
261 m_listener->disconnect ();
265 m_listener->listen (port, sigc::mem_fun (*
this, &server <client, serverdata>::l_pickup) );