|
Packit |
ae235b |
#include <gio/gio.h>
|
|
Packit |
ae235b |
#include <string.h>
|
|
Packit |
ae235b |
#include <stdio.h>
|
|
Packit |
ae235b |
#include <stdlib.h>
|
|
Packit |
ae235b |
#include <errno.h>
|
|
Packit |
ae235b |
#ifdef G_OS_UNIX
|
|
Packit |
ae235b |
#include <unistd.h>
|
|
Packit |
ae235b |
#include <gio/gunixinputstream.h>
|
|
Packit |
ae235b |
#include <gio/gunixoutputstream.h>
|
|
Packit |
ae235b |
#else
|
|
Packit |
ae235b |
#include <io.h>
|
|
Packit |
ae235b |
#endif
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static GOptionEntry options[] = {
|
|
Packit |
ae235b |
{NULL}
|
|
Packit |
ae235b |
};
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
write_all (int fd,
|
|
Packit |
ae235b |
const guint8* buf,
|
|
Packit |
ae235b |
gsize len)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
while (len > 0)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gssize bytes_written = write (fd, buf, len);
|
|
Packit |
ae235b |
int errsv = errno;
|
|
Packit |
ae235b |
if (bytes_written < 0)
|
|
Packit |
ae235b |
g_error ("Failed to write to fd %d: %s",
|
|
Packit |
ae235b |
fd, g_strerror (errsv));
|
|
Packit |
ae235b |
buf += bytes_written;
|
|
Packit |
ae235b |
len -= bytes_written;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
echo_mode (int argc,
|
|
Packit |
ae235b |
char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
int i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 2; i < argc; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
write_all (1, (guint8*)argv[i], strlen (argv[i]));
|
|
Packit |
ae235b |
write_all (1, (guint8*)"\n", 1);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
echo_stdout_and_stderr_mode (int argc,
|
|
Packit |
ae235b |
char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
int i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 2; i < argc; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
write_all (1, (guint8*)argv[i], strlen (argv[i]));
|
|
Packit |
ae235b |
write_all (1, (guint8*)"\n", 1);
|
|
Packit |
ae235b |
write_all (2, (guint8*)argv[i], strlen (argv[i]));
|
|
Packit |
ae235b |
write_all (2, (guint8*)"\n", 1);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
cat_mode (int argc,
|
|
Packit |
ae235b |
char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
GIOChannel *chan_stdin;
|
|
Packit |
ae235b |
GIOChannel *chan_stdout;
|
|
Packit |
ae235b |
GIOStatus status;
|
|
Packit |
ae235b |
char buf[1024];
|
|
Packit |
ae235b |
gsize bytes_read, bytes_written;
|
|
Packit |
ae235b |
GError *local_error = NULL;
|
|
Packit |
ae235b |
GError **error = &local_error;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
chan_stdin = g_io_channel_unix_new (0);
|
|
Packit |
ae235b |
g_io_channel_set_encoding (chan_stdin, NULL, error);
|
|
Packit |
ae235b |
g_assert_no_error (local_error);
|
|
Packit |
ae235b |
chan_stdout = g_io_channel_unix_new (1);
|
|
Packit |
ae235b |
g_io_channel_set_encoding (chan_stdout, NULL, error);
|
|
Packit |
ae235b |
g_assert_no_error (local_error);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
while (TRUE)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
do
|
|
Packit |
ae235b |
status = g_io_channel_read_chars (chan_stdin, buf, sizeof (buf),
|
|
Packit |
ae235b |
&bytes_read, error);
|
|
Packit |
ae235b |
while (status == G_IO_STATUS_AGAIN);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_ERROR)
|
|
Packit |
ae235b |
break;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
do
|
|
Packit |
ae235b |
status = g_io_channel_write_chars (chan_stdout, buf, bytes_read,
|
|
Packit |
ae235b |
&bytes_written, error);
|
|
Packit |
ae235b |
while (status == G_IO_STATUS_AGAIN);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_ERROR)
|
|
Packit |
ae235b |
break;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_io_channel_unref (chan_stdin);
|
|
Packit |
ae235b |
g_io_channel_unref (chan_stdout);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (local_error)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
g_printerr ("I/O error: %s\n", local_error->message);
|
|
Packit |
ae235b |
g_clear_error (&local_error);
|
|
Packit |
ae235b |
return 1;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static gint
|
|
Packit |
ae235b |
sleep_forever_mode (int argc,
|
|
Packit |
ae235b |
char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
GMainLoop *loop;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
loop = g_main_loop_new (NULL, TRUE);
|
|
Packit |
ae235b |
g_main_loop_run (loop);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
write_to_fds (int argc, char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
int i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 2; i < argc; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
int fd = atoi (argv[i]);
|
|
Packit |
ae235b |
FILE *f = fdopen (fd, "w");
|
|
Packit |
ae235b |
const char buf[] = "hello world\n";
|
|
Packit |
ae235b |
size_t bytes_written;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_assert (f != NULL);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
bytes_written = fwrite (buf, 1, sizeof (buf), f);
|
|
Packit |
ae235b |
g_assert (bytes_written == sizeof (buf));
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (fclose (f) == -1)
|
|
Packit |
ae235b |
g_assert_not_reached ();
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
env_mode (int argc, char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
char **env;
|
|
Packit |
ae235b |
int i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
env = g_get_environ ();
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; env[i]; i++)
|
|
Packit |
ae235b |
g_print ("%s\n", env[i]);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_strfreev (env);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
cwd_mode (int argc, char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
char *cwd;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
cwd = g_get_current_dir ();
|
|
Packit |
ae235b |
g_print ("%s\n", cwd);
|
|
Packit |
ae235b |
g_free (cwd);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static int
|
|
Packit |
ae235b |
printenv_mode (int argc, char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 2; i < argc; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
const gchar *value = g_getenv (argv[i]);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (value != NULL)
|
|
Packit |
ae235b |
g_print ("%s=%s\n", argv[i], value);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
int
|
|
Packit |
ae235b |
main (int argc, char **argv)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
GOptionContext *context;
|
|
Packit |
ae235b |
GError *error = NULL;
|
|
Packit |
ae235b |
const char *mode;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
context = g_option_context_new ("MODE - Test GSubprocess stuff");
|
|
Packit |
ae235b |
g_option_context_add_main_entries (context, options, NULL);
|
|
Packit |
ae235b |
if (!g_option_context_parse (context, &argc, &argv, &error))
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
g_printerr ("%s: %s\n", argv[0], error->message);
|
|
Packit |
ae235b |
return 1;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (argc < 2)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
g_printerr ("MODE argument required\n");
|
|
Packit |
ae235b |
return 1;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
mode = argv[1];
|
|
Packit |
ae235b |
if (strcmp (mode, "noop") == 0)
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
else if (strcmp (mode, "exit1") == 0)
|
|
Packit |
ae235b |
return 1;
|
|
Packit |
ae235b |
else if (strcmp (mode, "assert-argv0") == 0)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
if (strcmp (argv[0], "moocow") == 0)
|
|
Packit |
ae235b |
return 0;
|
|
Packit |
ae235b |
g_printerr ("argv0=%s != moocow\n", argv[0]);
|
|
Packit |
ae235b |
return 1;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
else if (strcmp (mode, "echo") == 0)
|
|
Packit |
ae235b |
return echo_mode (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "echo-stdout-and-stderr") == 0)
|
|
Packit |
ae235b |
return echo_stdout_and_stderr_mode (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "cat") == 0)
|
|
Packit |
ae235b |
return cat_mode (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "sleep-forever") == 0)
|
|
Packit |
ae235b |
return sleep_forever_mode (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "write-to-fds") == 0)
|
|
Packit |
ae235b |
return write_to_fds (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "env") == 0)
|
|
Packit |
ae235b |
return env_mode (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "cwd") == 0)
|
|
Packit |
ae235b |
return cwd_mode (argc, argv);
|
|
Packit |
ae235b |
else if (strcmp (mode, "printenv") == 0)
|
|
Packit |
ae235b |
return printenv_mode (argc, argv);
|
|
Packit |
ae235b |
else
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
g_printerr ("Unknown MODE %s\n", argv[1]);
|
|
Packit |
ae235b |
return 1;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return TRUE;
|
|
Packit |
ae235b |
}
|