Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On 2020-07-10 07:45, Bo Berglund via fpc-pascal wrote: On Fri, 10 Jul 2020 01:26:24 +0200, Tomas Hajny wrote: Well I do not believe the problem I am seeing is because of thread safe or not. This test server is just running the main thread (the program itself) where the detection of keyboard entry q is in a loop to make it possible to end execution in a controlled way. Nothing is output to the console from this loop when the server is running, only after it is commanded to shut down following detection of q. Additionally the TIdTCPServer is created and started prior to getting to the loop. This is for sure multi-threaded but by itself does not interact with the console. If you want others to check the real reason, you should provide your compilable source so that others may try to reproduce and analyze the problem. Obviously, there may be other issues as well like particular setting of your terminal, etc. . . Instead I think that this what you mention here is the real culprit. So Crt changes the way the console displays data on the screen as you describe and this screen position access is probably what I see as the messages from inside the server being output without the CR only using LF when executing the Writeln() command. That could be, but please note that Crt.WriteLn has been used many times without issues by others, so if it doesn't work correctly in your case, it is probably related either to other parts of your program, or to particular settings and/or features of your terminal. I posted here because I thought I had discovered a bug or that I had somehow mis-interpreted the way Writeln() works and could get an immediate advice concerning the cause of the problem. It is not that important since this is just a test program evaluating the TCP server class I am building. It would just be more convenient to stop the application using a single keypress than two, but ths only happens while I am testing. So by removing the loop, I can just hit Enter and it shuts down: . . Here I use the blocking Read(ch) instead and now Enter makes the code move on to the termination phase. It will not be used at all in the production program... Fine. I provided an alternative solution for checking a single keypress without using unit Crt, but it's obviously up to you whether you want or need to use it. BTW, both Crt.ReadKey and Keyboard.GetKeyEvent are blocking as well, but both Crt and Keyboard provide ways for non-blocking access as well (Crt.KeyPressed and Keyboard.PollKeyEvent). But I really asked about the *difference* between Windows and Linux behaviour because on Windows the original code works fine without any screen mess. The difference comes from different features and behaviour of console in Windows and Linux (especially from the lack of API access to more advanced features of the console - which, to be fair, is mostly due to the need to provide universal remote access to the console / terminal in the Unix world, which is not supported in the Windows world). Tomas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Fri, 10 Jul 2020, Bo Berglund via fpc-pascal wrote: On Fri, 10 Jul 2020 01:26:24 +0200, Tomas Hajny wrote: Here I use the blocking Read(ch) instead and now Enter makes the code move on to the termination phase. It will not be used at all in the production program... But I really asked about the *difference* between Windows and Linux behaviour because on Windows the original code works fine without any screen mess. The crt unit has been in use for 25 years. It behaves as expected. However, times change, terminals too, so who knows. Before answering to you I wrote a small program that does what you do. Write to screen, wait for keypress. Write again to screen. It behaves as expected: the next line is written flushed-left. The only difference with your program is that mine does not use threads which also write to screen. So the hypothesis that it is the threads that are messing up the terminal. It can also be that Indy messes up the terminal but I consider this less likely. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Fri, 10 Jul 2020 01:26:24 +0200, Tomas Hajny wrote: Well I do not believe the problem I am seeing is because of thread safe or not. This test server is just running the main thread (the program itself) where the detection of keyboard entry q is in a loop to make it possible to end execution in a controlled way. Nothing is output to the console from this loop when the server is running, only after it is commanded to shut down following detection of q. Additionally the TIdTCPServer is created and started prior to getting to the loop. This is for sure multi-threaded but by itself does not interact with the console. And I am using a TCP client application to connect to the TCP server and it will send one message at a time to the server when connecting in order to read back the state information for display. This is done sequentially in a single thread on the client, so messages arrive in an orderly fashion. >The point is that unit Keyboard makes no changes to the console output >(unlike unit Crt). Unit Crt provides special features allowing to >perform output at a particular position of the console (which makes it >less reliable in multi-threaded scenarios). Without this unit, standard >simple I/O is used. No, it isn't guaranteed to be thread-safe per se, >you should make sure to wait for finishing output from the first thread >before you start writing in another, that's your responsibility, but >there are ways for achieving that (as mentioned earlier in this thread). Instead I think that this what you mention here is the real culprit. So Crt changes the way the console displays data on the screen as you describe and this screen position access is probably what I see as the messages from inside the server being output without the CR only using LF when executing the Writeln() command. I posted here because I thought I had discovered a bug or that I had somehow mis-interpreted the way Writeln() works and could get an immediate advice concerning the cause of the problem. It is not that important since this is just a test program evaluating the TCP server class I am building. It would just be more convenient to stop the application using a single keypress than two, but ths only happens while I am testing. So by removing the loop, I can just hit Enter and it shuts down: Writeln('Server running, hit Enter to exit!'); //repeat Read(ch); //until ch='q'; {q} Writeln('Shutting down server'); Here I use the blocking Read(ch) instead and now Enter makes the code move on to the termination phase. It will not be used at all in the production program... But I really asked about the *difference* between Windows and Linux behaviour because on Windows the original code works fine without any screen mess. -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On 2020-07-10 01:05, Travis Siegel wrote: On 7/9/2020 5:11 PM, Tomas Hajny wrote: On 2020-07-09 22:58, Michael Van Canneyt wrote: On Thu, 9 Jul 2020, Bo Berglund via fpc-pascal wrote: On Thu, 9 Jul 2020 19:36:31 +0200 (CEST), Michael Van Canneyt wrote: Is this done in a thread ? Since you're using indy, I suppose so. The crt unit is not thread safe. The implementation on Windows and Linux is totally different, which may explain the difference you see. Is there a way to check user keyboard input in the main program while action is being done in the server's threads? Sure, do a fpselect() on file descriptor 0. You can use the unit Keyboard as well, which is cross-platform. cross platform doesn't mean thread safe, which is the primary reason for *not* using crt unit. I have no idea if keyboard is thread safe or not, and I've not seen anything in this discussion to answer that question either. The point is that unit Keyboard makes no changes to the console output (unlike unit Crt). Unit Crt provides special features allowing to perform output at a particular position of the console (which makes it less reliable in multi-threaded scenarios). Without this unit, standard simple I/O is used. No, it isn't guaranteed to be thread-safe per se, you should make sure to wait for finishing output from the first thread before you start writing in another, that's your responsibility, but there are ways for achieving that (as mentioned earlier in this thread). Is there sample code of server code so testing can be performed outside the discussion parameters? I have looked for years for client/server information for freepascal, and never found anything, then this discussion shows some code for running a server, where did that information come from? I'm apparently really bad on searching for said information. I'm not sure how we got from a multi-threaded application to client/server, but there are certainly examples of using FPC for both client and server in our SVN (see e.g. packages/fcl-net/examples/ and packages/fcl-web/examples/). Toams ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On 7/9/2020 5:11 PM, Tomas Hajny wrote: On 2020-07-09 22:58, Michael Van Canneyt wrote: On Thu, 9 Jul 2020, Bo Berglund via fpc-pascal wrote: On Thu, 9 Jul 2020 19:36:31 +0200 (CEST), Michael Van Canneyt wrote: Is this done in a thread ? Since you're using indy, I suppose so. The crt unit is not thread safe. The implementation on Windows and Linux is totally different, which may explain the difference you see. Is there a way to check user keyboard input in the main program while action is being done in the server's threads? Sure, do a fpselect() on file descriptor 0. You can use the unit Keyboard as well, which is cross-platform. cross platform doesn't mean thread safe, which is the primary reason for *not* using crt unit. I have no idea if keyboard is thread safe or not, and I've not seen anything in this discussion to answer that question either. Is there sample code of server code so testing can be performed outside the discussion parameters? I have looked for years for client/server information for freepascal, and never found anything, then this discussion shows some code for running a server, where did that information come from? I'm apparently really bad on searching for said information. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On 2020-07-10 00:40, Bo Berglund via fpc-pascal wrote: On Thu, 09 Jul 2020 23:11:34 +0200, Tomas Hajny wrote: You can use the unit Keyboard as well, which is cross-platform. I did as follows: uses ... Keyboard, ... begin ... repeat //ch := ReadKey; //ReadKey is not supported by Keyboard... Read(ch); until ch='q'; {q} ... end. You added unit Keyboard to the uses clause, but you don't use it. ;-) Now what happened is that the display is back to normal without these missing carriage returns. But I also must hit Enter after using the q key in order for the loop to break. So Crt was the culprit for the messed up Writeln() output, but replacing it with Keyboard brought back the old keyboard read behaviour. Removing Keyboard and Crt from uses does not change anything, but the display now is sensible at least. So Keyboard is not needed it seems. At least it does not add anything in this program. So I will have to live with q to break the loop... Not necessarily. uses Keyboard; var K: TKeyEvent; begin InitKeyboard; while char (TKeyRecord (K).KeyCode) <> 'q' do begin WriteLn (char (TKeyRecord (K).KeyCode)); K := GetKeyEvent; end; DoneKeyboard; end. = The above is just a dirty hack without handling the pressed keys properly, but it hopefully shows the basics. Tomas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Thu, 09 Jul 2020 23:11:34 +0200, Tomas Hajny wrote: >You can use the unit Keyboard as well, which is cross-platform. I did as follows: uses ... Keyboard, ... begin ... repeat //ch := ReadKey; //ReadKey is not supported by Keyboard... Read(ch); until ch='q'; {q} ... end. Now what happened is that the display is back to normal without these missing carriage returns. But I also must hit Enter after using the q key in order for the loop to break. So Crt was the culprit for the messed up Writeln() output, but replacing it with Keyboard brought back the old keyboard read behaviour. Removing Keyboard and Crt from uses does not change anything, but the display now is sensible at least. So Keyboard is not needed it seems. At least it does not add anything in this program. So I will have to live with q to break the loop... -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
Am 09.07.2020 um 18:42 schrieb Bo Berglund via fpc-pascal: On Thu, 9 Jul 2020 16:25:50 +, Alexander Grotewohl wrote: it sounds like your terminal has gotten fudged somehow I am using crt in the lpr file just for the sake of being able to shut it down sensibly: It doesn't matter where the CRT unit is used. It hooks globally for the whole program. try RemoteSrv.ClientPort := 23500; //Set port explicitly Logger.StdLog('Starting remote server on port: ' + IntToStr(RemoteSrv.ClientPort)); Writeln('Starting remote server on port: ' + IntToStr(RemoteSrv.ClientPort)); RemoteSrv.StartServer; Writeln('Server running, hit q to exit!'); repeat ch := ReadKey; <== NEEDS unit crt to read the keypress until ch='q'; {q} Writeln('Shutting down server'); Logger.StdLog('Shutting down server'); RemoteSrv.StopServer; finally RemoteSrv.Free; end; Writeln('Terminating program'); The messages put out from this code are all left aligned. From then on the messages are stacked sideways but on a new line. So when the server (it is a TCP/IP socket server) gets a client call this is written in the console by the writeln() executed inside the handler as I showed in my start message. I have tried the Linux terminal on Raspbian Buster and from Windows PuTTY, both show the same strange behaviour. If I run the program on Windows this does not happen (same code just compiled on Windows or Linux). You could try to use CheckSynchronize(SomeLowTimeout) inside the main loop (together with KeyPressed before using ReadKey) and then do your other output in the Indy event handlers using TThread.Synchronize or TThread.Queue. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On 2020-07-09 22:58, Michael Van Canneyt wrote: On Thu, 9 Jul 2020, Bo Berglund via fpc-pascal wrote: On Thu, 9 Jul 2020 19:36:31 +0200 (CEST), Michael Van Canneyt wrote: Is this done in a thread ? Since you're using indy, I suppose so. The crt unit is not thread safe. The implementation on Windows and Linux is totally different, which may explain the difference you see. Is there a way to check user keyboard input in the main program while action is being done in the server's threads? Sure, do a fpselect() on file descriptor 0. You can use the unit Keyboard as well, which is cross-platform. Tomas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Thu, 9 Jul 2020, Bo Berglund via fpc-pascal wrote: On Thu, 9 Jul 2020 19:36:31 +0200 (CEST), Michael Van Canneyt wrote: Is this done in a thread ? Since you're using indy, I suppose so. The crt unit is not thread safe. The implementation on Windows and Linux is totally different, which may explain the difference you see. Is there a way to check user keyboard input in the main program while action is being done in the server's threads? Sure, do a fpselect() on file descriptor 0. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Thu, 9 Jul 2020 19:36:31 +0200 (CEST), Michael Van Canneyt wrote: >Is this done in a thread ? Since you're using indy, I suppose so. > >The crt unit is not thread safe. The implementation on Windows and Linux is >totally different, which may explain the difference you see. Is there a way to check user keyboard input in the main program while action is being done in the server's threads? The code I first tried did not need to use crt: repeat Read(ch); until (ch='q'); But it acts like Readln(), in that it requires the user to press 'q' followed by ENTER in order for the loop to break. Then I used this but it needs the crt unit: repeat ch := ReadKey; until ch='q'; {q} and now the user just needs to hit q without any follow-up ENTER. -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Thu, 09 Jul 2020 21:13:38 +0200, Rainer Stratmann wrote: >I had exactly the same behaviour. > >Some setterm commands solved it, if I remember correct. > >setterm -blank 0 Response was: setterm: terminal xterm-256color does not support --blank >setterm -powersave off Power save is not involved here... >I guess it was the first command. >You can try it. -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
I had exactly the same behaviour. Some setterm commands solved it, if I remember correct. setterm -blank 0 setterm -powersave off I guess it was the first command. You can try it. Am Donnerstag, 9. Juli 2020, 18:01:42 CEST schrieb Bo Berglund via fpc-pascal: > I am writing a cross-platform program (console program, no GUI). > I am using Lazarus 2.0.8 and FPC 3.0.4 on both Linux and Windows. > > During sebugging I have put numerous writeln commands in the code to > track what is happening. > I started on Windows and all worked just fine according to > expectations. > Every new output generated a new line on the console with the printed > text left aligned. > > But then I moved the code over to Linux (Raspbian Buster) and > strangely this happens: > > Test line 1 >Test line 2 > Test line 3 > > and so on. > It looks exactly the same if I use a terminal window on the Linux > system itself as it does if I connect to the Linux machine using PuTTY > from Windows... > > > It seems like a writeln() in the code does actually not do a carriage > return on the console, just a linefeed so the console continues at the > column where the previous line ended. > The messages I print out are simple text strings either showing > incoming data packets or just my comment. > > Typical code: > > s := 'Status changed: ' + newstat + ' msg: ' + AStatusText; > LogStd(s); > Writeln(s); > > In the log file this obviously does not happen... > > What can cause this strange behaviour? ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Thu, 9 Jul 2020, Bo Berglund via fpc-pascal wrote: On Thu, 9 Jul 2020 16:25:50 +, Alexander Grotewohl wrote: perhaps try 'reset' or 'stty sane' in the terminal before running your program? reset in PuTTY gives me a new resized empty screen, but works exactly the same afterwards. are you using the crt or video units at all? Yes, see below. it sounds like your terminal has gotten fudged somehow I am using crt in the lpr file just for the sake of being able to shut it down sensibly: try RemoteSrv.ClientPort := 23500; //Set port explicitly Logger.StdLog('Starting remote server on port: ' + IntToStr(RemoteSrv.ClientPort)); Writeln('Starting remote server on port: ' + IntToStr(RemoteSrv.ClientPort)); RemoteSrv.StartServer; Writeln('Server running, hit q to exit!'); repeat ch := ReadKey; <== NEEDS unit crt to read the keypress until ch='q'; {q} Writeln('Shutting down server'); Logger.StdLog('Shutting down server'); RemoteSrv.StopServer; finally RemoteSrv.Free; end; Writeln('Terminating program'); The messages put out from this code are all left aligned. From then on the messages are stacked sideways but on a new line. So when the server (it is a TCP/IP socket server) gets a client call this is written in the console by the writeln() executed inside the handler as I showed in my start message. Is this done in a thread ? Since you're using indy, I suppose so. The crt unit is not thread safe. The implementation on Windows and Linux is totally different, which may explain the difference you see. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
On Thu, 9 Jul 2020 16:25:50 +, Alexander Grotewohl wrote: >perhaps try 'reset' or 'stty sane' in the terminal before running your program? reset in PuTTY gives me a new resized empty screen, but works exactly the same afterwards. >are you using the crt or video units at all? Yes, see below. > >it sounds like your terminal has gotten fudged somehow > I am using crt in the lpr file just for the sake of being able to shut it down sensibly: try RemoteSrv.ClientPort := 23500; //Set port explicitly Logger.StdLog('Starting remote server on port: ' + IntToStr(RemoteSrv.ClientPort)); Writeln('Starting remote server on port: ' + IntToStr(RemoteSrv.ClientPort)); RemoteSrv.StartServer; Writeln('Server running, hit q to exit!'); repeat ch := ReadKey; <== NEEDS unit crt to read the keypress until ch='q'; {q} Writeln('Shutting down server'); Logger.StdLog('Shutting down server'); RemoteSrv.StopServer; finally RemoteSrv.Free; end; Writeln('Terminating program'); The messages put out from this code are all left aligned. From then on the messages are stacked sideways but on a new line. So when the server (it is a TCP/IP socket server) gets a client call this is written in the console by the writeln() executed inside the handler as I showed in my start message. I have tried the Linux terminal on Raspbian Buster and from Windows PuTTY, both show the same strange behaviour. If I run the program on Windows this does not happen (same code just compiled on Windows or Linux). -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
perhaps try 'reset' or 'stty sane' in the terminal before running your program? are you using the crt or video units at all? it sounds like your terminal has gotten fudged somehow -- Alexander Grotewohl https://dcclost.com From: fpc-pascal on behalf of Bo Berglund via fpc-pascal Sent: Thursday, July 9, 2020 12:01:42 PM To: fpc-pascal@lists.freepascal.org Cc: Bo Berglund Subject: [fpc-pascal] Writeln() behaves differently on Windows and Linux, why? I am writing a cross-platform program (console program, no GUI). I am using Lazarus 2.0.8 and FPC 3.0.4 on both Linux and Windows. During sebugging I have put numerous writeln commands in the code to track what is happening. I started on Windows and all worked just fine according to expectations. Every new output generated a new line on the console with the printed text left aligned. But then I moved the code over to Linux (Raspbian Buster) and strangely this happens: Test line 1 Test line 2 Test line 3 and so on. It looks exactly the same if I use a terminal window on the Linux system itself as it does if I connect to the Linux machine using PuTTY from Windows... It seems like a writeln() in the code does actually not do a carriage return on the console, just a linefeed so the console continues at the column where the previous line ended. The messages I print out are simple text strings either showing incoming data packets or just my comment. Typical code: s := 'Status changed: ' + newstat + ' msg: ' + AStatusText; LogStd(s); Writeln(s); In the log file this obviously does not happen... What can cause this strange behaviour? -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] Writeln() behaves differently on Windows and Linux, why?
I am writing a cross-platform program (console program, no GUI). I am using Lazarus 2.0.8 and FPC 3.0.4 on both Linux and Windows. During sebugging I have put numerous writeln commands in the code to track what is happening. I started on Windows and all worked just fine according to expectations. Every new output generated a new line on the console with the printed text left aligned. But then I moved the code over to Linux (Raspbian Buster) and strangely this happens: Test line 1 Test line 2 Test line 3 and so on. It looks exactly the same if I use a terminal window on the Linux system itself as it does if I connect to the Linux machine using PuTTY from Windows... It seems like a writeln() in the code does actually not do a carriage return on the console, just a linefeed so the console continues at the column where the previous line ended. The messages I print out are simple text strings either showing incoming data packets or just my comment. Typical code: s := 'Status changed: ' + newstat + ' msg: ' + AStatusText; LogStd(s); Writeln(s); In the log file this obviously does not happen... What can cause this strange behaviour? -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal