尝试通过g_spawn_async执行shell命令并读取输出

时间:2013-10-26 11:17:02

标签: c glib

我试图执行shell命令(ls / home)并尝试读取输出 实际上这个程序的问题在哪里? 这是程序。

#include <stdio.h>
#include <glib.h>
#include <stdlib.h>
#include <signal.h>

typedef struct{
    int std_in;
    int std_out;
    int std_err;
}child_fds;

gboolean cb_stdout(GIOChannel* channel, GIOCondition condition, gpointer data){
    if(condition & G_IO_ERR ){
        return TRUE;
    }
    if(condition & G_IO_HUP ){
        return FALSE;
    }
    gsize actually_read;
    gchar* shell_out = (gchar*)g_malloc0(512);
    GIOStatus status = g_io_channel_read_chars(channel,shell_out, 512,&actually_read,NULL );
    if(status != G_IO_STATUS_NORMAL){
        //dont remove the source yet
        g_free(shell_out);
        return TRUE;
    }
    printf("%s \n",shell_out);
    g_free(shell_out);
    return TRUE;
}

GMainLoop * gml = NULL;

void sigterm_handler(int sig_num){
    g_warning("signal recieved");
    g_main_loop_quit(gml);
}

void child_handler(GPid pid, int status, gpointer data){
    g_warning("child killer");
    g_spawn_close_pid(pid);
}
int main(){
    gml = g_main_loop_new(NULL, 0);
    signal(SIGINT,&sigterm_handler ); //ctrl+c
    gchar** command;
    g_shell_parse_argv("/bin/ls /home",NULL, &command, NULL);
    GPid ls_pid;
    child_fds fds_ls;
    if( g_spawn_async_with_pipes(NULL,
                command,
                NULL,
                G_SPAWN_DO_NOT_REAP_CHILD,
                NULL,
                NULL,
                &ls_pid,
                &fds_ls.std_in,
                &fds_ls.std_out,
                &fds_ls.std_err,
                NULL)
    ){
        printf("succesfully spawned\n");
    } else {
        printf("spawning failed\n");
    }
    g_strfreev(command);
    GIOChannel * std_out_ch = g_io_channel_unix_new(fds_ls.std_out);
    g_io_add_watch(std_out_ch, G_IO_IN | G_IO_ERR | G_IO_HUP , (GIOFunc)cb_stdout , (gpointer)&fds_ls);
    g_io_channel_unref(std_out_ch);
    g_child_watch_add(ls_pid , (GChildWatchFunc)child_handler, NULL);
    g_main_loop_run(gml);
    return 0;
}

我不确定io频道的内存处理方式。还不确定主循环处理。建议也非常感谢。

1 个答案:

答案 0 :(得分:1)

乍一看,

if(condition | G_IO_ERR ){
    return TRUE;
}
if(condition | G_IO_HUP ){
    return FALSE;
}

似乎是错误的,因为两种情况总是评估为真。你可能想要'&amp;'操作