Hi all, when looking into a bug report about a funny character device driver which is "writeonly", I found something problematic in our FreeDOS kernel sources. For more details, check the snippets of FreeDOS 2036 below, or:
http://freedos.cvs.sourceforge.net/freedos/kernel/kernel/chario.c?revision=1.37&view=markup http://freedos.cvs.sourceforge.net/freedos/kernel/kernel/break.c?revision=1.17&view=markup (kernel 2037 unstable does the same, in slightly other code) Two problems, 1. a minor one and 2. a confusing real bug: - tab expansion treats all char devices as the same device, with one global shared "current column" variable. Just a minor problem unless you mix output to, say, CON and AUX too much? - whenever you WRITE to a char device, FreeDOS tries to PEEK (non destructive read) at that device to READ whether it is trying to send ctrl-c (break) or ctrl-s (stop). In the latter case, the WRITE waits for any character READ From that device. FreeDOS also checks for ctrl-break and for ctrl-c or ctrl-s being received from the CON device. Why should FreeDOS READ from a to-be-written-to device at all? It sounds okay that it checks CON for hotkeys, but write targets can be write-only, and in the case of the ROT13DEV device driver in question, this means that you get a critical error whenever you write a byte to that char device, because FreeDOS tries to peek / read a byte from ROT13DEV before each byte it sends to the write-only ROT13DEV driver / ROT13 device. The code in question was optimized in 2032 (Bart / Arkady) but is probably much older than that. Suggested solution: check_handle_break should be called with a &syscon argument in cooked_write_char. In turn, it might be useful to call it with a pdev argument in read_char_sft_dev (why does THAT use &syscon there?). Any objections to either of the two changes? And why is the code now as it is? Current algorithm is somehow unintuitive. And maybe: Any suggestions on how to fix the tab expansion? Thanks! Eric /* writes a character in cooked mode; maybe with printer echo; handles TAB expansion */ STATIC int cooked_write_char(struct dhdr FAR **pdev, unsigned char c, unsigned char *fast_counter) ... update_scr_pos ... <-- should probably keep stdout and other dev sep- <-- arate? see also write_char_stdout, DosRWSft... ... /* if not fast then < 0x80; always check otherwise check every 32 characters */ if (*fast_counter <= 0x80 && check_handle_break(pdev) == CTL_S) /* Test for hold char and ctl_c */ raw_get_char(pdev, TRUE); <-- bad idea ... either: fast_put_char(c); ... or: err = CharIO(pdev, c, C_OUTPUT); ... ... STATIC unsigned char read_char_sft_dev(int sft_in, int sft_out, struct dhdr FAR **pdev, BOOL check_break) ... if (check_break && *pdev != syscon) check_handle_break(&syscon); <-- why not pdev? ... unsigned char check_handle_break(struct dhdr FAR **pdev) ... if !ctrl_break_pressed() then ndread(&syscon) to check for ctrl-c, if still no ctrl-c, then ndread(pdev) unless pdev==syscon, <-- bad idea if ctrl-break or ctrl-c finally found, handle_break, return the peeked char ... ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ Freedos-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/freedos-devel
