glib の g_spawn_async_with_pipes () を bash でテストしています。
この機能を使用して bash を子プロセスとして起動し、親から子 (bash) 入力にコマンドを書き込んで、bash 出力から結果を取得できるかどうかを知りたいですか?
私の C プログラムは、対話型シェルへのインターフェースとして機能する必要があります。
私は bash に適切なオプションを与えておらず、bash がどのように機能するかを本当に理解していないと思います (対話モードでは bash の出力、入力が tty/端末にリンクされていることを man ページで確認できます)。
私は多くのことをテストしましたが、ここにいくつかのコードがあります:
//launcher:
GPid pid;
gchar *launch[] = {"/bin/bash","-s",NULL };
gint in,
out,
err;
GIOChannel *out_ch,
*err_ch;
gboolean ret;
/* Spawn child process */
ret = g_spawn_async_with_pipes( NULL, launch, NULL,
G_SPAWN_DO_NOT_REAP_CHILD |
G_SPAWN_FILE_AND_ARGV_ZERO, NULL,
NULL, &pid, &in, &out, &err, NULL );
if( ! ret )
{
g_error( "SPAWN FAILED" );
return;
}
/* Create channels that will be used to read data from pipes. */
out_ch = g_io_channel_unix_new( out );
err_ch = g_io_channel_unix_new( err );
/* Add watches to channels */
g_io_add_watch( out_ch, G_IO_IN | G_IO_HUP, (GIOFunc)cb_out_watch, NULL );
g_io_add_watch( err_ch, G_IO_IN | G_IO_HUP, (GIOFunc)cb_err_watch, NULL );
//create channel for input:
GIOChannel * input_channel;
input_channel = g_io_channel_unix_new (in);
//create the string "date\r\n" to send to bash input
GString * cmd = g_string_new("date");
GString * carriage_return = g_string_new("\r\n");
g_string_append(cmd,carriage_return->str);
GError * error;
error = NULL;
gsize bytes_written;
printf("Launching date in bash:\n");
g_io_channel_write_chars( input_channel,
cmd->str,
cmd->len,
&bytes_written,
&error);
if (error != NULL)
{
printf("%s\n", error->message);
}
ここにcb_out_watchのコードがあります
static gboolean
cb_out_watch( GIOChannel *channel, GIOCondition cond, gpointer user_data )
{
printf("->reading bash output\n");
gchar *string;
gsize size;
if( cond == G_IO_HUP )
{
g_io_channel_unref( channel );
return( FALSE );
}
g_io_channel_read_line( channel, &string, &size, NULL, NULL );
printf("output : \n:%s\n", string);
g_free( string );
return( TRUE );
}