Commit 14dc6826 authored by Sergei Golovan's avatar Sergei Golovan Committed by Sergei Golovan

* Applied a few fixes by upstream which were included in Expect 5.45.3

    never released as a tarball (closes: #799301).
  * Bumped standards version to 3.9.6.
parent 98e3f135
expect (5.45-7) UNRELEASED; urgency=medium
expect (5.45-7) unstable; urgency=medium
* NOT RELEASED YET
* Applied a few fixes by upstream which were included in Expect 5.45.3
never released as a tarball (closes: #799301).
* Bumped standards version to 3.9.6.
-- Sergei Golovan <sgolovan@debian.org> Mon, 14 Jul 2014 11:30:48 +0400
-- Sergei Golovan <sgolovan@debian.org> Fri, 23 Oct 2015 11:27:59 +0300
expect (5.45-6) unstable; urgency=low
......
......@@ -5,7 +5,7 @@ Maintainer: Sergei Golovan <sgolovan@debian.org>
Build-Depends: debhelper (>= 9.0.0), dpkg-dev (>= 1.16.1~), autotools-dev,
autoconf, tcl8.6-dev
Build-Conflicts: autoconf2.13
Standards-Version: 3.9.5
Standards-Version: 3.9.6
Homepage: http://sourceforge.net/projects/expect/
Package: expect
......
Author: Upstream
Description: Report and fix by Mutsuhito Iikura. On finding a full buffer during
matching the sliding window mechanism slides too far, truncating
the whole buffer and preventing matches across the boundary. Fix
is shortening the slide distance (slide only one 1/3).
Last-Modified: Fri, 23 Oct 2015 11:07:19 +0300
Bug: http://sourceforge.net/p/expect/bugs/76/
--- a/expect.c
+++ b/expect.c
@@ -979,7 +979,7 @@
/* condition is (size >= max*2/3) <=> (size*3 >= max*2) */
if (((expSizeGet(esPtr)*3) >= (esPtr->input.max*2)) && (numchars > 0)) {
o->e = e;
- o->matchlen = numchars;
+ o->matchlen = numchars/3;
o->matchbuf = str;
o->esPtr = esPtr;
expDiagLogU(yes);
Author: Upstream
Description: Report and fix both by Nils Carlson.
Replaced a cc==0 check with proper Tcl_Eof() check.
Last-Modified: Fri, 23 Oct 2015 11:09:07 +0300
Bug: http://sourceforge.net/p/expect/patches/18/
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=799301
--- a/expect.c
+++ b/expect.c
@@ -1860,19 +1860,11 @@
if (cc == EXP_DATA_NEW) {
/* try to read it */
cc = expIRead(interp,esPtr,timeout,tcl_set_flags);
-
- /* the meaning of 0 from i_read means eof. Muck with it a */
- /* little, so that from now on it means "no new data arrived */
- /* but it should be looked at again anyway". */
- if (cc == 0) {
+
+ if (Tcl_Eof(esPtr->channel)) {
cc = EXP_EOF;
- } else if (cc > 0) {
- /* successfully read data */
- } else {
- /* failed to read data - some sort of error was encountered such as
- * an interrupt with that forced an error return
- */
}
+
} else if (cc == EXP_DATA_OLD) {
cc = 0;
} else if (cc == EXP_RECONFIGURE) {
Author: Upstream
Description: Combination of 3 patches for unreleased Expect 5.45.1.
1) A patch sent in by Ogawa Hirofumi. The patch fixes a problem when
talking a tty where the writer has died. Some operating systems
report the condition as EIO with nothing read, while this
actually an EOF. Without the patch the returned data is
incomplete due to the error reported immediately and dropping
data in buffers.
2) A patch by Michael Cleverly fixing a problem with the
iteration over the expect channel list where the loop code may
modify the list, breaking the iterator.
3) A patch by Michael Cleverly fixing problem with an insufficient
test for a lost channel in exp_background_channelhandler().
Last-Modified: Fri, 23 Oct 2015 11:24:33 +0300
--- a/expect.c
+++ b/expect.c
@@ -2495,8 +2495,12 @@
*/
/* First check that the esPtr is even still valid! */
- /* This ought to be sufficient. */
- if (0 == Tcl_GetChannel(interp,backup,(int *)0)) {
+ /*
+ * It isn't sufficient to just check that 'Tcl_GetChannel' still knows about
+ * backup since it is possible that esPtr was lost in the background AND
+ * another process spawned and reassigned the same name.
+ */
+ if (!expChannelStillAlive(esPtr, backup)) {
expDiagLog("expect channel %s lost in background handler\n",backup);
return;
}
--- a/exp_chan.c
+++ b/exp_chan.c
@@ -218,6 +218,11 @@
bytesRead = read(esPtr->fdin, buf, (size_t) toRead);
/*printf("ExpInputProc: read(%d,,) = %d\r\n",esPtr->fdin,bytesRead);*/
+
+ /* Emulate EOF on tty for tcl */
+ if ((bytesRead == -1) && (errno == EIO) && isatty(esPtr->fdin)) {
+ bytesRead = 0;
+ }
if (bytesRead > -1) {
/* strip parity if requested */
if (esPtr->parity == 0) {
@@ -448,6 +453,34 @@
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
return tsdPtr->channelCount;
}
+
+int
+expChannelStillAlive(esBackupPtr, backupName)
+ ExpState *esBackupPtr;
+ char *backupName;
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ ExpState *esPtr;
+
+ /*
+ * This utility function is called from 'exp_background_channelhandler'
+ * and checks to make sure that backupName can still be found in the
+ * channels linked list at the same address as before.
+ *
+ * If it can't be (or if the memory address has changed) then it
+ * means that it was lost in the background (and possibly another
+ * channel was opened and reassigned the same name).
+ */
+
+ for (esPtr = tsdPtr->firstExpPtr; esPtr; esPtr = esPtr->nextPtr) {
+ if (0 == strcmp(esPtr->name, backupName))
+ return (esPtr == esBackupPtr);
+ }
+
+ /* not found; must have been lost in the background */
+ return 0;
+}
+
#if 0 /* Converted to macros */
int
expSizeGet(esPtr)
@@ -603,12 +636,38 @@
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ExpState *esPtr;
+ ExpState *esNextPtr;
+ ExpState *esPriorPtr = 0;
/* kick off any that already have input waiting */
- for (esPtr = tsdPtr->firstExpPtr;esPtr;esPtr = esPtr->nextPtr) {
+ for (esPtr = tsdPtr->firstExpPtr;esPtr; esPriorPtr = esPtr, esPtr = esPtr->nextPtr) {
/* is bg_interp the best way to check if armed? */
if (esPtr->bg_interp && !expSizeZero(esPtr)) {
+ /*
+ * We save the nextPtr in a local variable before calling
+ * 'exp_background_channelhandler' since in some cases
+ * 'expStateFree' could end up getting called before it
+ * returns, leading to a likely segfault on the next
+ * interaction through the for loop.
+ */
+ esNextPtr = esPtr->nextPtr;
exp_background_channelhandler((ClientData)esPtr,0);
+ if (esNextPtr != esPtr->nextPtr) {
+ /*
+ * 'expStateFree' must have been called from
+ * underneath us so we know that esPtr->nextPtr is
+ * invalid. However, it is possible that either the
+ * original nextPtr and/or the priorPtr have been
+ * freed too. If the esPriorPtr->nextPtr is now
+ * esNextPtr it seems safe to proceed. Otherwise we
+ * break and end early for safety.
+ */
+ if (esPriorPtr && esPriorPtr->nextPtr == esNextPtr) {
+ esPtr = esPriorPtr;
+ } else {
+ break; /* maybe set esPtr = tsdPtr->firstExpPtr again? */
+ }
+ }
}
}
}
--- a/exp_command.h
+++ b/exp_command.h
@@ -248,6 +248,7 @@
EXTERN void exp_ecmd_remove_state_direct_and_indirect _ANSI_ARGS_((Tcl_Interp *interp,ExpState *esPtr));
EXTERN void expChannelInit _ANSI_ARGS_((void));
EXTERN int expChannelCountGet _ANSI_ARGS_((void));
+EXTERN int expChannelStillAlive _ANSI_ARGS_((ExpState *, char *));
EXTERN int exp_tcl2_returnvalue _ANSI_ARGS_((int));
EXTERN int exp_2tcl_returnvalue _ANSI_ARGS_((int));
......@@ -13,3 +13,6 @@
22-segfault-with-stubs.patch
23-memmove.patch
24-format.patch
25-matchlen.patch
26-eof-handling.patch
27-exp_chan.patch
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment