Two methods to intercept the PIPE by an GS extension


This is an example made ​​to handle the execution and iteration of the process launched by an extension of gnome shell; the code allows you to intercept the contents of the PIPE of the process launched and print the contents in the log of the shell. This is the sample code of GLib.IOChannel:

...
var strPipeOut;

const PIPE = new Lang.Class({
    Name: 'Test23.PIPE',
    Signals: [{
        name: 'stdOUT',
        parameters: [GObject.TYPE_STRING],
        return_type: null
    }],

    // Create the application itself
    _init: function (cmd, scope) {
        global.log('Test #23 > PIPE init Communication');

        this.ScriptName = cmd;
        this.Scope = scope;
        this.notifyOUT = null;

        Main.sessionMode.connect('msg-event', Lang.bind(this, this._msg));


        [success, this.argv] = GLib.shell_parse_argv(cmd);
        if (success) {

            [success, this.pid, this.std_in, this.std_out, this.std_err] =
                GLib.spawn_async_with_pipes(null, this.argv, null, GLib.SpawnFlags.SEARCH_PATH, function () {}, null, null);
            if (success) {

                global.log('Test #23 > PIPE argv ' + this.argv);
                global.log('Test #23 > PIPE pid ' + this.pid);
                global.log('Test #23 > PIPE std_in ' + this.std_in);
                global.log('Test #23 > PIPE std_out ' + this.std_out);
                global.log('Test #23 > PIPE std_err  ' + this.std_err);

                global.log('Test #23 > PIPE read log from socket');



                this.IOchannelOUT = GLib.IOChannel.unix_new(this.std_out);
                this.IOchannelOUT.set_flags(GLib.IOFlags.IS_READABLE | GLib.IOFlags.NONBLOCK);
                this.tagWatchOUT = GLib.io_add_watch(this.IOchannelOUT, GLib.PRIORITY_DEFAULT,
                    GLib.IOCondition.IN | GLib.IOCondition.HUP | GLib.IOCondition.OUT |
                    GLib.IOCondition.ERR | GLib.IOCondition.NVAL | GLib.IOCondition.PRI,
                    this._loadPipeOUT, null, function () {});

                this.IOchannelERR = GLib.IOChannel.unix_new(this.std_err);
                this.IOchannelERR.set_flags(GLib.IOFlags.IS_READABLE | GLib.IOFlags.NONBLOCK);
                this.tagWatchERR = GLib.io_add_watch(this.IOchannelERR, GLib.PRIORITY_DEFAULT,
                    GLib.IOCondition.IN | GLib.IOCondition.HUP | GLib.IOCondition.OUT |
                    GLib.IOCondition.ERR | GLib.IOCondition.NVAL | GLib.IOCondition.PRI,
                    this._loadPipeERR, null, function () {});

                this.IOchannelIN = GLib.IOChannel.unix_new(this.std_in);
                this.IOchannelIN.set_flags(GLib.IOFlags.IS_WRITABLE | GLib.IOFlags.IS_READABLE | GLib.IOFlags.NONBLOCK);
                this.tagWatchIN = GLib.io_add_watch(this.IOchannelIN, GLib.PRIORITY_DEFAULT,
                    GLib.IOCondition.OUT | GLib.IOCondition.HUP | GLib.IOCondition.IN |
                    GLib.IOCondition.ERR | GLib.IOCondition.NVAL | GLib.IOCondition.PRI,
                    this._writePipeIN, null, function () {});
            }
        }
    },

    _loadPipeOUT: function (channel, condition) {
        var length, strLog, ret;
        global.log('Test #23 > PIPE OUT # Load pipe ');

        if (condition === GLib.IOCondition.HUP) {
            global.log('Test #23 > PIPE OUT # pipe condition HUP #');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchOUT);

            return false;
        } else if (condition === GLib.IOCondition.ERR) {
            global.log('Test #23 > PIPE OUT # pipe condition ERR#');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchOUT);

            return false;
        } else if (condition === GLib.IOCondition.NVAL) {
            global.log('Test #23 > PIPE OUT # pipe condition NVAL');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchOUT);

            return false;
        } else if (condition === GLib.IOCondition.IN) {
            global.log('Test #23 > PIPE OUT # pipe condition IN');

            [ret, strLog, length] = channel.read_line();

            if (ret === GLib.IOStatus.ERROR) {
                global.log('Test #23 > PIPE OUT # Error reading');

                channel.shutdown(true);
                channel.close();
                GLib.source_remove(this.tagWatchOUT);

                return false;
            } else if (ret === GLib.IOStatus.EOF) {
                global.log('Test #23 > PIPE OUT # EOF');

                channel.shutdown(true);
                channel.close();
                GLib.source_remove(this.tagWatchOUT);

                return false;
            } else {
                strPipeOut = strPipeOut + strLog;
                global.log('Test #23 > PIPE OUT # msg -len ' + length + ' -str ' + strLog);

            }

            return true;
        } else if (condition === GLib.IOCondition.OUT) {
            global.log('Test #23 > PIPE OUT # pipe condition OUT');
        } else if (condition === GLib.IOCondition.PRI) {
            global.log('Test #23 > PIPE OUT # pipe condition PRI');
        } else {
            global.log('Test #23 > PIPE OUT # pipe condition UNK : ' + condition);
            return false;
        }
        return false;
    },

    _loadPipeERR: function (channel, condition) {
        var strLog, length, ret;
        global.log('Test #23 > PIPE ERR # Load pipe ');
        if (condition === GLib.IOCondition.HUP) {
            global.log('Test #23 > PIPE ERR # pipe condition HUP #');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchERR);

            return false;
        } else if (condition === GLib.IOCondition.ERR) {
            global.log('Test #23 > PIPE ERR # pipe condition ERR#');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchERR);

            return false;
        } else if (condition === GLib.IOCondition.NVAL) {
            global.log('Test #23 > PIPE ERR # pipe condition NVAL');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchERR);

            return false;
        } else if (condition === GLib.IOCondition.IN) {
            global.log('Test #23 > PIPE ERR # pipe condition IN');

            [ret, strLog, length] = channel.read_line();

            if (ret === GLib.IOStatus.ERROR) {
                global.log('Test #23 > PIPE ERR # Error reading');

                channel.shutdown(true);
                channel.close();
                GLib.source_remove(this.tagWatchERR);

                return false;
            } else if (ret === GLib.IOStatus.EOF) {
                global.log('Test #23 > PIPE ERR # EOF');

                channel.shutdown(true);
                channel.close();
                GLib.source_remove(this.tagWatchERR);

                return false;
            } else {
                global.log('Test #23 > PIPE ERR # msg -len ' + length + ' -str ' + strLog);

                this.emit('msg-event', strLog);
            }

            return true;
        } else if (condition === GLib.IOCondition.OUT) {
            global.log('Test #23 > PIPE ERR # pipe condition OUT');
        } else if (condition === GLib.IOCondition.PRI) {
            global.log('Test #23 > PIPE ERR # pipe condition PRI');
        } else {
            global.log('Test #23 > PIPE ERR # pipe condition UNK : ' + condition);
            return false;
        }
        return false;
    },

    _writePipeIN: function (channel, condition) {
        var strLog, length, ret;
        global.log('Test #23 > PIPE IN # Load pipe ');
        if (condition === GLib.IOCondition.HUP) {
            global.log('Test #23 > PIPE IN # pipe condition HUP #');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchIN);

            return false;
        } else if (condition === GLib.IOCondition.ERR) {
            global.log('Test #23 > PIPE IN # pipe condition ERR#');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchIN);

            return false;
        } else if (condition === GLib.IOCondition.NVAL) {
            global.log('Test #23 > PIPE IN # pipe condition NVAL');

            channel.shutdown(true);
            channel.close();
            GLib.source_remove(this.tagWatchIN);

            return false;
        } else if (condition === GLib.IOCondition.OUT) {
            global.log('Test #23 > PIPE IN # pipe condition OUT');

            var ret = channel.flush();
            //channel.write_chars(strIP, strIP.length);

            if (ret === GLib.IOStatus.ERROR) {
                global.log('Test #23 > PIPE IN # Error');

                channel.shutdown(true);
                channel.close();
                GLib.source_remove(this.tagWatchIN);

                return false;
            } else if (ret === GLib.IOStatus.EOF) {
                global.log('Test #23 > PIPE IN # EOF');

                channel.shutdown(true);
                channel.close();
                GLib.source_remove(this.tagWatchIN);

                return false;
            } else if (ret === GLib.IOStatus.NORMAL) {
                global.log('Test #23 > PIPE IN # event NORMAL');

                return false;
            } else if (ret === GLib.IOStatus.AGAIN) {
                global.log('Test #23 > PIPE IN # event AGAIN');

                return true;
            } else {
                global.log('Test #23 > PIPE IN # error write to std_in : ' + ret);
                return false;
            }
        } else if (condition === GLib.IOCondition.IN) {
            global.log('Test #23 > PIPE IN # pipe condition IN');
        } else if (condition === GLib.IOCondition.PRI) {
            global.log('Test #23 > PIPE IN # pipe condition PRI');
        } else {
            global.log('Test #23 > PIPE IN # pipe condition UNK : ' + condition);
            return false;
        }
        return false;
    },

    _msg: function () {
        global.log('Test #23 > PIPE msg event present');
    },

    _destroy: function () {
        global.log('Test #23 > PIPE destroy script obj');
    }
});

Signals.addSignalMethods(PIPE.prototype);
...

This is the sample code of Gio.DataOutputStream:

...
const IPC = new Lang.Class({
    Name: 'Test23.IPC',

    // Create the application itself
    _init: function (cmd) {
        global.log('Test #23 > IPC init Communication');

        Main.sessionMode.connect('msg-event', Lang.bind(this, this._msg));

        [success, this.argv] = GLib.shell_parse_argv(cmd);
        if (success) {

            [success, this.pid, this.std_in, this.std_out, this.std_err] =
                GLib.spawn_async_with_pipes(null, this.argv, null, GLib.SpawnFlags.SEARCH_PATH, function () {}, null, null);
            if (success) {

                global.log('Test #23 > IPC argv ' + this.argv);
                global.log('Test #23 > IPC pid ' + this.pid);
                global.log('Test #23 > IPC std_in ' + this.std_in);
                global.log('Test #23 > IPC std_out ' + this.std_out);
                global.log('Test #23 > IPC std_err  ' + this.std_err);

                global.log('Test #23 > IPC read log from socket');

                let out_reader = new Gio.DataInputStream({
                    base_stream: new Gio.UnixInputStream({
                        fd: this.std_out
                    })
                });
                let in_writer = new Gio.DataOutputStream({
                    base_stream: new Gio.UnixOutputStream({
                        fd: this.std_in
                    })
                });

                var strOUT;
                let [out, size] = out_reader.read_line(null);
                while (out !== null) {
                    global.log('Test #23 > IPC std_out ->' + out);
                    strOUT += out;
                    [out, size] = out_reader.read_line(null);
                }

                global.log('Test #23 > IPC FINAL std_out ->' + strOUT);
            }
        }
    },

    _destroy: function () {
        global.log('Test #23 > IPC destroy script obj');
    }
});
...

that’s all.8y3

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...