[67300de] | 1 | Submitted By: LFS Book <lfs-book@linuxfromscratch.org>
|
---|
| 2 | Date: 2005-02-27 (originally submitted 2003-10-05)
|
---|
| 3 | Initial Package Version: 5.38
|
---|
| 4 | Origin: Redhat RPM (Patch by HJ Lu); rediffed by Randy McMurchy
|
---|
| 5 | Description: NA
|
---|
| 6 |
|
---|
| 7 | $LastChangedBy: randy $
|
---|
| 8 | $Date: 2005-03-24 21:05:48 -0700 (Thu, 24 Mar 2005) $
|
---|
| 9 |
|
---|
| 10 | diff -Naur expect-5.43-orig/exp_chan.c expect-5.43/exp_chan.c
|
---|
| 11 | --- expect-5.43-orig/exp_chan.c 2005-02-08 02:01:20.000000000 +0000
|
---|
| 12 | +++ expect-5.43/exp_chan.c 2005-02-27 15:09:29.270201960 +0000
|
---|
| 13 | @@ -622,6 +622,7 @@
|
---|
| 14 | esPtr->buffer = Tcl_NewStringObj("",0);
|
---|
| 15 | Tcl_IncrRefCount(esPtr->buffer);
|
---|
| 16 | esPtr->umsize = exp_default_match_max;
|
---|
| 17 | + esPtr->umsize_changed = exp_default_match_max_changed;
|
---|
| 18 | /* this will reallocate object with an appropriate sized buffer */
|
---|
| 19 | expAdjust(esPtr);
|
---|
| 20 |
|
---|
| 21 | diff -Naur expect-5.43-orig/exp_command.h expect-5.43/exp_command.h
|
---|
| 22 | --- expect-5.43-orig/exp_command.h 2004-07-30 15:35:28.000000000 +0000
|
---|
| 23 | +++ expect-5.43/exp_command.h 2005-02-27 15:09:29.272201656 +0000
|
---|
| 24 | @@ -30,6 +30,7 @@
|
---|
| 25 | EXTERN char * exp_get_var _ANSI_ARGS_((Tcl_Interp *,char *));
|
---|
| 26 |
|
---|
| 27 | EXTERN int exp_default_match_max;
|
---|
| 28 | +EXTERN int exp_default_match_max_changed;
|
---|
| 29 | EXTERN int exp_default_parity;
|
---|
| 30 | EXTERN int exp_default_rm_nulls;
|
---|
| 31 | EXTERN int exp_default_close_on_eof;
|
---|
| 32 | @@ -103,6 +104,7 @@
|
---|
| 33 | int msize; /* # of bytes that buffer can hold (max) */
|
---|
| 34 | int umsize; /* # of bytes (min) that is guaranteed to match */
|
---|
| 35 | /* this comes from match_max command */
|
---|
| 36 | + int umsize_changed; /* is umsize changed by user? */
|
---|
| 37 | int printed; /* # of bytes written to stdout (if logging on) */
|
---|
| 38 | /* but not actually returned via a match yet */
|
---|
| 39 | int echoed; /* additional # of bytes (beyond "printed" above) */
|
---|
| 40 | diff -Naur expect-5.43-orig/expect.c expect-5.43/expect.c
|
---|
| 41 | --- expect-5.43-orig/expect.c 2004-07-06 23:26:02.000000000 +0000
|
---|
| 42 | +++ expect-5.43/expect.c 2005-02-27 15:09:29.279200592 +0000
|
---|
| 43 | @@ -41,8 +41,17 @@
|
---|
| 44 | #include "tcldbg.h"
|
---|
| 45 | #endif
|
---|
| 46 |
|
---|
| 47 | +/* The initial length is 2000. We increment it by 2000. The maximum
|
---|
| 48 | + is 8MB (0x800000). */
|
---|
| 49 | +#define EXP_MATCH_MAX 2000
|
---|
| 50 | +#define EXP_MATCH_INC 2000
|
---|
| 51 | +#define EXP_MATCH_STEP_LIMIT 0x700000
|
---|
| 52 | +#define EXP_MATCH_LIMIT 0x800000
|
---|
| 53 | +#define EXP_MATCH_LIMIT_QUOTE "0x800000"
|
---|
| 54 | +
|
---|
| 55 | /* initial length of strings that we can guarantee patterns can match */
|
---|
| 56 | -int exp_default_match_max = 2000;
|
---|
| 57 | +int exp_default_match_max = EXP_MATCH_MAX;
|
---|
| 58 | +int exp_default_match_max_changed = 0;
|
---|
| 59 | #define INIT_EXPECT_TIMEOUT_LIT "10" /* seconds */
|
---|
| 60 | #define INIT_EXPECT_TIMEOUT 10 /* seconds */
|
---|
| 61 | int exp_default_parity = TRUE;
|
---|
| 62 | @@ -1619,6 +1628,76 @@
|
---|
| 63 | return newsize;
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | +/* returns # of bytes until we see a newline at the end or EOF. */
|
---|
| 67 | +/*ARGSUSED*/
|
---|
| 68 | +static int
|
---|
| 69 | +expReadNewLine(interp,esPtr,save_flags) /* INTL */
|
---|
| 70 | +Tcl_Interp *interp;
|
---|
| 71 | +ExpState *esPtr;
|
---|
| 72 | +int save_flags;
|
---|
| 73 | +{
|
---|
| 74 | + int size;
|
---|
| 75 | + int exp_size;
|
---|
| 76 | + int full_size;
|
---|
| 77 | + int count;
|
---|
| 78 | + char *str;
|
---|
| 79 | +
|
---|
| 80 | + count = 0;
|
---|
| 81 | + for (;;) {
|
---|
| 82 | + exp_size = expSizeGet(esPtr);
|
---|
| 83 | +
|
---|
| 84 | + /* When we reach the limit, we will only read one char at a
|
---|
| 85 | + time. */
|
---|
| 86 | + if (esPtr->umsize >= EXP_MATCH_STEP_LIMIT)
|
---|
| 87 | + size = TCL_UTF_MAX;
|
---|
| 88 | + else
|
---|
| 89 | + size = exp_size;
|
---|
| 90 | +
|
---|
| 91 | + if (exp_size + TCL_UTF_MAX >= esPtr->msize) {
|
---|
| 92 | + if (esPtr->umsize >= EXP_MATCH_LIMIT) {
|
---|
| 93 | + expDiagLogU("WARNING: interact buffer is full. probably your program\r\n");
|
---|
| 94 | + expDiagLogU("is not interactive or has a very long output line. The\r\n");
|
---|
| 95 | + expDiagLogU("current limit is " EXP_MATCH_LIMIT_QUOTE ".\r\n");
|
---|
| 96 | + expDiagLogU("Dumping first half of buffer in order to continue\r\n");
|
---|
| 97 | + expDiagLogU("Recommend you enlarge the buffer.\r\n");
|
---|
| 98 | + exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect");
|
---|
| 99 | + return count;
|
---|
| 100 | + }
|
---|
| 101 | + else {
|
---|
| 102 | + esPtr->umsize += EXP_MATCH_INC;
|
---|
| 103 | + expAdjust(esPtr);
|
---|
| 104 | + }
|
---|
| 105 | + }
|
---|
| 106 | +
|
---|
| 107 | + full_size = esPtr->msize - (size / TCL_UTF_MAX);
|
---|
| 108 | + size = Tcl_ReadChars(esPtr->channel,
|
---|
| 109 | + esPtr->buffer,
|
---|
| 110 | + full_size,
|
---|
| 111 | + 1 /* append */);
|
---|
| 112 | + if (size > 0) {
|
---|
| 113 | + count += size;
|
---|
| 114 | + /* We try again if there are more to read and we haven't
|
---|
| 115 | + seen a newline at the end. */
|
---|
| 116 | + if (size == full_size) {
|
---|
| 117 | + str = Tcl_GetStringFromObj(esPtr->buffer, &size);
|
---|
| 118 | + if (str[size - 1] != '\n')
|
---|
| 119 | + continue;
|
---|
| 120 | + }
|
---|
| 121 | + }
|
---|
| 122 | + else {
|
---|
| 123 | + /* It is even trickier. We got an error from read. We have
|
---|
| 124 | + to recover from it. Let's make sure the size of
|
---|
| 125 | + buffer is correct. It can be corrupted. */
|
---|
| 126 | + str = Tcl_GetString(esPtr->buffer);
|
---|
| 127 | + Tcl_SetObjLength(esPtr->buffer, strlen(str));
|
---|
| 128 | + }
|
---|
| 129 | +
|
---|
| 130 | + break;
|
---|
| 131 | + }
|
---|
| 132 | +
|
---|
| 133 | + return count;
|
---|
| 134 | +}
|
---|
| 135 | +
|
---|
| 136 | /* returns # of bytes read or (non-positive) error of form EXP_XXX */
|
---|
| 137 | /* returns 0 for end of file */
|
---|
| 138 | /* If timeout is non-zero, set an alarm before doing the read, else assume */
|
---|
| 139 | @@ -1633,6 +1712,8 @@
|
---|
| 140 | {
|
---|
| 141 | int cc = EXP_TIMEOUT;
|
---|
| 142 | int size = expSizeGet(esPtr);
|
---|
| 143 | + int full_size;
|
---|
| 144 | + int count;
|
---|
| 145 |
|
---|
| 146 | if (size + TCL_UTF_MAX >= esPtr->msize)
|
---|
| 147 | exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect");
|
---|
| 148 | @@ -1649,11 +1730,43 @@
|
---|
| 149 | }
|
---|
| 150 | #endif
|
---|
| 151 |
|
---|
| 152 | -
|
---|
| 153 | + /* FIXME: If we ask less than what is available in the tcl buffer
|
---|
| 154 | + when tcl has seen EOF, we will throw away the remaining data
|
---|
| 155 | + since the next read will get EOF. Since expect is line-oriented,
|
---|
| 156 | + we exand our buffer to get EOF or the next newline at the end of
|
---|
| 157 | + the input buffer. I don't know if it is the right fix. H.J. */
|
---|
| 158 | + count = 0;
|
---|
| 159 | + full_size = esPtr->msize - (size / TCL_UTF_MAX);
|
---|
| 160 | cc = Tcl_ReadChars(esPtr->channel,
|
---|
| 161 | - esPtr->buffer,
|
---|
| 162 | - esPtr->msize - (size / TCL_UTF_MAX),
|
---|
| 163 | - 1 /* append */);
|
---|
| 164 | + esPtr->buffer,
|
---|
| 165 | + full_size,
|
---|
| 166 | + 1 /* append */);
|
---|
| 167 | + if (cc > 0) {
|
---|
| 168 | + count += cc;
|
---|
| 169 | + /* It gets very tricky. There are more to read. We will expand
|
---|
| 170 | + our buffer and get EOF or a newline at the end unless the
|
---|
| 171 | + buffer length has been changed. */
|
---|
| 172 | + if (cc == full_size) {
|
---|
| 173 | + char *str;
|
---|
| 174 | + str = Tcl_GetStringFromObj(esPtr->buffer, &size);
|
---|
| 175 | + if (str[size - 1] != '\n') {
|
---|
| 176 | + if (esPtr->umsize_changed) {
|
---|
| 177 | + char buf[20]; /* big enough for 64bit int in hex. */
|
---|
| 178 | + snprintf(buf,sizeof(buf),"0x%x", esPtr->umsize);
|
---|
| 179 | + expDiagLogU("WARNING: interact buffer is not large enough to hold\r\n");
|
---|
| 180 | + expDiagLogU("all output. probably your program is not interactive or\r\n");
|
---|
| 181 | + expDiagLogU("has a very long output line. The current limit is ");
|
---|
| 182 | + expDiagLogU(buf);
|
---|
| 183 | + expDiagLogU(".\r\n");
|
---|
| 184 | + }
|
---|
| 185 | + else {
|
---|
| 186 | + cc = expReadNewLine(interp,esPtr,save_flags);
|
---|
| 187 | + if (cc > 0)
|
---|
| 188 | + count += cc;
|
---|
| 189 | + }
|
---|
| 190 | + }
|
---|
| 191 | + }
|
---|
| 192 | + }
|
---|
| 193 | i_read_errno = errno;
|
---|
| 194 |
|
---|
| 195 | #ifdef SIMPLE_EVENT
|
---|
| 196 | @@ -1674,7 +1787,7 @@
|
---|
| 197 | }
|
---|
| 198 | }
|
---|
| 199 | #endif
|
---|
| 200 | - return cc;
|
---|
| 201 | + return count > 0 ? count : cc;
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | /*
|
---|
| 205 | @@ -2751,8 +2864,14 @@
|
---|
| 206 | return(TCL_ERROR);
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 | - if (Default) exp_default_match_max = size;
|
---|
| 210 | - else esPtr->umsize = size;
|
---|
| 211 | + if (Default) {
|
---|
| 212 | + exp_default_match_max = size;
|
---|
| 213 | + exp_default_match_max_changed = 1;
|
---|
| 214 | + }
|
---|
| 215 | + else {
|
---|
| 216 | + esPtr->umsize = size;
|
---|
| 217 | + esPtr->umsize_changed = 1;
|
---|
| 218 | + }
|
---|
| 219 |
|
---|
| 220 | return(TCL_OK);
|
---|
| 221 | }
|
---|