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

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since c768003 was 69cde8d, checked in by Jim Gifford <clfs@…>, 19 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.