Discussion:
[fpc-pascal] Exec(), Linux, and /dev/null redirection
Zitt Zitterkopf
2010-02-17 00:34:08 UTC
Permalink
I'm cross developing a program in free pascal running FreeVision. When running under Linux / Busybox; I'm attempting to mount a device to scan it for a set of files. Since I'm running a TUI (Text User Interface); I cannot have the BusyBox mount command printing failure information to the screen where it corrupts the TUI. The pascal code:



Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' &> /dev/null');



When running:



Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline );



I see "device busy" STDERR messages appear on the screen. However, when I try to redirect using the ' &> /dev/null' it appears as tho the BusyBox executable is being passed ' &> /dev/null' as a parameter and isn't taking it as the appropriate redirection command.



I tried the following kludge instead:

var

OurPipe : Text;



popen( OurPipe, '/bin/mount /dev/'+ aline +' /media/' + aline, 'R');
Try
if (fpgeterrno=0) then Flush (OurPipe)
ELSE MessageBox ('mount pipe error ' + IntToStr(fpgeterrno), nil,
mfError or mfOKButton);
Finally
PClose( OurPipe );
END;



however, I'm getting an Accessviolation. unsure if I'm even going down the right path.



Any other suggestions?
cobines
2010-02-17 01:45:38 UTC
Permalink
Post by Zitt Zitterkopf
Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' &> /dev/null');
Try:

Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' 1>/dev/null');

for redirecting STDOUT or

Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' 2>/dev/null
1>/dev/null');

for redirecting STDOUT and STDERR.
Post by Zitt Zitterkopf
var
OurPipe    : Text;
         popen( OurPipe, '/bin/mount /dev/'+ aline +' /media/' + aline,
'R');
         Try
             if (fpgeterrno=0) then Flush (OurPipe)
             ELSE MessageBox ('mount pipe error ' + IntToStr(fpgeterrno),
nil,
                  mfError or mfOKButton);
         Finally
             PClose( OurPipe );
         END;
This works for me:

var f: textfile;
s: string;
begin
if popen(f, '/bin/mount /dev/'+ aline +' /media/' + aline + ' 2>&1',
'r') = 0 then
begin
readln(f,s);

// test output 's'

pclose(f);
end
else
error := fpgeterrno; // failed
end;

This puts stdout and stderr into one pipe however. There must be some
way to read from stdout and stderr separately, maybe using TProcess,
but I've never needed it so I don't know how.

--
cobines
Marco van de Voort
2010-02-17 08:03:51 UTC
Permalink
Post by cobines
Post by Zitt Zitterkopf
Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' &> /dev/null');
Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' 1>/dev/null');
for redirecting STDOUT or
Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' 2>/dev/null
1>/dev/null');
for redirecting STDOUT and STDERR.
Try
fpsystem

it executes a shell, and &> 1> 2> are shell commands, and won't work with
direct execution commands like exec (which is old anyway, use
executeprocess)
Post by cobines
This puts stdout and stderr into one pipe however. There must be some
way to read from stdout and stderr separately, maybe using TProcess,
but I've never needed it so I don't know how.
TProcess is definitely the thing to look at.
Zitt Zitterkopf
2010-02-19 06:11:06 UTC
Permalink
I wanted to thank you guys for you help with this and other problems I posted recently.

My project entered beta today... and I'm expecting it to be opensourced in the coming mth or so.



I ended up using the suggestion of using the fpsystem() call which seemed to work well except that it does not work if you do not have a bash shell installed in your environment. I worked around this by sym linking sh to bash to make it work under busybox; however, someone may want to look to see if the fpsystem call can be shell independant.



John



From: ***@hotmail.com
To: fpc-***@lists.freepascal.org
Subject: Exec(), Linux, and /dev/null redirection
Date: Tue, 16 Feb 2010 16:34:08 -0800



I'm cross developing a program in free pascal running FreeVision. When running under Linux / Busybox; I'm attempting to mount a device to scan it for a set of files. Since I'm running a TUI (Text User Interface); I cannot have the BusyBox mount command printing failure information to the screen where it corrupts the TUI. The pascal code:

Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline + ' &> /dev/null');

When running:

Exec( '/bin/mount', '/dev/'+ aline +' /media/' + aline );

I see "device busy" STDERR messages appear on the screen. However, when I try to redirect using the ' &> /dev/null' it appears as tho the BusyBox executable is being passed ' &> /dev/null' as a parameter and isn't taking it as the appropriate redirection command.

I tried the following kludge instead:
var
OurPipe : Text;

popen( OurPipe, '/bin/mount /dev/'+ aline +' /media/' + aline, 'R');
Try
if (fpgeterrno=0) then Flush (OurPipe)
ELSE MessageBox ('mount pipe error ' + IntToStr(fpgeterrno), nil,
mfError or mfOKButton);
Finally
PClose( OurPipe );
END;

however, I'm getting an Accessviolation. unsure if I'm even going down the right path.

Any other suggestions?

Loading...