Пример #1
0
static pipeline_t va_pipe_pipeline(pipeline_t result_so_far,
                                   va_list args)
{
    pipe_processor_t proc = va_arg(args, pipe_processor_t);

    if(proc == NULL)
        return result_so_far;

    void*  aux       = va_arg(args, void*);
    size_t pipe_size = va_arg(args, size_t);

    if(pipe_size == 0)
    {
        pipe_consumer_free(result_so_far.out);
        result_so_far.out = NULL;
        return result_so_far;
    }

    pipe_t* pipe = pipe_new(pipe_size, 0);

    pipe_connect(result_so_far.out , proc, aux, pipe_producer_new(pipe));
    result_so_far.out = pipe_consumer_new(pipe);

    pipe_free(pipe);

    return va_pipe_pipeline(result_so_far, args);
}
Пример #2
0
/* 'open' operation of pipe stream. For each pipe stream, it is
   identified by a decimal number in URI. There could be two
   types: pipe and pipe.srv. They behave pretty much the same,
   except they are two ends of the pipe. */
static int pipe_open (PAL_HANDLE *handle, const char * type,
                      const char * uri, int access, int share,
                      int create, int options)
{
    if (!memcmp(type, "pipe:", 5) && !*uri)
        return pipe_private(handle);

    char * endptr;
    PAL_NUM pipeid = strtol(uri, &endptr, 10);
    PAL_IDX connid = 0;

    if (*endptr == ':') {
        if (create & PAL_CREAT_TRY)
            return -PAL_ERROR_INVAL;

        connid = strtol(endptr + 1, &endptr, 10);
    }

    if (*endptr)
        return -PAL_ERROR_INVAL;

    if (!memcmp(type, "pipe.srv:", 9))
        return pipe_listen(handle, pipeid, create);

    if (!memcmp(type, "pipe:", 5))
        return pipe_connect(handle, pipeid, connid, create);

    return -PAL_ERROR_INVAL;
}
Пример #3
0
/* Connect to a server over a full-duplex socket (i.e. created by
   socketpair), creating the assuan context and returning it in CTX.
   The server filename is NAME, the argument vector in ARGV.
   FD_CHILD_LIST is a -1 terminated list of file descriptors not to
   close in the child.  ATFORK is called in the child right after the
   fork; ATFORKVALUE is passed as the first argument and 0 is passed
   as the second argument. The ATFORK function should only act if the
   second value is 0.

   FLAGS is a bit vector and controls how the function acts:
   Bit 0: If cleared a simple pipe based server is expected and the
          function behaves similar to `assuan_pipe_connect'.

          If set a server based on full-duplex pipes is expected. Such
          pipes are usually created using the `socketpair' function.
          It also enables features only available with such servers.

   Bit 7: If set and there is a need to start the server it will be
          started as a background process.  This flag is useful under
          W32 systems, so that no new console is created and pops up a
          console window when starting the server


   If NAME is NULL, no exec is done but the same process is continued.
   However all file descriptors are closed and some special
   environment variables are set. To let the caller detect whether the
   child or the parent continues, the child returns "client" or
   "server" in *ARGV (but it is sufficient to check only the first
   character).  This feature is only available on POSIX platforms.  */
gpg_error_t
assuan_pipe_connect (assuan_context_t ctx,
		     const char *name, const char *argv[],
		     assuan_fd_t *fd_child_list,
		     void (*atfork) (void *opaque, int reserved),
		     void *atforkvalue, unsigned int flags)
{
  TRACE2 (ctx, ASSUAN_LOG_CTX, "assuan_pipe_connect", ctx,
	  "name=%s, flags=0x%x", name ? name : "(null)", flags);

  if (flags & ASSUAN_PIPE_CONNECT_FDPASSING)
    {
#ifdef HAVE_W32_SYSTEM
      return _assuan_error (ctx, GPG_ERR_NOT_IMPLEMENTED);
#else
      return socketpair_connect (ctx, name, argv, fd_child_list,
                                 atfork, atforkvalue);
#endif
    }
  else
    return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue,
                         flags);
}
Пример #4
0
pipeline_t pipe_parallel(size_t           instances,
                         size_t           in_size,
                         pipe_processor_t proc,
                         void*            aux,
                         size_t           out_size)
{
    pipe_t* in  = pipe_new(in_size,  0),
          * out = pipe_new(out_size, 0);

    while(instances--)
        pipe_connect(pipe_consumer_new(in),
                     proc, aux,
                     pipe_producer_new(out));

    pipeline_t ret = {
        .in  = pipe_producer_new(in),
        .out = pipe_consumer_new(out)
    };

    pipe_free(in);
    pipe_free(out);

    return ret;
}