(root)/
glib-2.79.0/
gio/
tests/
test-pipe-unix.c
       1  /* Unix pipe-to-self. This is a utility module for tests, not a test.
       2   *
       3   * Copyright © 2008-2010 Red Hat, Inc.
       4   * Copyright © 2011 Nokia Corporation
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   *
       8   * This library is free software; you can redistribute it and/or
       9   * modify it under the terms of the GNU Lesser General Public
      10   * License as published by the Free Software Foundation; either
      11   * version 2.1 of the License, or (at your option) any later version.
      12   *
      13   * This library is distributed in the hope that it will be useful,
      14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16   * Lesser General Public License for more details.
      17   *
      18   * You should have received a copy of the GNU Lesser General
      19   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      20   *
      21   * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
      22   */
      23  
      24  #include <errno.h>
      25  #include <unistd.h>
      26  
      27  #include <gio/gio.h>
      28  
      29  #include "test-io-stream.h"
      30  #include "test-pipe-unix.h"
      31  
      32  #ifdef G_OS_UNIX
      33  #   include <gio/gunixinputstream.h>
      34  #   include <gio/gunixoutputstream.h>
      35  #else
      36  #   error This module only exists on Unix
      37  #endif
      38  
      39  /**
      40   * test_pipe:
      41   * @is: (out) (optional): used to return a #GInputStream
      42   * @os: (out) (optional): used to return a #GOutputStream
      43   * @error: used to raise an error
      44   *
      45   * Return a "pipe to self" connecting @is to @os. This can be used
      46   * as a unidirectional pipe to or from a child process, for instance.
      47   *
      48   * See test_bidi_pipe() if you want to emulate a bidirectional pipe
      49   * via a pair of unidirectional pipes.
      50   *
      51   * Returns: %TRUE on success
      52   */
      53  gboolean
      54  test_pipe (GInputStream  **is,
      55             GOutputStream **os,
      56             GError        **error)
      57  {
      58    int pipefd[2];
      59    int ret;
      60  
      61    ret = pipe (pipefd);
      62  
      63    if (ret != 0)
      64      {
      65        int e = errno;
      66  
      67        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (e),
      68                     "%s", g_strerror (e));
      69        return FALSE;
      70      }
      71  
      72    if (is != NULL)
      73      *is = g_unix_input_stream_new (pipefd[0], TRUE);
      74    else
      75      close (pipefd[0]);
      76  
      77    if (os != NULL)
      78      *os = g_unix_output_stream_new (pipefd[1], TRUE);
      79    else
      80      close (pipefd[1]);
      81  
      82    return TRUE;
      83  }
      84  
      85  /**
      86   * test_bidi_pipe:
      87   * @left: (out) (optional): used to return one #GIOStream
      88   * @right: (out) (optional): used to return the other #GIOStream
      89   * @error: used to raise an error
      90   *
      91   * Return two #GIOStreams connected to each other with pipes.
      92   * The "left" input stream is connected by a unidirectional pipe
      93   * to the "right" output stream, and vice versa. This can be used
      94   * as a bidirectional pipe to a child process, for instance.
      95   *
      96   * See test_pipe() if you only need a one-way pipe.
      97   *
      98   * Returns: %TRUE on success
      99   */
     100  gboolean
     101  test_bidi_pipe (GIOStream **left,
     102                  GIOStream **right,
     103                  GError    **error)
     104  {
     105    GInputStream *left_in = NULL;
     106    GOutputStream *left_out = NULL;
     107    GInputStream *right_in = NULL;
     108    GOutputStream *right_out = NULL;
     109    gboolean ret = FALSE;
     110  
     111    if (!test_pipe (&left_in, &right_out, error))
     112      goto out;
     113  
     114    if (!test_pipe (&right_in, &left_out, error))
     115      goto out;
     116  
     117    if (left != NULL)
     118      *left = test_io_stream_new (left_in, left_out);
     119  
     120    if (right != NULL)
     121      *right = test_io_stream_new (right_in, right_out);
     122  
     123    ret = TRUE;
     124  
     125  out:
     126    g_clear_object (&left_in);
     127    g_clear_object (&left_out);
     128    g_clear_object (&right_in);
     129    g_clear_object (&right_out);
     130    return ret;
     131  }