WvStreams
wvstreams.cc
1 #include "wvistreamlist.h"
2 #include "wvlog.h"
3 #include "pwvstream.h"
4 #include "wvstreamclone.h"
5 #include "wvlinkerhack.h"
6 #include <signal.h>
7 
8 WV_LINK_TO(WvConStream);
9 WV_LINK_TO(WvTCPConn);
10 
11 
12 volatile bool want_to_die = false;
13 
14 static void signalhandler(int sig)
15 {
16  fprintf(stderr, "Caught signal %d. Exiting...\n", sig);
17  want_to_die = true;
18  signal(sig, SIG_DFL);
19 }
20 
21 
22 static void bounce_to_list(IWvStream *in, WvIStreamList *list)
23 {
24  char buf[4096];
25  size_t len;
26 
27  len = in->read(buf, sizeof(buf));
28 
29  WvIStreamList::Iter i(*list);
30  for (i.rewind(); i.next(); )
31  {
32  if (in != i.ptr())
33  {
34  // you might think this assumes IWvStream has a buffer; but in
35  // fact, we already know that everything in the list is a
36  // WvStreamClone, and WvStreamClone *does* have an output
37  // buffer, so this is safe.
38  i->write(buf, len);
39  }
40  }
41 }
42 
43 
44 static void died(WvLog &log, WvStringParm name, IWvStream *s)
45 {
46  if (s->geterr())
47  log("%s: %s\n", name, s->errstr());
48 }
49 
50 
51 static void add(WvLog &log, WvIStreamList &list, const char *_mon)
52 {
53  WvString mon(_mon);
54  if (mon == "-")
55  mon = "stdio";
56  log("Creating stream: '%s'\n", mon);
57  PWvStream s(mon);
58  if (!s->isok())
59  died(log, _mon, s.addRef());
60  else
61  {
62  s->setcallback(wv::bind(bounce_to_list, s.get(), &list));
63  s->setclosecallback(wv::bind(died, log, _mon, s.addRef()));
64  }
65  list.append(s.addRef(), true, _mon);
66 }
67 
68 
69 int main(int argc, char **argv)
70 {
71  WvIStreamList list;
72  WvLog log(argv[0], WvLog::Debug);
73 
74  signal(SIGTERM, signalhandler);
75  signal(SIGINT, signalhandler);
76 
77  if (argc <= 1)
78  {
79  fprintf(stderr, "Usage: %s <stream1> [stream2 [stream3...]]\n",
80  argv[0]);
81  return 1;
82  }
83 
84  if (argc == 2) // talking to just one stream means send it to stdio
85  add(log, list, "-");
86 
87  for (int count = 1; count < argc; count++)
88  add(log, list, argv[count]);
89 
90  while (!want_to_die && list.count() >= 2)
91  list.runonce();
92 }
WvStream::runonce
void runonce(time_t msec_timeout=-1)
Exactly the same as: if (select(timeout)) callback();.
Definition: wvstream.h:391
WvErrorBase::geterr
virtual int geterr() const
If isok() is false, return the system error number corresponding to the error, -1 for a special error...
Definition: wverror.h:48
IWvStream
Definition: iwvstream.h:24
WvTCPConn
WvTCPConn tries to make all outgoing connections asynchronously (in the background).
Definition: wvtcp.h:39
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvLog
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
Definition: wvlog.h:56
PWvStream
PWvStream is a smart pointer to an IWvStream object.
Definition: pwvstream.h:36
IWvStream::isok
virtual bool isok() const =0
By default, returns true if geterr() == 0.
IWvStream::setclosecallback
virtual IWvStreamCallback setclosecallback(IWvStreamCallback _callfunc)=0
Sets a callback to be invoked on close().
WvIStreamList
WvStreamList holds a list of WvStream objects – and its select() and callback() functions know how to...
Definition: wvistreamlist.h:20
IObject::addRef
virtual unsigned int addRef()=0
Indicate you are using this object.