svn commit: [25698] trunk/busybox/miscutils

vda at busybox.net vda at busybox.net
Mon Mar 16 23:06:23 UTC 2009


Author: vda
Date: 2009-03-16 23:06:23 +0000 (Mon, 16 Mar 2009)
New Revision: 25698

Log:
chat: update by Vladimir
 1) to treat timeout more correctly (timeout affects whole send command
    duration, not a single char); 
 2) to recognize RECORD directive.

function                                             old     new   delta
chat_main                                           1246    1359    +113
exitcode                                               1       -      -1



Modified:
   trunk/busybox/miscutils/chat.c


Changeset:
Modified: trunk/busybox/miscutils/chat.c
===================================================================
--- trunk/busybox/miscutils/chat.c	2009-03-16 22:18:05 UTC (rev 25697)
+++ trunk/busybox/miscutils/chat.c	2009-03-16 23:06:23 UTC (rev 25698)
@@ -9,16 +9,6 @@
  */
 #include "libbb.h"
 
-/*
-#define ENABLE_FEATURE_CHAT_NOFAIL              1 // +126 bytes
-#define ENABLE_FEATURE_CHAT_TTY_HIFI            0 // + 70 bytes
-#define ENABLE_FEATURE_CHAT_IMPLICIT_CR         1 // + 44 bytes
-#define ENABLE_FEATURE_CHAT_SEND_ESCAPES        0 // +103 bytes
-#define ENABLE_FEATURE_CHAT_VAR_ABORT_LEN       0 // + 70 bytes
-#define ENABLE_FEATURE_CHAT_CLR_ABORT           0 // +113 bytes
-#define ENABLE_FEATURE_CHAT_SWALLOW_OPTS        0 // + 23 bytes
-*/
-
 // default timeout: 45 sec
 #define	DEFAULT_CHAT_TIMEOUT 45*1000
 // max length of "abort string",
@@ -37,8 +27,7 @@
 };
 
 // exit code
-// N.B> 10 bytes for volatile. Why all these signals?!
-static /*volatile*/ smallint exitcode;
+#define exitcode bb_got_signal
 
 // trap for critical signals
 static void signal_handler(UNUSED_PARAM int signo)
@@ -101,13 +90,10 @@
 	return p - start;
 }
 
-
 int chat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int chat_main(int argc UNUSED_PARAM, char **argv)
 {
-// should we dump device output? to what fd? by default no.
-// this can be controlled later via ECHO {ON|OFF} chat directive
-//	int echo_fd;
+	int record_fd = -1;
 	bool echo = 0;
 	// collection of device replies which cause unconditional termination
 	llist_t *aborts = NULL;
@@ -132,6 +118,7 @@
 		DIR_TIMEOUT,
 		DIR_ECHO,
 		DIR_SAY,
+		DIR_RECORD,
 	};
 
 	// make x* functions fail with correct exitcode
@@ -166,14 +153,14 @@
 #if ENABLE_FEATURE_CHAT_CLR_ABORT
 			"CLR_ABORT\0"
 #endif
-			"TIMEOUT\0" "ECHO\0" "SAY\0"
+			"TIMEOUT\0" "ECHO\0" "SAY\0" "RECORD\0"
 			, *argv
 		);
 		if (key >= 0) {
 			// cache directive value
 			char *arg = *++argv;
-			// ON -> 1, anything else -> 0
-			bool onoff = !strcmp("ON", arg);
+			// OFF -> 0, anything else -> 1
+			bool onoff = (0 != strcmp("OFF", arg));
 			// process directive
 			if (DIR_HANGUP == key) {
 				// turn SIGHUP on/off
@@ -217,14 +204,20 @@
 					timeout = DEFAULT_CHAT_TIMEOUT;
 			} else if (DIR_ECHO == key) {
 				// turn echo on/off
-				// N.B. echo means dumping output
-				// from stdin (device) to stderr
+				// N.B. echo means dumping device input/output to stderr
 				echo = onoff;
-//TODO?				echo_fd = onoff * STDERR_FILENO;
-//TODO?				echo_fd = xopen(arg, O_WRONLY|O_CREAT|O_TRUNC);
+			} else if (DIR_RECORD == key) {
+				// turn record on/off
+				// N.B. record means dumping device input to a file
+					// close previous record_fd
+				if (record_fd > 0)
+					close(record_fd);
+				// N.B. do we have to die here on open error?
+				record_fd = (onoff) ? xopen(arg, O_WRONLY|O_CREAT|O_TRUNC) : -1;
 			} else if (DIR_SAY == key) {
 				// just print argument verbatim
-				fprintf(stderr, arg);
+				// TODO: should we use full_write() to avoid unistd/stdio conflict?
+				bb_error_msg("%s", arg);
 			}
 			// next, please!
 			argv++;
@@ -288,12 +281,18 @@
 
 				// read next char from device
 				if (safe_read(STDIN_FILENO, buf+buf_len, 1) > 0) {
-					// dump device output if ECHO ON or RECORD fname
-//TODO?					if (echo_fd > 0) {
-//TODO?						full_write(echo_fd, buf+buf_len, 1);
-//TODO?					}
-					if (echo > 0)
+					// dump device input if RECORD fname
+					if (record_fd > 0) {
+						full_write(record_fd, buf+buf_len, 1);
+					}
+					// dump device input if ECHO ON
+					if (echo > 0) {
+//						if (buf[buf_len] < ' ') {
+//							full_write(STDERR_FILENO, "^", 1);
+//							buf[buf_len] += '@';
+//						}
 						full_write(STDERR_FILENO, buf+buf_len, 1);
+					}
 					buf_len++;
 					// move input frame if we've reached higher bound
 					if (buf_len > COMMON_BUFSIZE) {
@@ -320,7 +319,7 @@
 				if (delta >= 0 && !memcmp(buf+delta, expect, expect_len))
 					goto expect_done;
 #undef buf
-			}
+			} /* while (have data) */
 
 			// device timed out or unexpected reply received
 			exitcode = ERR_TIMEOUT;
@@ -365,21 +364,18 @@
 					trim(++buf);
 					buf = loaded = xmalloc_xopen_read_close(buf, NULL);
 				}
-
 				// expand escape sequences in command
 				len = unescape(buf, &nocr);
 
 				// send command
-#if ENABLE_FEATURE_CHAT_SEND_ESCAPES
+				alarm(timeout);
 				pfd.fd = STDOUT_FILENO;
 				pfd.events = POLLOUT;
 				while (len && !exitcode
-				    && poll(&pfd, 1, timeout) > 0
+				    && poll(&pfd, 1, -1) > 0
 				    && (pfd.revents & POLLOUT)
 				) {
-					// ugly! ugly! ugly!
-					// gotta send char by char to achieve this!
-					// Brrr...
+#if ENABLE_FEATURE_CHAT_SEND_ESCAPES
 					// "\\d" means 1 sec delay, "\\p" means 0.01 sec delay
 					// "\\K" means send BREAK
 					char c = *buf;
@@ -389,31 +385,28 @@
 							sleep(1);
 							len--;
 							continue;
-						} else if ('p' == c) {
+						}
+						if ('p' == c) {
 							usleep(10000);
 							len--;
 							continue;
-						} else if ('K' == c) {
+						}
+						if ('K' == c) {
 							tcsendbreak(STDOUT_FILENO, 0);
 							len--;
 							continue;
-						} else {
-							buf--;
 						}
+						buf--;
 					}
-					if (safe_write(STDOUT_FILENO, buf, 1) > 0) {
-						len--;
-						buf++;
-					} else
+					if (safe_write(STDOUT_FILENO, buf, 1) != 1)
 						break;
-				}
+					len--;
+					buf++;
 #else
-//				if (len) {
-					alarm(timeout);
 					len -= full_write(STDOUT_FILENO, buf, len);
-					alarm(0);
-//				}
 #endif
+				} /* while (can write) */
+				alarm(0);
 
 				// report I/O error if there still exists at least one non-sent char
 				if (len)
@@ -427,14 +420,12 @@
 				else if (!nocr)
 					xwrite(STDOUT_FILENO, "\r", 1);
 #endif
-
 				// bail out unless we sent command successfully
 				if (exitcode)
 					break;
-
-			}
+			} /* if (*argv) */
 		}
-	}
+	} /* while (*argv) */
 
 #if ENABLE_FEATURE_CHAT_TTY_HIFI
 	tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio0);



More information about the busybox-cvs mailing list