WvStreams
|
00001 #include "wvistreamlist.h" 00002 #include "wvlog.h" 00003 #include "pwvstream.h" 00004 #include "wvstreamclone.h" 00005 #include "wvlinkerhack.h" 00006 #include <signal.h> 00007 00008 WV_LINK_TO(WvConStream); 00009 WV_LINK_TO(WvTCPConn); 00010 00011 00012 volatile bool want_to_die = false; 00013 00014 static void signalhandler(int sig) 00015 { 00016 fprintf(stderr, "Caught signal %d. Exiting...\n", sig); 00017 want_to_die = true; 00018 signal(sig, SIG_DFL); 00019 } 00020 00021 00022 static void bounce_to_list(IWvStream *in, WvIStreamList *list) 00023 { 00024 char buf[4096]; 00025 size_t len; 00026 00027 len = in->read(buf, sizeof(buf)); 00028 00029 WvIStreamList::Iter i(*list); 00030 for (i.rewind(); i.next(); ) 00031 { 00032 if (in != i.ptr()) 00033 { 00034 // you might think this assumes IWvStream has a buffer; but in 00035 // fact, we already know that everything in the list is a 00036 // WvStreamClone, and WvStreamClone *does* have an output 00037 // buffer, so this is safe. 00038 i->write(buf, len); 00039 } 00040 } 00041 } 00042 00043 00044 static void died(WvLog &log, WvStringParm name, IWvStream *s) 00045 { 00046 if (s->geterr()) 00047 log("%s: %s\n", name, s->errstr()); 00048 } 00049 00050 00051 static void add(WvLog &log, WvIStreamList &list, const char *_mon) 00052 { 00053 WvString mon(_mon); 00054 if (mon == "-") 00055 mon = "stdio"; 00056 log("Creating stream: '%s'\n", mon); 00057 PWvStream s(mon); 00058 if (!s->isok()) 00059 died(log, _mon, s.addRef()); 00060 else 00061 { 00062 s->setcallback(wv::bind(bounce_to_list, s.get(), &list)); 00063 s->setclosecallback(wv::bind(died, log, _mon, s.addRef())); 00064 } 00065 list.append(s.addRef(), true, _mon); 00066 } 00067 00068 00069 int main(int argc, char **argv) 00070 { 00071 WvIStreamList list; 00072 WvLog log(argv[0], WvLog::Debug); 00073 00074 signal(SIGTERM, signalhandler); 00075 signal(SIGINT, signalhandler); 00076 00077 if (argc <= 1) 00078 { 00079 fprintf(stderr, "Usage: %s <stream1> [stream2 [stream3...]]\n", 00080 argv[0]); 00081 return 1; 00082 } 00083 00084 if (argc == 2) // talking to just one stream means send it to stdio 00085 add(log, list, "-"); 00086 00087 for (int count = 1; count < argc; count++) 00088 add(log, list, argv[count]); 00089 00090 while (!want_to_die && list.count() >= 2) 00091 list.runonce(); 00092 }