0

I'm trying to write a TCL script that reads from stdin channel 1 or 2 characters from user, discarding anything other from user input without reading it. Malicious user can create a very long string to try to overflow the buffer, that's why I want to read maximum 2 characters. I understand, to do it, something like read $chan 2 and chan pending input $chan can be used together, but I cannot figure out how to do it right.

I tried read $chan 2, but if the user enters 1 character, read just reads it and a newline character as well; if user enters more than 2 characters, they are still in input, I can check for them with chan pending input $chan. I expect just to read 2 characters from the user and discard everything else.

Any suggestions? Thanks!

1 Answer 1

1

You want a non-blocking read. You do this by doing chan configure $channel -blocking 0 first. When you are doing a non-blocking read you may receive less characters than you asked for... including none at all, but you will never get more than you asked for.

Use chan event to arrange for a callback when it is likely that there is something to be read.

The chan pending command only tells you about data in Tcl's buffers, not data that the OS knows about and which hasn't been seen by the Tcl runtime yet (or that is buffered by the OS for outbound data). If you do a non-blocking read of one byte then you can use chan pending to estimate how much was also ingested at the same time.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer! It helped me to write my script. I have another question. What is more efficient: "while 1 {...}" or "while {1} {...}"? Do those extra {} around 1 improve performance?
You might try Tcl time or timerate (recommended for the newest Tcl, 9.0 already) command to test and improve the performance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.