ChildProcess not working?


#1

Hi Jules,

I’ve successfully used ChildProcess on Windows but I’m not able to make it work on OSX

a simple

ChildProcess process
process.start("unzip PathToSomeZippedFile -d PathToAFolder")

does not work.

Am I missing something ?

Thanks,


#2

Try using a full path for the exe name?


#3

already tried that with my own code.
This test fails as well

ChildProcess process;
process.start("/usr/bin/unzip PathToSomeZippedFile -d PathToAFolder");

#4

Well, I use that class on OSX and it has always worked… Have you dug into it with the debugger?


#5

I did try the debugger but I don’t see how to debug the fork part

Do you use it with parameters ?


#6

Yeah, I pass parameters. Never had a problem!


#7

I’m not sure if this is related, but the OP’s code works for me, in the sense that the application is run. But you can’t generally get results. That is:

ChildProcess process;
process.start("/usr/bin/unzip PathToSomeZippedFile -d PathToAFolder");
String result = process.readAllProcessOutput();

Typically returns an empty string on OS-X. This is because ChildProcess::ActiveProcess::read (…) always fails at:

readHandle = fdopen (pipeHandle, "r");

When I first ran into it I assumed that it is because the process has already ended, but I never really rang it out to make sure. When I want to run a util like unzip and check results, I typically use something like this:

    String process = "/usr/bin/unzip PathToSomeZippedFile -d PathToAFolder";  // Tweak by platform
    String result;
 
#if JUCE_MAC
    FILE* pipe = popen(process.toUTF8(), "r");
    if (pipe)
    {
        char buffer[128];
        while (! feof (pipe))
        {
            if (fgets (buffer, sizeof (buffer), pipe) != NULL)
                result += buffer;
        }
        pclose (pipe);
    }
#else
    ChildProcess childProcess;
    childProcess.start (process);
    result = childProcess.readAllProcessOutput();
#endif

Again, not sure if it is related, but it is definitely a problem I have had with ChildProcess on OS-X.


#8

FWIW, I just took a quick look. fdopen on the read pipe fails with an errno of 2 (no such file) even if you put it in the parent process response to fork().

Didn’t see anything blatantly wrong with the pipe mapping, but I don’t have time to dig deeper.


#9

Yeah, I remember also looking at this, but never figured out what was going wrong. AFAICT my code is doing everything just like the examples tell you to…


#10

Well, in theory, popen is basically a wrapper around pipe/fork:

http://www.publicsource.apple.com/source/Libc/Libc-166/gen.subproj/popen.c?txt

At a glance, the biggest difference I see is that it is a vfork(), same memory space. If I have time later I’ll do some poking.


#11

Ok, the reason that reading process output is broken on OS-X is that fdopen is being defined to:

#      define fdopen(fd,mode) NULL /* No fdopen() */

In a file called zutil.h, from zlib, specifically in the OS-X case. If I force fdopen back to the definition from stdio.h in juce_posix_SharedCode.h, I can read the child process output using ChildProcess::readAllProcessOutput(), just like with popen() above.

Sorry, only had a few minutes, so I didn’t start spelunking to see what’s going on with includes and namespaces.


#12

Humm I know why it wasn’t working for me.
I had a break-point and in that case, the forked process is killed (don’t ask me why)

assertion failure on line 219 of "/SourceCache/gdb/gdb-1510/src/gdb/macosx/macosx-nat-inferior-util.c" in function "macosx_inferior_suspend_mach": macosx_task_valid (s->task)
warning: Got an error handling event: "assertion failure on line 219 of "/SourceCache/gdb/gdb-1510/src/gdb/macosx/macosx-nat-inferior-util.c" in function "macosx_inferior_suspend_mach": macosx_task_valid (s->task)

#13

By the way, thanks jfitzpat, your code with popen works fine so I will be using this.


#14

[quote=“jfitzpat”]Ok, the reason that reading process output is broken on OS-X is that fdopen is being defined to:

#      define fdopen(fd,mode) NULL /* No fdopen() */

[/quote]

WTF?? Goddamn C hackers with their fucking macros! :evil: Considering that zlib must be one of the most widely-used libraries in the world, it really is a terrible piece of crap. One day when I’ve nothing better to do, I’ll write a C++ replacement for it, in about 200 lines of elegant code with no macros.

Thanks, I’ve added some #undefs now, and some checks to make sure it doesn’t sneak through the net again!


#15

[quote=“jules”]
WTF?? Goddamn C hackers with their fucking macros! :evil: [/quote]

A JUCE gear tee shirt perhaps?


#16

[quote=“jfitzpat”][quote=“jules”]
WTF?? Goddamn C hackers with their fucking macros! :evil: [/quote]

A JUCE gear tee shirt perhaps?[/quote]

I’d rock it!