Recent

Author Topic: freopen and fpc?  (Read 1242 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 2210
    • StrumPract is the musicians best friend
freopen and fpc?
« on: April 22, 2021, 09:22:33 pm »
Hello.

Does have fpc the equivalent of that C method?
(It is about to redirect messages from stderr.

Code: C  [Select][+][-]
  1. #include <stdio.h>
  2. freopen("error.log", "w", stderr);

Thanks.

Fre;D
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

devEric69

  • Sr. Member
  • ****
  • Posts: 465
Re: freopen and fpc?
« Reply #1 on: April 22, 2021, 10:48:15 pm »
Hello,

I don't have the answer, but there are tracks... ( source: http://www.delphigroups.info/2/db/506471.html, http://www.delphigroups.info/2/32/118674.html ):
- on Linux, we should have to look for code with 'stderr' (the string, of the homonymous file name stored in the /dev directory, apparently);
- on Windows, we should have to use the MS API GetStdhandle or SetStdhandle;
... which leads to the FpRedir.pas unit, and functions like ChangeRedirError. But, I've never used them.
« Last Edit: April 22, 2021, 10:51:52 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

winni

  • Hero Member
  • *****
  • Posts: 2323
Re: freopen and fpc?
« Reply #2 on: April 22, 2021, 10:51:36 pm »
Hi!

What do you want to achieve?

You  know that there are system.StdOut, system.StdIn and system.StdErr?

Code: Pascal  [Select][+][-]
  1. writeln (StdErr,'Error 123');

Winni

Fred vS

  • Hero Member
  • *****
  • Posts: 2210
    • StrumPract is the musicians best friend
Re: freopen and fpc?
« Reply #3 on: April 22, 2021, 11:43:46 pm »
Hi!

What do you want to achieve?

You  know that there are system.StdOut, system.StdIn and system.StdErr?

Code: Pascal  [Select][+][-]
  1. writeln (StdErr,'Error 123');

Winni

Hello Winni.

Some libraries, for example PortAudio, generate lot of debug-warnings when running it via console.

For example: Audacity, running it via terminal:

Code: Bash  [Select][+][-]
  1. fred@fiens ~> audacity

Gives this on the terminal:
Quote
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
Cannot connect to server socket err = Aucun fichier ou dossier de ce type
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Cannot connect to server socket err = Aucun fichier ou dossier de ce type
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_a52.c:823:(_snd_pcm_a52_open) a52 is only for playback
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
Cannot connect to server socket err = Aucun fichier ou dossier de ce type
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736

Of course you may redirect the output to a file using that parameter:

Code: Bash  [Select][+][-]
  1. fred@fiens ~> audacity 2>> error.log

And now the goal:
In C you may use at init of your program this:

Code: C  [Select][+][-]
  1.     #include <stdio.h>
  2.     freopen("error.log", "w", stderr);

In that case, all the StdErr messages, even from library used, will be redirected to error.log.
It is the same as running in terminal "myprog 2>> error.log" but it is instructed by the program.

How to do that with fpc?

Fre;D
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

Warfley

  • Sr. Member
  • ****
  • Posts: 446
Re: freopen and fpc?
« Reply #4 on: April 23, 2021, 03:24:23 am »
You can use AssignFile:
Code: Pascal  [Select][+][-]
  1.   AssignFile(StdErr, 'stderr.txt');
  2.   Rewrite(StdErr); // Don't know if required
  3.   WriteLn(StdErr, 'Hello World'); // will be written to stderr.txt

Alternatively, using from unit StreamIO the function AssignStream you can redirect the file directly to any stream you like:
Code: Pascal  [Select][+][-]
  1. uses
  2.   Classes, StreamIO;
  3.  
  4. var
  5.   errFile: TFileStream;
  6. begin
  7.   errFile := TFileStream.Create('stderr.txt', fmOpenReadWrite or fmCreate);
  8.   try
  9.     AssignStream(StdErr, errFile);
  10.     Rewrite(StdErr);
  11.     WriteLn(StdErr, 'Hello stderr');
  12.     Flush(StdErr);
  13.   finally
  14.     errFile.Free;
  15.   end;
This way you can also redirect it into a memory stream, a string stream, or your own stream class that writes it to the GUI.
« Last Edit: April 23, 2021, 03:28:24 am by Warfley »

MarkMLl

  • Hero Member
  • *****
  • Posts: 2486
Re: freopen and fpc?
« Reply #5 on: April 23, 2021, 08:57:19 am »
In that case, all the StdErr messages, even from library used, will be redirected to error.log.
It is the same as running in terminal "myprog 2>> error.log" but it is instructed by the program.

OK, so trying to focus on what I think at least one other person has missed: it's concatenating to an existing text file.

Checking working code here:

Code: Pascal  [Select][+][-]
  1.     AssignFile(statusText, filename);
  2.     if FileExists(filename) then
  3.       Append(statusText)
  4.     else
  5.       Rewrite(statusText);
  6.     if IOResult <> 0 then
  7.       statusText := ErrOutput
  8.  

There isn't an fpreopen(), which arguably could be reported as a bug.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Fred vS

  • Hero Member
  • *****
  • Posts: 2210
    • StrumPract is the musicians best friend
Re: freopen and fpc?
« Reply #6 on: April 23, 2021, 01:51:18 pm »
@devEric69 : thanks for the infos!

@Warfley: I try this:

Code: Pascal  [Select][+][-]
  1. program errorlog;
  2. ...
  3. begin
  4.    Assign(StdErr, 'error.log');
  5.    Rewrite(StdErr);
  6.   ...
  7.    Application.run;
  8.    Close(StdErr);
  9.  end.

A empty error.log is created but console-messages are still there.

@MarkMLI: 
Quote
There isn't an fpreopen()

Imho it should make things easier.

Fre;D
« Last Edit: April 23, 2021, 01:54:01 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

Thaddy

  • Hero Member
  • *****
  • Posts: 10782
Re: freopen and fpc?
« Reply #7 on: April 23, 2021, 02:07:53 pm »
If you want to keep the info, do not just use rewrite, but eof().
Rewrite resets pointer to the begin of a file, amongst other issues.
« Last Edit: April 23, 2021, 02:09:36 pm by Thaddy »

Fred vS

  • Hero Member
  • *****
  • Posts: 2210
    • StrumPract is the musicians best friend
Re: freopen and fpc?
« Reply #8 on: April 23, 2021, 02:11:20 pm »
Quote
OK, so trying to focus on what I think at least one other person has missed: it's concatenating to an existing text file.

No, I wanted to know how to hide the error message that appear in terminal and redirect it to a text file.
« Last Edit: April 23, 2021, 02:13:58 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 2210
    • StrumPract is the musicians best friend
Re: freopen and fpc?
« Reply #9 on: April 23, 2021, 02:18:25 pm »
If you want to keep the info, do not just use rewrite, but eof().
Rewrite resets pointer to the begin of a file, amongst other issues.

Hello Thaddy.

Please try this in terminal and see the result on the terminal:

Code: Pascal  [Select][+][-]
  1. $ audacity

Then try this:

Code: Pascal  [Select][+][-]
  1. $ audacity 2>> error.log

You will not see message on console but a log file created with all the infos.

In C they do like this:

Code: C  [Select][+][-]
  1. #include <stdio.h>
  2.     freopen("error.log", "w", stderr);

How to do that in Pascal code.
« Last Edit: April 23, 2021, 02:20:45 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1424
  • Former Delphi 1-7, 10.2 user
Re: freopen and fpc?
« Reply #10 on: April 24, 2021, 03:41:03 am »
Fred, just a thought: are you sure the console text you want to redirect is being sent to StdErr?
Lazarus 2.1 r65061 FPC 3.3.1 r49223 macOS 10.14.6 Xcode 11.3.1
Lazarus 2.1 r65070 FPC 3.3.1 r49223 macOS 11.2.3 aarch64 Xcode 12.4
Lazarus 2.1 r61574 FPC 3.3.1 r42318 FreeBSD 12.1 amd64 VMware VM
Lazarus 2.1 r61574 FPC 3.0.4 Ubuntu 20.04 Parallels VM
Lazarus 2.0.10 FPC 3.2.0 Win10 Parallels VM

Fred vS

  • Hero Member
  • *****
  • Posts: 2210
    • StrumPract is the musicians best friend
Re: freopen and fpc?
« Reply #11 on: April 24, 2021, 04:09:06 am »
Fred, just a thought: are you sure the console text you want to redirect is being sent to StdErr?

Hello Trev.

Yes.

Doing this:

Code: Pascal  [Select][+][-]
  1. $ audacity 2>> log.txt

Redirect all StdErr generated by the application, included the StdErr generated by the dependencies and libraries.

For code, to do this, c++ on gcc uses the method freopen() from stdio.h
https://www.cplusplus.com/reference/cstdio/freopen/

Sadly, freopen() is not implemented by fpc.

So I would be very happy if somebody gives me light how to implement it.
It seems that it comes from the standard C library.

Fre;D
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

devEric69

  • Sr. Member
  • ****
  • Posts: 465
Re: freopen and fpc?
« Reply #12 on: April 24, 2021, 02:46:25 pm »
Hello @all,

Just as an anecdote, I sometimes use the tee command (available for nix* OSes), in bash scripts, which allows to redirect stdin and stdout and stderr to each others, or towards a third text file. So, wondering me how this could be written in Lazarus, I'm interested in any possible answers to this question.
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

lucamar

  • Hero Member
  • *****
  • Posts: 3859
Re: freopen and fpc?
« Reply #13 on: April 24, 2021, 03:20:52 pm »
Just as an anecdote, I sometimes use the tee command (available for nix* OSes), in bash scripts, which allows to redirect stdin and stdout and stderr to each others, or towards a third text file. So, wondering me how this could be written in Lazarus, I'm interested in any possible answers to this question.

That's relatively easy. Open two streams, one for whatever you want to redirect  and another for the file, and write the same to both streams.

Just a small correction: what the standard tee does is to read stdin and write to both stdout and a file. Basically something like:

Code: Pascal  [Select][+][-]
  1. while not eof(Input) do begin
  2.   ReadLn(whatever); {or: Read(somestring)}
  3.   WriteLn(whatever); {or: Write(somestring)}
  4.   WriteLn(AFile, whatever); {or: Write(AFile, somestring);}
  5. end;

Any other "redirection" is done by the shell itself, which is an expert on that ;)

That's why tee is most often used as:
Code: Bash  [Select][+][-]
  1. somecommand | tee somefile.log
« Last Edit: April 24, 2021, 03:22:59 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Warfley

  • Sr. Member
  • ****
  • Posts: 446
Re: freopen and fpc?
« Reply #14 on: April 24, 2021, 05:19:51 pm »
I think the problem is the following, when using Assign, AssignFile or AssignStream, what happens is that the handling of the "Text" object in pascal is changed. The problem is that the other code seems to send the data to stderr not via the pascal Text object, but rather via the filedescriptor and the operating system commands (e.g. fwrite on posix), thereby circumventing the Text handler completely.

So to target this problem you need to change the file handling on the OS level. I don't know much about the windows API with regards to this topic, but on POSIX systems you have the dup2 command available: Link. dup2 can be thought of as a form of redirect meaning dup2(filedescriptor, stderr) will make every write to stderr be a write to the same file as filedescriptor.

So you can try out something like this:
Code: Pascal  [Select][+][-]
  1. uses BaseUnix;
  2. ...
  3. var errFileHandle: Integer;
  4.  
  5. function MapStdErrToFile(const FileName: String): Boolean;
  6. begin
  7.   errFileHandle := FpOpen(FileName, O_Creat, O_WrOnly);
  8.   Result := FpDup2(errFileHandle, StdErrorHandle) >= 0;
  9. end;

 

TinyPortal © 2005-2018