From 618df147e19d12075f351930d6bf85e9b171c99c Mon Sep 17 00:00:00 2001 From: chatty Date: Tue, 27 Jul 1993 14:02:13 +0000 Subject: Initial revision --- comm/OLD/tellagent.cc | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++ comm/TkMultiplexer.cc | 117 ++++++++++++++++++++++++++++++ comm/TkMultiplexer.h | 44 ++++++++++++ comm/XtMultiplexer.cc | 136 +++++++++++++++++++++++++++++++++++ comm/XtMultiplexer.h | 47 ++++++++++++ 5 files changed, 539 insertions(+) create mode 100644 comm/OLD/tellagent.cc create mode 100644 comm/TkMultiplexer.cc create mode 100644 comm/TkMultiplexer.h create mode 100644 comm/XtMultiplexer.cc create mode 100644 comm/XtMultiplexer.h (limited to 'comm') diff --git a/comm/OLD/tellagent.cc b/comm/OLD/tellagent.cc new file mode 100644 index 0000000..6f73537 --- /dev/null +++ b/comm/OLD/tellagent.cc @@ -0,0 +1,195 @@ +/* + * The Unix Channel + * + * by Michel Beaudouin-Lafon + * + * Copyright 1990-1993 + * Laboratoire de Recherche en Informatique (LRI) + * + * Send a request to a server + * + * $Id$ + * $CurLog$ + */ + +/* Usage: + * tellagent agentname request + * tellagent agentname -f file + * tellagent agentname + */ + +#include "TextStream.h" +#include "Multiplexer.h" +#include "error.h" +#include +#include +#include +#include + +class INPUT; +class TELLER; + + +class INPUT : public UchChannel { +protected: + TELLER* tell; + UchMsgBuffer input; +public: + INPUT (TELLER* t, int fd) : UchChannel (fd) { tell = t; } + void HandleRead (); +}; + +class TELLER : public UchTextService { +protected: + pUchChannel in; + pUchChannel out; + + cmd_res Execute (const UchTextLine&); + void AbandonRestart (); +public: + TELLER () : UchTextService () { in = 0; out = 0; } + void SetOutput (int); + void SetInput (int fd); + void Close (); +}; + +//---------------- INPUT +void +INPUT :: HandleRead () +{ + input.NeedSize (128); + int n = Read (input); + if (n < 0) + SysError (ErrFatal, "read input"); + if (n == 0) { + if (input.BufLength ()) { + input.Append ('\n'); + input.Append ('\0'); + tell->Send ((const char*) input.Buffer ()); + input.Flush (); + } + tell->Close (); + return; + } + + input.Append ('\0'); + tell->Send ((const char*) input.Buffer ()); + input.Flush (); +} + +void +TELLER :: SetOutput (int fd) +{ + out = new UchChannel (fd); +} + +void +TELLER :: SetInput (int fd) +{ + in = new INPUT (this, fd); + in->SetMode (IORead); + if (Mpx) + Mpx->Add (*in); +} + +UchTextService::cmd_res +TELLER :: Execute (const UchTextLine& l) +{ + if (! out) + return isCmdOk; + UchMsgBuffer buf; + l.Unparse (&buf); + buf.Append ('\n'); + out->WriteBuffer (buf); + return isCmdOk; +} + +void +TELLER :: AbandonRestart () +{ + if (in) { + Mpx->Remove (*in); + in = 0; + } + out = 0; + UchTextService::AbandonRestart (); +} + +void +TELLER :: Close () +{ + if (in) { + Mpx->Remove (*in); + in = 0; + } + out = 0; + UchTextService::Close (); +} + +//---------------- Usage +void +Usage () +{ + Error (ErrUsage, NULL, "server[@host] [request | -f file]"); +} + +//---------------- main +main (int argc, char** argv) +{ + ProgramName (argv [0]); +// LogfileName ("tellagent.log"); + + if (argc < 2) + Usage (); + + const char* sname = argv [1]; + const char* host = 0; + char* p = index (sname, '@'); + if (p) { + *p++ = '\0'; + host = p; + } + + TELLER* tell = new TELLER; + tell->Init (sname, host); + + UchMultiplexer mpx; + + int fdin = 0; /*stdin*/ + if (argc == 2) { + // tellagent server : start interactive session + } else if (strcmp (argv [2], "-f") == 0) { + // tellagent server -f file: read from file + if (argc != 4) + Usage (); + + const char* fname = argv [3]; + fdin = open (fname, O_RDONLY); + if (fdin < 0) + SysError (ErrFatal, fname); + } else { + // tellagent server request: send request and close + UchTextLine line; + for (int i = 2; i < argc; i++) + line << argv [i]; + tell->SetOutput (1 /*stdout*/); + tell->Send (line); + tell->Close (); + while (tell->GetStatus () != UchTextService::isRunning) { + mpx.LoopScan (); + wait (0); + } + exit (1); + } + + if (fdin >= 0) + tell->SetInput (fdin); + tell->SetOutput (1 /*stdout*/); +#if 0 + if (MpxRun () == isMpxEmpty) + exit (0); +#else + mpx.LoopScan (); +#endif + exit (1); +} diff --git a/comm/TkMultiplexer.cc b/comm/TkMultiplexer.cc new file mode 100644 index 0000000..3272851 --- /dev/null +++ b/comm/TkMultiplexer.cc @@ -0,0 +1,117 @@ +/* + * The Unix Channel + * + * by Michel Beaudouin-Lafon and Stephane Chatty + * + * Copyright 1990-1993 + * Laboratoire de Recherche en Informatique (LRI) + * Centre d'Etudes de la Navigation Aerienne + * + * Tk-based multiplexers + * + * $Id$ + * $CurLog$ + */ + +#include "TkMultiplexer.h" +#include "error.h" + +#include + +static void +ioHandler (ClientData client_data, int mask) +{ + UchChannel* ch = (UchChannel*) client_data; + if (mask & TK_WRITABLE) + ch->HandleWrite (); + if (mask & TK_READABLE) + ch->HandleRead (); +} + +UchTkMultiplexer :: UchTkMultiplexer () +: UchBaseMultiplexer () +{ + memset (Active, 0, NFILE * sizeof (bool)); +} + + +UchTkMultiplexer :: ~UchTkMultiplexer () +{ +} + +void +UchTkMultiplexer :: SetMasks (int fd, IOMODE mode) +{ + UchChannel* ch = Channels [fd]; + if (!ch) + return; + + /* remove if already there */ + if (Active [fd]) { + Tk_DeleteFileHandler (fd); + ReadCount--; + } + + /* add channel */ + int mask = 0; + + if (mode & IORead) + mask |= TK_READABLE; + + if (mode & IOWrite) + mask |= TK_WRITABLE; + + if (mode & IOSelect) + Error (ErrWarn, "AddChannel", "select condition ignored"); + + if (mask) { + Tk_CreateFileHandler (fd, mask, ioHandler, (ClientData) ch); + ReadCount++; + Active [fd] = TRUE; + } +} + +void +UchTkMultiplexer :: FireTimers (ClientData mpx) +{ + CcuCoreTimer::Fire (((UchTkMultiplexer*) mpx)->GetTimerSet ()); +} + +void +UchTkMultiplexer :: SetTimeOut (Millisecond delay) +{ + TimeOut = Tk_CreateTimerHandler (int (delay), &UchTkMultiplexer::FireTimers, (ClientData) this); +} + +void +UchTkMultiplexer :: SuppressTimeOut () +{ + Tk_DeleteTimerHandler (TimeOut); + TimeOut = 0; +} + +void +UchTkMultiplexer :: FireSignals (ClientData mpx) +{ + ((UchTkMultiplexer*) mpx)->HandleDeferredSignals (); +} + +void +UchTkMultiplexer :: AddSignalHook () +{ + Tk_DoWhenIdle (&UchTkMultiplexer::FireSignals, (ClientData) this); +} + +MPX_RES +UchTkMultiplexer :: Loop () +{ + Looping = TRUE; + + Tk_MainLoop (); + + if (Looping) { + Looping = FALSE; + return isMpxEmpty; + } + return isMpxTerminated; +} diff --git a/comm/TkMultiplexer.h b/comm/TkMultiplexer.h new file mode 100644 index 0000000..c1ecded --- /dev/null +++ b/comm/TkMultiplexer.h @@ -0,0 +1,44 @@ +/* + * The Unix Channel + * + * by Michel Beaudouin-Lafon and Stephane Chatty + * + * Copyright 1990-1993 + * Laboratoire de Recherche en Informatique (LRI) + * Centre d'Etudes de la Navigation Aerienne + * + * Tk-based multiplexers + * + * $Id$ + * $CurLog$ + */ + +#ifndef TkMultiplexer_H_ +#define TkMultiplexer_H_ + +#include "Multiplexer.h" +extern "C" { +#include "tk.h" +} + +class UchTkMultiplexer : public UchBaseMultiplexer { +private: +static void FireSignals (ClientData); +static void FireTimers (ClientData); + +protected: + bool Active [NFILE]; + Tk_TimerToken TimeOut; + + void SetMasks (int, IOMODE); + void SetTimeOut (Millisecond); + void SuppressTimeOut (); + void AddSignalHook (); + MPX_RES Loop (); + +public: + UchTkMultiplexer (); + ~UchTkMultiplexer (); +}; + +#endif /* TkMultiplexer_H_ */ diff --git a/comm/XtMultiplexer.cc b/comm/XtMultiplexer.cc new file mode 100644 index 0000000..edd2409 --- /dev/null +++ b/comm/XtMultiplexer.cc @@ -0,0 +1,136 @@ +/* + * The Unix Channel + * + * by Michel Beaudouin-Lafon and Stephane Chatty + * + * Copyright 1990-1993 + * Laboratoire de Recherche en Informatique (LRI) + * Centre d'Etudes de la Navigation Aerienne + * + * Xt-based multiplexers + * + * $Id$ + * $CurLog$ + */ + +#include "XtMultiplexer.h" +#include "error.h" + +UchXtMultiplexer :: UchXtMultiplexer () +: UchBaseMultiplexer () +{ + memset (ReadId, 0, NFILE * sizeof (XtInputId)); + memset (WriteId, 0, NFILE * sizeof (XtInputId)); +} + + +UchXtMultiplexer :: ~UchXtMultiplexer () +{ +} + +/* the input and output callback for channels */ +static void +inputCB (XtPointer client_data, int*, XtInputId*) +{ + UchChannel* chan = (UchChannel*) client_data; + chan->HandleRead (); +} + +static void +outputCB (XtPointer client_data, int*, XtInputId*) +{ + UchChannel* chan = (UchChannel*) client_data; + chan->HandleWrite (); +} + +void +UchXtMultiplexer :: SetMasks (int fd, IOMODE mode) +{ + UchChannel* ch = Channels [fd]; + if (!ch) + return; + + /* remove if already there */ + if (ReadId [fd]) { + XtRemoveInput (ReadId [fd]); + ReadId [fd] = (XtInputId) 0; + ReadCount--; + } + if (WriteId [fd]) { + XtRemoveInput (WriteId [fd]); + WriteId [fd] = (XtInputId) 0; + WriteCount--; + } + + /* add channel */ + if (mode & IORead) { + ReadId [fd] = XtAddInput (fd, (XtPointer) XtInputReadMask, inputCB, (caddr_t) ch); + ReadCount++; + } + + if (mode & IOWrite) { + WriteId [fd] = XtAddInput (fd, (XtPointer) XtInputWriteMask, outputCB, (caddr_t) ch); + WriteCount++; + } + + if (mode & IOSelect) + Error (ErrWarn, "AddChannel", "select condition ignored"); +} + +void +UchXtMultiplexer :: FireTimers (void* mpx, XtIntervalId*) +{ + CcuCoreTimer::Fire (((UchXtMultiplexer*) mpx)->GetTimerSet ()); +} + +void +UchXtMultiplexer :: SetTimeOut (Millisecond delay) +{ + /* should replace with XtAppAddTimeOut */ + TimeOut = XtAddTimeOut (delay, &UchXtMultiplexer::FireTimers, this); +} + +void +UchXtMultiplexer :: SuppressTimeOut () +{ + XtRemoveTimeOut (TimeOut); + TimeOut = 0; +} + +void +UchXtMultiplexer :: FireSignals (void* mpx) +{ + ((UchXtMultiplexer*) mpx)->HandleDeferredSignals (); +} + + +void +UchXtMultiplexer :: AddSignalHook () +{ + /* should replace with XtAppAddWorkProc */ + XtAddWorkProc ((XtWorkProc) (&UchXtMultiplexer::FireSignals), this); +} + + +MPX_RES +UchXtMultiplexer :: Loop () +{ + XEvent event; + bool waiting = TRUE; + + while (Looping && (waiting || ReadCount || WriteCount)) { + // *** problem with other loop: work proc are not called! + // *** we must find a way to exit properly with this one... + // *** sending ourselves an event??? + XtNextEvent (&event); + XtDispatchEvent (&event); + if (ReadCount || WriteCount) + waiting = FALSE; + } + if (Looping) { + Looping = FALSE; + return isMpxEmpty; + } + return isMpxTerminated; +} + diff --git a/comm/XtMultiplexer.h b/comm/XtMultiplexer.h new file mode 100644 index 0000000..164a296 --- /dev/null +++ b/comm/XtMultiplexer.h @@ -0,0 +1,47 @@ +/* + * The Unix Channel + * + * by Michel Beaudouin-Lafon and Stephane Chatty + * + * Copyright 1990-1993 + * Laboratoire de Recherche en Informatique (LRI) + * Centre d'Etudes de la Navigation Aerienne + * + * Xt-based multiplexers + * + * $Id$ + * $CurLog$ + */ + +#ifndef XtMultiplexer_H_ +#define XtMultiplexer_H_ + +#include "Multiplexer.h" + +/*** Intrinsic.h redefines TRUE and FALSE if FALSE is undefined... */ +#define FALSE 0 +#include +#undef FALSE + +class UchXtMultiplexer : public UchBaseMultiplexer { +private: +static void FireSignals (void*); +static void FireTimers (void*, XtIntervalId*); + +protected: + XtInputId ReadId [NFILE]; + XtInputId WriteId [NFILE]; + XtIntervalId TimeOut; + + void SetMasks (int, IOMODE); + void SetTimeOut (Millisecond); + void SuppressTimeOut (); + void AddSignalHook (); + MPX_RES Loop (); + +public: + UchXtMultiplexer (); + ~UchXtMultiplexer (); +}; + +#endif /* XtMultiplexer_H_ */ -- cgit v1.1