Hi!
What do you want to achieve?
You know that there are system.StdOut, system.StdIn and system.StdErr?
writeln (StdErr,'Error 123');
Winni
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
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.
There isn't an fpreopen()
OK, so trying to focus on what I think at least one other person has missed: it's concatenating to an existing text file.
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.
Fred, just a thought: are you sure the console text you want to redirect is being sent to StdErr?
Just as an anecdote, I sometimes use the tee (https://fr.wikipedia.org/wiki/Tee_(Unix)) 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.
@Warfley: I try this:
program errorlog; ... begin Assign(StdErr, 'error.log'); Rewrite(StdErr); ... Application.run; Close(StdErr); end.
A empty error.log is created but console-messages are still there.
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 (https://www.man7.org/linux/man-pages/man2/dup.2.html). 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:
uses BaseUnix; ... var errFileHandle: Integer; function MapStdErrToFile(const FileName: String): Boolean; begin errFileHandle := FpOpen(FileName, O_Creat, O_WrOnly); Result := FpDup2(errFileHandle, StdErrorHandle) >= 0; end;
Ok, fpOpen seems to be weird, but you can use filestreams an grab the handle:
uses Classes, BaseUnix; var fs: TFileStream; begin fs := TFileStream.Create('error.txt', fmOpenReadWrite or fmCreate); try FpDup2(fs.Handle, StdErrorHandle); FpWrite(StdErrorHandle, 'Hello World'#10, 12); finally fs.Free; end; end.
Works fine on my Linux