Skip to content

Issue with callback functions #120

@yveszoundi

Description

@yveszoundi

I'm trying to execute a command and capture its output via NSTask, as a way to run external commands within an app bundle (sandbox issues and PATH visibility).

The code below executes successfully, but the command output is printed directly to stdout, instead of being captured. That means that my callback (set_readability_handler) is never registered or invoked.

I suspect that it could be a method signature issue or something fundamental that I'm missing. Any help would be appreciated.

extern crate objc;
extern crate objc_id;
extern crate objc_foundation;

use std::error::Error;
use objc::runtime::{Sel, BOOL, Object};
use objc::{msg_send, sel, class, sel_impl};
use objc_foundation::{NSString, INSString, NSArray, INSArray};

fn main() -> Result<(), Box<dyn Error>> {
    unsafe {
        let cls = class!(NSPipe);
        let pipe: *mut Object = msg_send![cls, alloc];        
        let cls = class!(NSTask);
        let tk: *mut Object = msg_send![cls, alloc];

        let strings = vec![
            NSString::from_str("Hello"),
            NSString::from_str("World"),
        ];

        let args = NSArray::from_vec(strings);

        // See https://gist.github.com/PaulChana/74c7f009e23492fb14bd92e0d82d5268
        extern "C" fn set_readability_handler(_: &Object, _sel: Sel, _: &Object, _: BOOL) {
            println!("Output has been captured.....Maybe not....");
        }          
        
        let s = NSString::from_str("/bin/echo");
        let _:() = msg_send![tk, setLaunchPath: s];
        let _:() = msg_send![tk, setArguments:  args];
        let _:() = msg_send![tk, setStandardOutput: pipe];
        let _:() = msg_send![tk, setStandardError:  pipe];

        let read_handle: *mut Object = msg_send![pipe, fileHandleForReading];

        let _:() = msg_send![read_handle, setReadabilityHandler: set_readability_handler];        
        let _:() = msg_send![read_handle, waitForDataInbackgroundAndNotify];        
        let _:() = msg_send![tk, launch];
        let _:() = msg_send![tk, waitUntilExit];
        let _:() = msg_send![read_handle, closeFile];
        let _:() = msg_send![tk, release];
        let _:() = msg_send![read_handle, release];
        let _:() = msg_send![pipe, release];
    }

    Ok(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions