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

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 04ef2143 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
  • exp_chan.c

    Submitted By:            LFS Book <lfs-book@linuxfromscratch.org>
    Date:                    2005-02-27 (originally submitted 2003-10-05)
    Initial Package Version: 5.38
    Origin:                  Redhat RPM (Patch by HJ Lu); rediffed by Randy McMurchy
    Description:             NA
    
    $LastChangedBy: randy $
    $Date: 2005-03-24 21:05:48 -0700 (Thu, 24 Mar 2005) $
    
    diff -Naur expect-5.43-orig/exp_chan.c expect-5.43/exp_chan.c
    old new  
    622622    esPtr->buffer = Tcl_NewStringObj("",0);
    623623    Tcl_IncrRefCount(esPtr->buffer);
    624624    esPtr->umsize = exp_default_match_max;
     625    esPtr->umsize_changed = exp_default_match_max_changed;
    625626    /* this will reallocate object with an appropriate sized buffer */
    626627    expAdjust(esPtr);
    627628
  • exp_command.h

    diff -Naur expect-5.43-orig/exp_command.h expect-5.43/exp_command.h
    old new  
    3030EXTERN char *           exp_get_var _ANSI_ARGS_((Tcl_Interp *,char *));
    3131
    3232EXTERN int exp_default_match_max;
     33EXTERN int exp_default_match_max_changed;
    3334EXTERN int exp_default_parity;
    3435EXTERN int exp_default_rm_nulls;
    3536EXTERN int exp_default_close_on_eof;
     
    103104    int msize;          /* # of bytes that buffer can hold (max) */
    104105    int umsize;         /* # of bytes (min) that is guaranteed to match */
    105106                        /* this comes from match_max command */
     107    int umsize_changed; /* is umsize changed by user?  */
    106108    int printed;        /* # of bytes written to stdout (if logging on) */
    107109                        /* but not actually returned via a match yet */
    108110    int echoed;         /* additional # of bytes (beyond "printed" above) */
  • expect.c

    diff -Naur expect-5.43-orig/expect.c expect-5.43/expect.c
    old new  
    4141#include "tcldbg.h"
    4242#endif
    4343
     44/* The initial length is 2000. We increment it by 2000. The maximum
     45   is 8MB (0x800000).  */
     46#define EXP_MATCH_MAX           2000
     47#define EXP_MATCH_INC           2000
     48#define EXP_MATCH_STEP_LIMIT    0x700000
     49#define EXP_MATCH_LIMIT         0x800000
     50#define EXP_MATCH_LIMIT_QUOTE   "0x800000"
     51
    4452/* initial length of strings that we can guarantee patterns can match */
    45 int exp_default_match_max =     2000;
     53int exp_default_match_max =     EXP_MATCH_MAX;
     54int exp_default_match_max_changed = 0;
    4655#define INIT_EXPECT_TIMEOUT_LIT "10"    /* seconds */
    4756#define INIT_EXPECT_TIMEOUT     10      /* seconds */
    4857int exp_default_parity =        TRUE;
     
    16191628    return newsize;
    16201629}
    16211630
     1631/* returns # of bytes until we see a newline at the end or EOF.  */
     1632/*ARGSUSED*/
     1633static int
     1634expReadNewLine(interp,esPtr,save_flags) /* INTL */
     1635Tcl_Interp *interp;
     1636ExpState *esPtr;
     1637int save_flags;
     1638{
     1639    int size;
     1640    int exp_size;
     1641    int full_size;
     1642    int count;
     1643    char *str;
     1644
     1645    count = 0;
     1646    for (;;) {
     1647        exp_size = expSizeGet(esPtr);
     1648
     1649        /* When we reach the limit, we will only read one char at a
     1650           time.  */
     1651        if (esPtr->umsize >= EXP_MATCH_STEP_LIMIT)
     1652            size = TCL_UTF_MAX;
     1653        else
     1654            size = exp_size;
     1655
     1656        if (exp_size + TCL_UTF_MAX >= esPtr->msize) {
     1657            if (esPtr->umsize >= EXP_MATCH_LIMIT) {
     1658                expDiagLogU("WARNING: interact buffer is full. probably your program\r\n");
     1659                expDiagLogU("is not interactive or has a very long output line. The\r\n");
     1660                expDiagLogU("current limit is " EXP_MATCH_LIMIT_QUOTE ".\r\n");
     1661                expDiagLogU("Dumping first half of buffer in order to continue\r\n");
     1662                expDiagLogU("Recommend you enlarge the buffer.\r\n");
     1663                exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect");
     1664                return count;
     1665            }
     1666            else {
     1667                esPtr->umsize += EXP_MATCH_INC;
     1668                expAdjust(esPtr);
     1669            }
     1670        }
     1671
     1672        full_size = esPtr->msize - (size / TCL_UTF_MAX);
     1673        size = Tcl_ReadChars(esPtr->channel,
     1674                        esPtr->buffer,
     1675                        full_size,
     1676                        1 /* append */);
     1677        if (size > 0) {
     1678            count += size;
     1679            /* We try again if there are more to read and we haven't
     1680               seen a newline at the end. */
     1681            if (size == full_size) {
     1682                str = Tcl_GetStringFromObj(esPtr->buffer, &size);
     1683                if (str[size - 1] != '\n')
     1684                    continue;
     1685            }
     1686        }
     1687        else {
     1688            /* It is even trickier. We got an error from read. We have
     1689               to recover from it. Let's make sure the size of
     1690               buffer is correct. It can be corrupted. */
     1691            str = Tcl_GetString(esPtr->buffer);
     1692            Tcl_SetObjLength(esPtr->buffer, strlen(str));
     1693        }
     1694
     1695        break;
     1696    }
     1697
     1698    return count;
     1699}
     1700
    16221701/* returns # of bytes read or (non-positive) error of form EXP_XXX */
    16231702/* returns 0 for end of file */
    16241703/* If timeout is non-zero, set an alarm before doing the read, else assume */
     
    16331712{
    16341713    int cc = EXP_TIMEOUT;
    16351714    int size = expSizeGet(esPtr);
     1715    int full_size;
     1716    int count;
    16361717
    16371718    if (size + TCL_UTF_MAX >= esPtr->msize)
    16381719        exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect");
     
    16491730    }
    16501731#endif
    16511732
    1652    
     1733    /* FIXME: If we ask less than what is available in the tcl buffer
     1734       when tcl has seen EOF, we will throw away the remaining data
     1735       since the next read will get EOF. Since expect is line-oriented,
     1736       we exand our buffer to get EOF or the next newline at the end of
     1737       the input buffer. I don't know if it is the right fix.  H.J. */
     1738    count = 0;
     1739    full_size = esPtr->msize - (size / TCL_UTF_MAX);
    16531740    cc = Tcl_ReadChars(esPtr->channel,
    1654             esPtr->buffer,
    1655             esPtr->msize - (size / TCL_UTF_MAX),
    1656             1 /* append */);
     1741                esPtr->buffer,
     1742                full_size,
     1743                1 /* append */);
     1744    if (cc > 0) {
     1745        count += cc;
     1746        /* It gets very tricky. There are more to read. We will expand
     1747           our buffer and get EOF or a newline at the end unless the
     1748           buffer length has been changed.  */
     1749        if (cc == full_size) {
     1750            char *str;
     1751            str = Tcl_GetStringFromObj(esPtr->buffer, &size);
     1752            if (str[size - 1] != '\n') {
     1753                if (esPtr->umsize_changed) {
     1754                    char buf[20];       /* big enough for 64bit int in hex.  */
     1755                    snprintf(buf,sizeof(buf),"0x%x", esPtr->umsize);
     1756                    expDiagLogU("WARNING: interact buffer is not large enough to hold\r\n");
     1757                    expDiagLogU("all output. probably your program is not interactive or\r\n");
     1758                    expDiagLogU("has a very long output line. The current limit is ");
     1759                    expDiagLogU(buf);
     1760                    expDiagLogU(".\r\n");
     1761                }
     1762                else {
     1763                    cc = expReadNewLine(interp,esPtr,save_flags);
     1764                    if (cc > 0)
     1765                        count += cc;
     1766                }
     1767            }
     1768        }
     1769    }
    16571770    i_read_errno = errno;
    16581771
    16591772#ifdef SIMPLE_EVENT
     
    16741787        }
    16751788    }
    16761789#endif
    1677     return cc; 
     1790    return count > 0 ? count : cc;
    16781791}
    16791792
    16801793/*
     
    27512864        return(TCL_ERROR);
    27522865    }
    27532866
    2754     if (Default) exp_default_match_max = size;
    2755     else esPtr->umsize = size;
     2867    if (Default) {
     2868        exp_default_match_max = size;
     2869        exp_default_match_max_changed = 1;
     2870    }
     2871    else {
     2872        esPtr->umsize = size;
     2873        esPtr->umsize_changed = 1;
     2874    }
    27562875
    27572876    return(TCL_OK);
    27582877}
Note: See TracBrowser for help on using the repository browser.