Calling external programs from D
Regan Heath
regan at netwin.co.nz
Wed Apr 19 14:47:15 PDT 2006
On Wed, 19 Apr 2006 16:53:18 +0200, Tydr Schnubbis <fake at address.dude>
wrote:
> Regan Heath wrote:
>> On Wed, 19 Apr 2006 03:57:44 +0200, Tydr Schnubbis <fake at address.dude>
>> wrote:
>>> Tydr Schnubbis wrote:
>>>> Regan Heath wrote:
>>>>> On Thu, 6 Apr 2006 14:46:09 +0000 (UTC), Stuart Delaney
>>>>> <Stuart_member at pathlink.com> wrote:
>>>>>> There's a bug in the makeBlock functions in process.d. The first
>>>>>> parameter to
>>>>>> calloc should be 1 not 0. With that change (and the private
>>>>>> readLine one) it
>>>>>> works fine for me. Don't have an answer to the OP's DNS problem
>>>>>> though.
>>>>> You're dead right. With those changes it works for me too.
>>>> I've fixed the calloc calls too, but it doesn't help. If I try to
>>>> ping google's IP, which is 64.233.167.99 according to ping, I get
>>>> "Pinging Error: 4invalid UTF-8 sequence". Maybe my windows
>>>> installation is screwed, it's getting really old...
>>>> Btw, I use dmd 0.148, haven't tried this with any other version yet.
>>> Could it be that CreateProcessA is used wrong somehow? I don't know
>>> the win32 api, but does anyone know if using it wrong (security
>>> settings or sth) could block new process from accessing the network?
>>> Where would I start looking if I want to fix this? The msdn docs
>>> didn't help much. Couldn't even find mention of this function, only
>>> CreateProcess, without the trailing 'A'. But it seems to be the same
>>> function.
>>>
>>> Here's what the call looks like:
>>> CreateProcessA(null,std.string.toStringz(command),null,null,true,DETACHED_PROCESS,env,null,&startup,info)
>> CreateProcessA is the ascii version.
>> CreateProcessW is the unicode (UTF-16) version.
>> std.string.toStringz converts the UTF-8 char[] into ascii
>> std.string.toUTF16 can be used to convert the UTF-8 char[] into UTF-16
>> if you want to call CreateProcessW instead.
>> The common cause of the "4invalid UTF-8 sequence" error is trying to
>> output non-ascii characters to the windows console. Can you post your
>> current code here.
>
> Sure. As you can see it's full of weird characters...
>
> import lib.process;
> import std.stdio;
>
> void main()
> {
> Process proc;
> // ping my router
> proc = new Process("ping 192.168.0.1");
> writefln(proc.readLine());
> writefln(proc.readLine());
> writefln(proc.readLine());
> writefln(proc.readLine());
> }
>
>
> I have only made readLine public, and fixed the four calloc calls, no
> other changes have been made to your files.
>
> Compile with: dmd test.d lib/process.d lib/pipestream.d
>
> This prints:
> Pinging Error: 4invalid UTF-8 sequence
>
>
> If I ping google.com instead, I get this:
> Ping request could not find host google.com. Please check the name and
> try again
> .
>
> Error: ReadFile: The pipe has been ended.
>
> ---------
>
> Does both of these work for you? I have no idea what would cause any of
> these problems. I have winxp SP2 US. CreateProcessA is in
> kernel32.dll, of which I have version 5.1.2600.2180
> (xpsp_sp2_rtm.040803-2158). dmd version 0.154, got the same results
> with 0.148.
It's quite odd, try this:
import lib.process;
import std.stdio;
import std.string;
import std.c.string;
extern(C) extern char **_environ;
void main()
{
Process proc;
proc = new Process();
for(int i = 0; _environ[i]; i++) {
proc.addEnv(toString(_environ[i]).dup);
}
//proc.execute("ping www.google.com");
proc.execute("ping 192.168.0.1");
while(true) writefln("%s",proc.readLine());
}
without the addEnv calls above I get the behaviour you're describing. With
them it works.
Without them, and using printf I can see that ping responds with:
"Pinging °ÿ with 32 bytes of data:"
note the weird characters there. At first I thought maybe the command line
I was passing to CreateProcessA was temporary and being collected by the
GC, so I changed process.d to use:
cmd = strdup(std.string.toStringz(command));
where cmd is a member of Process - so will persist as long as it does.
That made no difference. I have no idea why it's doing that, perhaps it
reads it's args in a strange way?? I might write a debug program and run
that passing different args etc to see if I can replicate the odd
behaviour and figure out where it comes from.
Regan
More information about the Digitalmars-d-learn
mailing list