Cygwin-multitee

From YobiWiki
Revision as of 22:36, 25 November 2008 by <bdi>PhilippeTeuwen</bdi> (talk | contribs) (→‎The patch)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

multitee sends multiple inputs to multiple outputs.
Check this page.
Original is here, or can also be found here on Debian.

Below you'll find a patch to build multitee on cygwin (and possibly any other POSIX distribution). To build, just untar the multitee archive, and then in a shell:

$ patch -Np1 <../multitee-3.0-cygwin.patch
$ make
$ cp multitee.1 /usr/local/man/man1
$ cp multitee.exe /usr/local/bin

Example of use:

$ multitee 0-1,4,5 4> foo 5> bar             # same as tee foo bar with better blocking behavior
$ multitee 0:1 3:1 4:1,2 6:7                 # various merge and copy
$ tcpclient server smtp multitee 0:7 6:1e0   # e0 tell multitee to quit as soon connection close
$ multitee 0:3 3:1                           # same as 'socat - FD:3'

The patch

The patch ports calls to BSD signal.h API (struct sigvec, sigvec(), sigmask(), sigblock()...) to the POSIX API (struct sigaction, sigaction(), sigprocmask(), sigfillset()...).
Here the [{{#file: multitee-3.0-cygwin.patch}} patch (you can download it here)]:

--- multitee-3.0/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ multitee-3.0/Makefile	2008-11-24 03:35:43.875000000 +0100
@@ -0,0 +1,9 @@
+
+all:		multitee tee
+
+multitee:       multitee.o sigdfl.o sigsched.o ralloc.o getopt.o fmt.o scan.o
+tee:            tee.o getopt.o ralloc.o fmt.o
+
+clean:
+	rm -f tee multitee *.o *.a *.0 *~ core
+
--- multitee-3.0/multitee.c	1998-02-17 03:25:43.000000000 +0100
+++ multitee-3.0/multitee.c	2008-11-24 03:38:51.296875000 +0100
@@ -180,7 +180,7 @@
  int in;
  int w;
 
- ioscp = (ioscstack) p;
+ ioscp = (struct iosc *) p;
  in = ioscp->in;
 
  if (ioscp->dead)
--- multitee-3.0/ralloc.c	1998-02-17 03:25:43.000000000 +0100
+++ multitee-3.0/ralloc.c	2008-11-24 03:41:24.093750000 +0100
@@ -40,7 +40,7 @@
 
 #include "ralloc.h"
 #include "sod.h"
-extern char *malloc(); /*XXXX*/
+extern void *malloc(); /*XXXX*/
 extern void free();
 
 typedef int (*foo)();
--- multitee-3.0/sigdfl.c	1998-02-17 03:25:44.000000000 +0100
+++ multitee-3.0/sigdfl.c	2008-11-24 03:39:57.734375000 +0100
@@ -2,6 +2,7 @@
 Daniel J. Bernstein, brnstnd@nyu.edu.
 No dependencies.
 Requires BSD signal syscalls.
+24/11/08: Michael Peeters - Ported to POSIX signal.h (tested under Cygwin)
 7/18/91: Baseline. sigdfl 1.0, public domain.
 No known patent problems.
 
@@ -18,18 +19,20 @@
 
 static int cont = 0;
 
-static sigcont() /* XXX: should declare with right signal type */
+static void sigcont(int sig) /* XXX: should declare with right signal type */
 {
+ (void)sig;
  cont = 1;
 }
 
 int sigdfl(sig)
 int sig;
 {
- int oldmask;
- struct sigvec oldvec;
- struct sigvec vec;
- struct sigvec contvec;
+ sigset_t oldmask;
+ sigset_t workmask;
+ struct sigaction oldvec;
+ struct sigaction vec;
+ struct sigaction contvec;
 
  if (sig == SIGCONT)
    return 0; /* strategy below simply cannot work for CONT */
@@ -43,19 +46,20 @@
  /* killing the process and without stopping the process so that it'll */
  /* receive CONT later, then we will enter an infinite loop. [sigh] */
  /* XXX: put maximum time wastage on this? */
- oldmask = sigblock(0);
- sigblock(~0);
+ sigprocmask(SIG_BLOCK,NULL,&oldmask);
+ sigfillset(&workmask);
+ sigprocmask(SIG_BLOCK,&workmask,NULL);
  /* now we won't receive any signals */
- vec.sv_handler = SIG_DFL;
- vec.sv_mask = ~0;
- vec.sv_flags = 0;
- if (sigvec(sig,&vec,&oldvec) == -1)
+ vec.sa_handler = SIG_DFL;
+ vec.sa_mask = ~0;
+ vec.sa_flags = 0;
+ if (sigaction(sig,&vec,&oldvec) == -1)
    if ((sig != SIGSTOP) && (sig != SIGKILL))
      return -1;
- vec.sv_handler = sigcont;
- vec.sv_mask = ~0;
- vec.sv_flags = 0;
- if (sigvec(SIGCONT,&vec,&contvec) == -1)
+ vec.sa_handler = sigcont;
+ vec.sa_mask = ~0;
+ vec.sa_flags = 0;
+ if (sigaction(SIGCONT,&vec,&contvec) == -1)
    return -1;
  cont = 0;
  if (kill(getpid(),sig) == -1)
@@ -66,16 +70,20 @@
     reached this point, sigcont() might already have been run. that's
     why cont must be set to 0 before the kill(). */
  /* after this next bit we may receive sig and/or CONT */
- sigsetmask(~(sigmask(sig) | sigmask(SIGCONT)));
+ sigfillset(&workmask);
+ sigdelset(&workmask,sig);
+ sigdelset(&workmask,SIGCONT);
+ sigprocmask(SIG_SETMASK,&workmask,NULL);
  /* in the near future, sig will in fact be received */
  while (!cont) /* dead loop until we receive CONT */
    ; /* XXX: there should be a syscall so we don't have to loop here */
- sigblock(~0);
+ sigfillset(&workmask);
+ sigprocmask(SIG_BLOCK,&workmask,NULL);
  /* now we won't receive any signals */
- (void) sigvec(sig,&oldvec,&vec); /* we don't care if it fails */
- (void) sigvec(SIGCONT,&contvec,&vec);
+ (void) sigaction(sig,&oldvec,&vec); /* we don't care if it fails */
+ (void) sigaction(SIGCONT,&contvec,&vec);
  /* now signal handlers are back to normal */
- (void) sigsetmask(oldmask);
+ (void) sigprocmask(SIG_SETMASK,&oldmask,NULL);
  return 0;
 }
 
--- multitee-3.0/sigsched.c	1998-02-17 03:25:44.000000000 +0100
+++ multitee-3.0/sigsched.c	2008-11-24 03:35:43.906250000 +0100
@@ -2,6 +2,7 @@
 Daniel J. Bernstein, brnstnd@nyu.edu.
 Depends on ralloc.h, sod.h, config/fdsettrouble.h.
 Requires BSDish environment: reliable signals, sig{vec,block,setmask}, select.
+24/11/08: Michael Peeters - Ported to POSIX signal.h (tested under Cygwin)
 9/1/91: Added worst-case fdset, FD_ZERO, etc. definitions.
 8/25/91: sigsched 1.1, public domain.
 8/25/91: Fixed bug that sigs[sched->blah].r didn't force instant timeout.
@@ -31,17 +32,6 @@
 
 /* XXX: should restore signal set exactly after ss_exec returns */
 
-typedef int sigc_set; /*XXX */
-
-#define sigc_ismember(x,i) (*(x) & (1 << ((i) - 1)))
-#define sigc_addset(x,i) (*(x) |= (1 << ((i) - 1)))
-#define sigc_emptyset(x) (*(x) = 0)
-
-/*       sigprocmask(SIG_UNBLOCK,xxxx,(sigc_set *) 0); */
-#define sigc_unblock(x) (sigsetmask(sigblock(0) & ~*(x)))
-/*       sigprocmask(SIG_BLOCK,xxxx,(sigc_set *) 0); */
-#define sigc_block(x) (sigblock(*(x)))
-
 #ifndef NSIG
 #define NSIG 64 /* it's not as if any sane system has more than 32 */
 #endif
@@ -333,8 +323,8 @@
  sigs[i].r = 1;
 }
 
-static sigc_set sigstorage;
-static sigc_set *xxxx = 0;
+static sigset_t sigstorage;
+static sigset_t *xxxx = 0;
 
 int ss_addsig(i)
 int i;
@@ -344,9 +334,9 @@
  if (!xxxx)
   {
    xxxx = &sigstorage;
-   sigc_emptyset(xxxx);
+   sigemptyset(xxxx);
   }
- sigc_addset(xxxx,i);
+ sigaddset(xxxx,i);
  return 0;
 }
 
@@ -362,7 +352,7 @@
 int ss_exec()
 {
  int i;
- struct sigvec sv;
+ struct sigaction sv;
  recvlist recvhead;
  recvlist temp;
  schedlist sch;
@@ -371,18 +361,18 @@
 
  if (xxxx)
   {
-   sigc_block(xxxx);
+   sigprocmask(SIG_BLOCK,xxxx,NULL);
 
-   sv.sv_handler = handle;
-   sv.sv_mask = *xxxx; /* so handle won't interrupt itself */
-   sv.sv_flags = 0;
+   sv.sa_handler = handle;
+   sv.sa_mask = *xxxx; /* so handle won't interrupt itself */
+   sv.sa_flags = 0;
 
    /* XXX: Does anyone but me find it absolutely idiotic that POSIX
       doesn't provide a way to get each member of a signal set in turn? */
    for (i = 0;i < NUMSIGS;i++)
     {
-     if (sigc_ismember(xxxx,i))
-       if (sigvec(i,&sv,(struct sigvec *) 0) == -1) /*XXX: really trash orig? */
+     if (sigismember(xxxx,i))
+       if (sigaction(i,&sv,(struct sigaction *) 0) == -1) /*XXX: really trash orig? */
 	 ; /* not our problem */
     }
   }
@@ -498,7 +488,7 @@
       }
 
      if (xxxx)
-       sigc_unblock(xxxx);
+       sigprocmask(SIG_UNBLOCK,xxxx,NULL);
      /* This is the only section where handle() can be called. */
      /* XXX: If maxfd == -1, this select functions as a pause. */
      /* XXX: If maxfd == -1 and timeout is instant, should skip select. */
@@ -510,7 +500,7 @@
      r = select(maxfd + 1,&rfds,&wfds,&efds,&timeout);
        /* XXX: does this necessarily prevent timeout race conditions? */
      if (xxxx)
-       sigc_block(xxxx);
+       sigprocmask(SIG_BLOCK,xxxx,NULL);
 
      if (r == -1)
       {
@@ -529,7 +519,7 @@
 
      for (sp = schedhead;sp;sp = SODnext(sp))
       {
-       switch(SODdata(sp).sig->type) 
+       switch(SODdata(sp).sig->type)
 	{
 	 case JUNK:
 	   break;
@@ -595,7 +585,7 @@
     }
   }
  if (xxxx)
-   sigc_unblock(xxxx);
+   sigprocmask(SIG_UNBLOCK,xxxx,NULL);
    /* XXX: should put this at other returns as well */
  return 0;
 }