Beispiel #1
0
/* This actually is a hack.
 *
 * We only have one single operation active at a time.  So we can use
 * a static buffer here which keeps the intermediate string.
 */
static const char *
get_src(const char *name)
{
  static TINO_BUF	buf;

  if (!m_source)
    return name;

  tino_buf_resetO(&buf);
  tino_buf_add_sO(&buf, m_source);
  tino_buf_add_sO(&buf, name);
  return tino_buf_get_sN(&buf);
}
Beispiel #2
0
/* This is plain crap, really, however there is no good support for
 * this all in my lib yet (there is no support for such things in
 * nearly no language, either.  Python is best in this regard).
 */
static void
dump_line(const char *ptr, size_t n, int lineend)
{
  const char		*p;

  start_line(0, lineend);
  p = tino_buf_get_sN(&prefix);

  if (flag_hexdump)
    tino_xd(&out, p, 8, byte_pos, (const unsigned char *)ptr, n+lineend);
  else
    {
      if (p && *p)
	tino_data_putsA(&out, p);
#ifdef HAVE_ESCAPE_XML
      if (flag_xml)
	tino_data_write_xmlA(&out, ptr, n, flag_xml-1);
      else
#endif
#ifdef HAVE_ESCAPE_JSON
      if (flag_xml)
	tino_data_write_jsonA(&out, ptr, n);
      else
#endif
        tino_data_writeA(&out, ptr, n);
    }

  byte_pos	+= n+lineend;

  in_line	= !lineend;
  p		= in_line ? line_cont_suffix : line_suffix;
  if (!p && !flag_hexdump)
    p		= "\n";
  if (p && *p)
    tino_data_putsA(&out, p);
}
Beispiel #3
0
static void
unbuffered(const char *arg0, int argc, char **argv)
{
  TINO_BUF	buf;

  if (!line_cont_suffix && !flag_hexdump)
    if (flag_localtime || flag_linecount || flag_utc || flag_verbose)
      line_cont_suffix = "\n";
  producer = 0;
  if (argc)
    {
      int	fds[2], redir[TINO_OPEN_MAX], fdmax, i;

      if (tino_file_pipeE(fds))
	tino_exit("cannot create pipe");

      fdmax = fd_in<3 ? 3 : fd_in+1;

      for (i=fdmax; --i>=0; )
        redir[i] = -1;				/* preserve all FDs	*/

      if (fd_in<0)
        fd_in = 1;

      redir[2] = flag_both ? fds[1] : 2;	/* catch stderr on -d, too	*/
      if (fd_in==2)
        redir[1] = redir[2];			/* swap stdin/stderr on -i2	*/
      redir[fd_in] = fds[1];			/* catch the given FD */

      /* catch the child's output for preprocessing
       */
      producer = tino_fork_execO(redir, fdmax, argv, NULL, 0, NULL);
      tino_file_closeE(fds[1]);

      fd_in = fds[0];

#if 0
      /* Following is a mess.  It is only needed for a consumer, though.
       * With a producer we see EOF on the pipe.
       * Shall be handled implicitely by a library somehow:
       */
      tino_sigset(SIGCHLD, terminate);
      terminate();	/* catch early terminated childs	*/
#endif
    }

  tino_buf_initO(&buf);
  if (producer && flag_verbose)
    {
      start_line(1, 1);
      add_prefix("start");
      for (; *argv; argv++)
	add_prefix(" '%s'", *argv);	/* XXX TODO sadly, escape is implemented in tino_io, not in tino_buf	*/
      add_prefix("\n");
      out_open();
      tino_data_putsA(&out, tino_buf_get_sN(&prefix));
    }

  if (fd_in<0)
    fd_in = 0;
  while (tino_buf_readE(&buf, fd_in, -1))
    {
      size_t		n;

      out_open();
      /* XXX TODO MISSING:
       * for flag_buffer==1 or flag_buffer==2
       * immediately write STDOUT(1),
       * but buffer STDERR(dump_line)
       */
      while ((n=tino_buf_get_lenO(&buf))>0)
	{
	  const char	*ptr;
	  size_t	k, p;

	  ptr	= tino_buf_getN(&buf);
	  p	= 0;
	  for (k=0; k<n; k++)
	    if (ptr[k]==line_terminator)
	      {
		dump_line(ptr+p, k-p, 1);
		p	= k+1;
	      }
	  /* k=n	*/
	  if (flag_buffer && p)
	    n = p;	/* do not output incomplete line	*/
	  else if ((flag_buffer>1 && n<=99999) || flag_buffer>2)
	    break;		/* buffer fragments	*/

	  /* We shall, nonblockingly, read additional input data here,
	   * if available.  Leave this to future.
	   */
	  TINO_XXX;

	  if (p<n)
	    dump_line(ptr+p, n-p, 0);
	  if (flag_cat)
	    tino_buf_advanceO(&buf, n);
	  else if (tino_buf_write_away_allE(&buf, 1, n))
	    {
	      /* silently drop out	*/
	      *tino_main_errflag	= 1;
	      break;
	    }
	  if (flag_buffer)
	    break;
	}
      out_flush();
    }
  {
      size_t		n;

      /* in case of flag_buffer: send the rest	*/
      if ((n=tino_buf_get_lenO(&buf))>0)
	{
	  const char	*ptr;

	  out_open();
	  ptr	= tino_buf_getN(&buf);
	  dump_line(ptr, n, 0);
	  if (!flag_cat && tino_buf_write_away_allE(&buf, 1, n))
	    *tino_main_errflag	= 1;
	}
  }
  if (producer)
    {
      char *cause;

#if 0
      tino_sigdummy(SIGCHLD);	/* prevent reentrance of waitpid()	*/
#endif
      /* wait for child to finish after the pipe was closed,
       * so give the child the chance to terminate.
       */
      tino_file_closeE(0);
      *tino_main_errflag	= tino_wait_child_exact(producer, &cause);
      if (flag_verbose)
	{
	  start_line(1, 1);
	  add_prefix("end %s\n", cause);
	  out_open();
	  tino_data_putsA(&out, tino_buf_get_sN(&prefix));
	}
    }
  out_close();			/* close(2)	*/
}