After running tstringlist.savetostream how can I make sure that the buffer has been flushed and data sent successfully?
Thx

Mailing lists / fpc-pascal / 2010-03
7 messages · 5 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
After running tstringlist.savetostream how can I make sure that the buffer has been flushed and data sent successfully?
Thx
Terry A. Haimann wroteAfter running tstringlist.savetostream how can I make sure that the buffer has been flushed and data sent successfully?
That depend on the stream you passed to TStringList.SaveToStream
After running tstringlist.savetostream how can I make sure that the buffer has been…
Terry A. Haimann wroteAfter running tstringlist.savetostream how can I make sure that the buffer has been flushed and data sent successfully?
It depends on the kind of stream you pass it, but for most streams: if the call returns, all data has been written by the application layer.
Michael.
After running tstringlist.savetostream how can I make sure that the buffer has been…
Hello FPC-Pascal,
Tuesday, March 16, 2010, 2:53:44 AM, you wrote:
TAH> After running tstringlist.savetostream how can I make sure that the TAH> buffer has been flushed and data sent successfully?
If the call returns everything has been saved, if not an exception should happend, but you can not know if data has been flushed to disk, that's a task for your OS, so you must ask the OS about flushed data.
So in other words, if no exception, everything is saved. If you wish to know if data is phisically written to media you must know the stream media and ask the underlaying OS for information, but in this case the stream mode is not the way to go because stream hides that intentionally to the programmer (like hiding handles or any other OS dependent data).
Ok, I have a Lazarus test program that has the following code:
procedure TMainForm.ExecButClick(Sender: TObject);
Var
StdStrLst, ErrorStrLst: TStringList;
MyProcess: TProcess;
begin
StdStrLst := TStringlist.Create;
ErrorStrLst := TStringlist.Create;
MyProcess := TProcess.Create(nil);
MyProcess.CommandLine := 'at -m ' + TimeEdit.Text;
MyProcess.Options := MyProcess.Options + [poUsePipes];
MyProcess.Execute;
StdStrLst.Clear;
StdStrLst.Add(CmdEdit.Text);
StdStrLst.SaveToStream(MyProcess.Input);
StdStrLst.Clear;
StdStrLst.Add(chr(4));
StdStrLst.SaveToStream(MyProcess.Input);
StdStrLst.Destroy;
ErrorStrLst.Destroy;
MyProcess.Destroy;
end;This program seems to submit commands to the At Facility without any issues. They will even run invalid commands and return error messages in the mail command.
Virtually the same logic in a fpc program doesn't work. The program runs, but nothing is submitted to the "AT" facility. I am suspecting something is requiring one of the libraries in Lazarus that I can't seem to get to compile in fpc such as fileutil, LResources or maybe Controls. But I may be missing something else. Something could be going on with the pipes that I don't understand. I don't know of a way to monitor the pipes or the "AT" Facility to see what is going on. I am running FC10-64
program TestPrg;
Uses Classes, Process, SysUtils;
// Uses Classes, SysUtils, fileutil, LResources, Forms, Controls,
Graphics, Dialogs,
// StdCtrls, Process;
Var
i: Integer;
Cmd, Pre, Post, StrVar, SwStr: String;
MyProcess: TProcess;
SOut, EOut, StdStrLst: TStringList;
Begin
StdStrLst := TStringlist.Create;
SOut := TStringlist.Create;
EOut := TStringlist.Create;
MyProcess := TProcess.Create(nil);
MyProcess.CommandLine := 'at -m now';
MyProcess.Options := MyProcess.Options + [poUsePipes];
MyProcess.Execute;
StdStrLst.Clear;
StdStrLst.Add('awk -F":" ''{print $1"\t"$3"\t"$4}'' /etc/passwd |
sort > /home/terry/Documents/fpc/CommandProg/Output.txt');
StdStrLst.SaveToStream(MyProcess.Input);
StdStrLst.Clear;
StdStrLst.Add(chr(4));
StdStrLst.SaveToStream(MyProcess.Input);
SOut.LoadFromStream(MyProcess.Output);
For i:=1 to SOut.Count Do
WriteLn(SOut.Strings[i]);
EOut.LoadFromStream(MyProcess.StdErr);
For i:=1 to EOut.Count Do
WriteLn(EOut.Strings[i]);
End.In our previous episode, Terry A. Haimann said:
As said before, the FPC program might simply terminate and take the AT job with it. Let it pauze at the end, e.g. a readln, and see if that makes a difference.
A tool to see what is going could be "strace"
OK,
I had a bunch of "WriteLn" in my program, so that is how I knew it was running to completion. But I have removed them for this test. I changed my source from sending a chr(4) to pipe.closeinput, which seemed to give a little cleaner run in Lazarus. My test linux command is just a "ls -l" to keep it simple.I am still not getting any jobs created in the AT Facility from my test fpc program. But I have some output from strace, but am not sure how to interpret it:
execve("./teest", ["./teest"], [/* 42 vars */]) = 0 getrlimit(RLIMIT_STACK, {rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0 rt_sigaction(SIGFPE, {0x41f520, [], SA_RESTORER|SA_SIGINFO, 0x400d78}, NULL, 8) = 0 rt_sigaction(SIGSEGV, {0x41f520, [], SA_RESTORER|SA_SIGINFO, 0x400d78}, NULL, 8) = 0 rt_sigaction(SIGBUS, {0x41f520, [], SA_RESTORER|SA_SIGINFO, 0x400d78}, NULL, 8) = 0 rt_sigaction(SIGILL, {0x41f520, [], SA_RESTORER|SA_SIGINFO, 0x400d78}, NULL, 8) = 0 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 readlink("/proc/self/exe", "/home/terry/Documents/fpc/CommandProg/teest", 255) = 43 open("/etc/timezone", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3543, ...}) = 0 open("/etc/localtime", O_RDONLY|O_LARGEFILE) = 3
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\0\5\0\0\0\0"..., 2048) = 2048 mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f513a9c4000 mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f513a9bc000 mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f513a9b4000 mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f513a9ac000 close(3) = 0
time([1268875052]) = 1268875052 mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f513a9a4000 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 readlink("/proc/self/fd/1", "/dev/pts/4"..., 255) = 10 ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 readlink("/proc/self/fd/0", "/dev/pts/4"..., 255) = 10 ioctl(1, TIOCGWINSZ, {ws_row=63, ws_col=209, ws_xpixel=0, ws_ypixel=0}) = 0 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(1, SNDCTL_TMR_START or TCSETS, {B38400 -opost -isig -icanon -echo ...}) = 0 write(0, "\33[6n", 4) = 4
select(2, [1], NULL, NULL, {1, 0}) = 1 (in [1], left {0, 997000}) read(1, "\33[63;1R", 256) = 7
write(1, "\33[m", 3) = 3
pipe([3, 4]) = 0
pipe([5, 6]) = 0
pipe([7, 8]) = 0
access("at", F_OK) = 0
fork() = 7010
close(4) = 0
close(5) = 0
close(8) = 0
write(6, "ls -l\n", 6) = 6
read(3, "", 1024) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
read(7, "", 1024) = 0
close(6) = 0
ioctl(1, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0 munmap(0x7f513a9b4000, 32768) = 0
exit_group(0) = ?
Message: 5
Date: Wed, 17 Mar 2010 06:52:50 +0100 (CET)
From: (Marco van de Voort)
Subject: Re: [fpc-pascal] Re: tstringlist.savetostream To: FPC-Pascal users discussions
Message-ID:
Content-Type: text/plain; charset="US-ASCII"
In our previous episode, Terry A. Haimann said:
As said before, the FPC program might simply terminate and take the AT job with it. Let it pauze at the end, e.g. a readln, and see if that makes a difference.
A tool to see what is going could be "strace"