source: patches/expect-5.43.0-spawn-2.patch @ f71c005

clfs-1.2clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since f71c005 was 69cde8d, checked in by Jim Gifford <clfs@…>, 18 years ago

Added: All patches needed for the book.

  • Property mode set to 100644
File size: 6.9 KB
RevLine 
[69cde8d]1Submitted By:            LFS Book <lfs-book@linuxfromscratch.org>
2Date:                    2005-02-27 (originally submitted 2003-10-05)
3Initial Package Version: 5.38
4Origin:                  Redhat RPM (Patch by HJ Lu); rediffed by Randy McMurchy
5Description:             NA
6
7$LastChangedBy: randy $
8$Date: 2005-03-24 21:05:48 -0700 (Thu, 24 Mar 2005) $
9
10diff -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 
21diff -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) */
40diff -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 }
Note: See TracBrowser for help on using the repository browser.