Expect

Check-in [35d0b2bdfe]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Apply patch "patch-warnings" from Mikhail T. Fixes many compiler warnings. Also do some additional cleanup of pre-ansi C function definitions and ensure build on Linux still works.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 35d0b2bdfecd634d69a3534df32ab9dc62a95ea1
User & Date: pyssling 2020-05-21 16:43:26
Context
2020-05-21
16:55
Replace CONST84 with const. CONST84 is deprecated. Reported by multiple users including Peter da Silva. check-in: 4aa905d5e2 user: pyssling tags: trunk
16:43
Apply patch "patch-warnings" from Mikhail T. Fixes many compiler warnings. Also do some additional cleanup of pre-ansi C function definitions and ensure build on Linux still works. check-in: 35d0b2bdfe user: pyssling tags: trunk
2018-02-04
13:55
Add ChangeLog for 5.45.4 release check-in: 0a2dd35d85 user: pyssling tags: trunk, expect-5-45-4
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Dbg.c.

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
...
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
654
655
656
657
658
659
660


661
662
663
664
665
666
667
...
712
713
714
715
716
717
718


719
720
721
722
723
724
725
	sprintf(name,"%d",i);
	Tcl_SetVar2Ex(interp, Dbg_VarName, name, Tcl_GetRange(objPtr,
		info.matches[i].start, info.matches[i].end-1), 0);
    }
}

/* return 1 to break, 0 to continue */
static int
breakpoint_test(interp,cmd,bp)
Tcl_Interp *interp;
char *cmd;		/* command about to be executed */
struct breakpoint *bp;	/* breakpoint to test */
{
    if (bp->re) {
        int found = 0;
	Tcl_Obj *cmdObj;
	Tcl_RegExp re = Tcl_GetRegExpFromObj(NULL, bp->pat,
		TCL_REG_ADVANCED);
	cmdObj = Tcl_NewStringObj(cmd,-1);
................................................................................
    char *string;		/* String describing frame. */
    CallFrame **framePtrPtr;	/* Store pointer to frame here (or NULL
				 * if global frame indicated). */
    enum debug_cmd dir;	/* look up or down the stack */
{
    Interp *iPtr = (Interp *) interp;
    int level, result;
    CallFrame *framePtr;	/* frame currently being searched */

    CallFrame *curFramePtr = iPtr->varFramePtr;

    /*
     * Parse string to figure out which level number to go to.
     */

................................................................................
	if (framePtr == NULL) {
	    goto levelError;
	}
    }
    *framePtrPtr = framePtr;
    return result;
}


static char *printify(s)
char *s;
{
    static int destlen = 0;
    char *d;		/* ptr into dest */
    unsigned int need;
................................................................................
		if (step_count > 0) goto finish;
		goto start_interact;
	case ret:
		/* same comment as in "case next" */
		if (goalFramePtr != iPtr->varFramePtr) goto finish;
		goto start_interact;
    /* DANGER: unhandled cases! none, up, down, where */


	}

start_interact:
	if (print_command_first_time) {
		print(interp,"%s: %s\n",
				level_text,print_argv(interp,1,&command));
		print_command_first_time = FALSE;
................................................................................
			break;
		}
		goalFramePtr = goalFramePtr->callerVarPtr;
		goto finish;
	case where:
	PrintStack(interp,iPtr->varFramePtr,viewFramePtr,objc,objv,level_text);
		break;


	}

	/* restore view and restart interactor */
	iPtr->varFramePtr = viewFramePtr;
	goto start_interact;

 finish:






|
|
|
|
|
|







 







|







 







<







 







>
>







 







>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
...
297
298
299
300
301
302
303

304
305
306
307
308
309
310
...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
...
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
	sprintf(name,"%d",i);
	Tcl_SetVar2Ex(interp, Dbg_VarName, name, Tcl_GetRange(objPtr,
		info.matches[i].start, info.matches[i].end-1), 0);
    }
}

/* return 1 to break, 0 to continue 
 * cmd: command about to be executed
 * bp: breakpoint to test
 */
static int
breakpoint_test(Tcl_Interp *interp,const char *cmd,struct breakpoint *bp)
{
    if (bp->re) {
        int found = 0;
	Tcl_Obj *cmdObj;
	Tcl_RegExp re = Tcl_GetRegExpFromObj(NULL, bp->pat,
		TCL_REG_ADVANCED);
	cmdObj = Tcl_NewStringObj(cmd,-1);
................................................................................
    char *string;		/* String describing frame. */
    CallFrame **framePtrPtr;	/* Store pointer to frame here (or NULL
				 * if global frame indicated). */
    enum debug_cmd dir;	/* look up or down the stack */
{
    Interp *iPtr = (Interp *) interp;
    int level, result;
    CallFrame *framePtr = NULL;	/* frame currently being searched */

    CallFrame *curFramePtr = iPtr->varFramePtr;

    /*
     * Parse string to figure out which level number to go to.
     */

................................................................................
	if (framePtr == NULL) {
	    goto levelError;
	}
    }
    *framePtrPtr = framePtr;
    return result;
}


static char *printify(s)
char *s;
{
    static int destlen = 0;
    char *d;		/* ptr into dest */
    unsigned int need;
................................................................................
		if (step_count > 0) goto finish;
		goto start_interact;
	case ret:
		/* same comment as in "case next" */
		if (goalFramePtr != iPtr->varFramePtr) goto finish;
		goto start_interact;
    /* DANGER: unhandled cases! none, up, down, where */
	default:
		break; /* Silence compiler warning */
	}

start_interact:
	if (print_command_first_time) {
		print(interp,"%s: %s\n",
				level_text,print_argv(interp,1,&command));
		print_command_first_time = FALSE;
................................................................................
			break;
		}
		goalFramePtr = goalFramePtr->callerVarPtr;
		goto finish;
	case where:
	PrintStack(interp,iPtr->varFramePtr,viewFramePtr,objc,objv,level_text);
		break;
	default:
		break; /* Silence compiler warning */
	}

	/* restore view and restart interactor */
	iPtr->varFramePtr = viewFramePtr;
	goto start_interact;

 finish:

Changes to configure.in.

215
216
217
218
219
220
221


222
223
224
225
226
227
228
	# we only need to define OPENPTY once, but since we are overriding
	# the default behavior, we must also handle augment LIBS too.
	# This needn't be done in the 2nd and 3rd tests.
	AC_DEFINE(HAVE_OPENPTY)
	LIBS="$LIBS -lutil"
  ])
fi



######################################################################
# End of library/func checking
######################################################################

# Hand patches to library/func checking.
dnl From: Michael Kuhl <[email protected]>






>
>







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	# we only need to define OPENPTY once, but since we are overriding
	# the default behavior, we must also handle augment LIBS too.
	# This needn't be done in the 2nd and 3rd tests.
	AC_DEFINE(HAVE_OPENPTY)
	LIBS="$LIBS -lutil"
  ])
fi

AC_CHECK_HEADER(libutil.h,AC_DEFINE(HAVE_LIBUTIL_H))

######################################################################
# End of library/func checking
######################################################################

# Hand patches to library/func checking.
dnl From: Michael Kuhl <[email protected]>

Changes to exp_chan.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
..
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <errno.h>

#include	"tclInt.h"	/* Internal definitions for Tcl. */

#include "tcl.h"

#include "string.h"

#include "exp_rename.h"
#include "exp_prog.h"
#include "exp_command.h"
#include "exp_log.h"

#include "tcldbg.h" /* Dbg_StdinMode */

extern int		expSetBlockModeProc _ANSI_ARGS_((int fd, int mode));
static int		ExpBlockModeProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static int		ExpCloseProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));
................................................................................
		            int direction, ClientData *handlePtr));

/*
 * This structure describes the channel type structure for Expect-based IO:
 */

Tcl_ChannelType expChannelType = {
    "exp",				/* Type name. */

    ExpBlockModeProc,			/* Set blocking/nonblocking mode.*/
    ExpCloseProc,			/* Close proc. */
    ExpInputProc,			/* Input proc. */
    ExpOutputProc,			/* Output proc. */
    NULL,				/* Seek proc. */
    NULL,				/* Set option proc. */
    NULL,				/* Get option proc. */
    ExpWatchProc,			/* Initialize notifier. */
    ExpGetHandleProc,			/* Get OS handles out of channel. */
    NULL,				/* Close2 proc */
};

typedef struct ThreadSpecificData {
    /*
     * List of all exp channels currently open.  This is per thread and is
     * used to match up fd's to channels, which rarely occurs.
     */
................................................................................
    ClientData instanceData;	/* The exp state. */
    int direction;		/* TCL_READABLE or TCL_WRITABLE */
    ClientData *handlePtr;	/* Where to store the handle.  */
{
    ExpState *esPtr = (ExpState *) instanceData;

    if (direction & TCL_WRITABLE) {
	*handlePtr = (ClientData) esPtr->fdin;
    }
    if (direction & TCL_READABLE) {
	*handlePtr = (ClientData) esPtr->fdin;
    } else {
	return TCL_ERROR;
    }
    return TCL_OK;
}

int






|
<
|







>







 







|
>
|
|
|
|
<
<
<
|
|
<







 







|


|







21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
..
53
54
55
56
57
58
59
60
61
62
63
64
65



66
67

68
69
70
71
72
73
74
...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <errno.h>

#include <tclInt.h>	/* Internal definitions for Tcl. */

#include <tcl.h>

#include "string.h"

#include "exp_rename.h"
#include "exp_prog.h"
#include "exp_command.h"
#include "exp_log.h"
#include "exp_event.h"
#include "tcldbg.h" /* Dbg_StdinMode */

extern int		expSetBlockModeProc _ANSI_ARGS_((int fd, int mode));
static int		ExpBlockModeProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static int		ExpCloseProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));
................................................................................
		            int direction, ClientData *handlePtr));

/*
 * This structure describes the channel type structure for Expect-based IO:
 */

Tcl_ChannelType expChannelType = {
    .typeName = "exp",			/* Type name. */
    .version = TCL_CHANNEL_VERSION_2,
    .blockModeProc = ExpBlockModeProc,	/* Set blocking/nonblocking mode.*/
    .closeProc = ExpCloseProc,		/* Close proc. */
    .inputProc = ExpInputProc,		/* Input proc. */
    .outputProc = ExpOutputProc,	/* Output proc. */



    .watchProc = ExpWatchProc,		/* Initialize notifier. */
    .getHandleProc = ExpGetHandleProc	/* Get OS handles out of channel. */

};

typedef struct ThreadSpecificData {
    /*
     * List of all exp channels currently open.  This is per thread and is
     * used to match up fd's to channels, which rarely occurs.
     */
................................................................................
    ClientData instanceData;	/* The exp state. */
    int direction;		/* TCL_READABLE or TCL_WRITABLE */
    ClientData *handlePtr;	/* Where to store the handle.  */
{
    ExpState *esPtr = (ExpState *) instanceData;

    if (direction & TCL_WRITABLE) {
	*handlePtr = (ClientData)(intptr_t)esPtr->fdin;
    }
    if (direction & TCL_READABLE) {
	*handlePtr = (ClientData)(intptr_t)esPtr->fdin;
    } else {
	return TCL_ERROR;
    }
    return TCL_OK;
}

int

Changes to exp_clib.c.

45
46
47
48
49
50
51




52
53
54
55
56
57
58
...
112
113
114
115
116
117
118

119
120
121
122
123
124
125
....
1803
1804
1805
1806
1807
1808
1809







1810
1811
1812
1813
1814
1815
1816
....
1819
1820
1821
1822
1823
1824
1825

1826
1827
1828
1829
1830
1831
1832
1833
1834
1835

1836

1837
1838
1839
1840
1841
1842
1843
....
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
....
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
....
2849
2850
2851
2852
2853
2854
2855

2856

2857
2858
2859
2860
2861
2862
2863
#ifdef HAVE_STRREDIR_H
#include <sys/strredir.h>
# ifdef SRIOCSREDIR
#  undef TIOCCONS
# endif
#endif





#include <signal.h>
/*#include <memory.h> - deprecated - ANSI C moves them into string.h */
#include "string.h"

#include <errno.h>

................................................................................

#else
#include <stdlib.h>		/* for malloc */
#endif

#include <tcl.h>
#include "expect.h"

#define TclRegError exp_TclRegError

/*
 * regexp code - from tcl8.0.4/generic/regexp.c
 */

/*
................................................................................
	}
	fp->buffer_end = fp->buffer;
	fp->match_end = fp->buffer;
	return fp;

}








static
void
exp_setpgrp()
{
#ifdef MIPS_BSD
    /* required on BSD side of MIPS OS <[email protected]> */
#   include <sysv/sys.s>
................................................................................

#ifdef SETPGRP_VOID
    (void) setpgrp();
#else
    (void) setpgrp(0,0);
#endif
}


/* returns fd of master side of pty */
int
exp_spawnv(file,argv)
char *file;
char *argv[];	/* some compiler complains about **argv? */
{
	int cc;
	int errorfd;	/* place to stash fileno(stderr) in child */
			/* while we're setting up new stderr */

	int ttyfd;

	int sync_fds[2];
	int sync2_fds[2];
	int status_pipe[2];
	int child_errno;
	char sync_byte;
#ifdef PTYTRAP_DIES
	int slave_write_ioctls = 1;
................................................................................
	close(status_pipe[0]);
	fcntl(status_pipe[1],F_SETFD,1);	/* close on exec */

#ifdef CRAY
	(void) close(exp_pty[0]);
#endif

/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
/* is called.  setpgrp works though.  */
#if defined(POSIX) && !defined(ultrix)
#define DO_SETSID
#endif
#ifdef __convex__
#define DO_SETSID
#endif

#ifdef DO_SETSID
	setsid();
#else
#ifdef SYSV3
#ifndef CRAY
	exp_setpgrp();
#endif /* CRAY */
................................................................................
	time_t end_time;	/* future time at which to give up */
	int remtime;		/* remaining time in timeout */

	struct f *f;
	int return_val;
	int sys_error = 0;
#define return_normally(x)	{return_val = x; goto cleanup;}
#define return_errno(x)	{sys_error = x; goto cleanup;}

	f = fdfp2f(fd,fp);
	if (!f) return_errno(ENOMEM);

	exp_buffer = f->buffer;
	exp_buffer_end = f->buffer_end;
	exp_match_end = f->match_end;
................................................................................
	setbuf(fp,(char *)0);
	return(fp);
}

int
exp_disconnect()
{

	int ttyfd;


#ifndef EALREADY
#define EALREADY 37
#endif

	/* presumably, no stderr, so don't bother with error message */
	if (exp_disconnected) sysreturn(EALREADY);






>
>
>
>







 







>







 







>
>
>
>
>
>
>







 







>










>

>







 







<
<
<
<
<
<
<
<
<







 







|







 







>

>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
....
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
....
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
....
2019
2020
2021
2022
2023
2024
2025









2026
2027
2028
2029
2030
2031
2032
....
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
....
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
#ifdef HAVE_STRREDIR_H
#include <sys/strredir.h>
# ifdef SRIOCSREDIR
#  undef TIOCCONS
# endif
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <signal.h>
/*#include <memory.h> - deprecated - ANSI C moves them into string.h */
#include "string.h"

#include <errno.h>

................................................................................

#else
#include <stdlib.h>		/* for malloc */
#endif

#include <tcl.h>
#include "expect.h"
#include "exp_command.h"
#define TclRegError exp_TclRegError

/*
 * regexp code - from tcl8.0.4/generic/regexp.c
 */

/*
................................................................................
	}
	fp->buffer_end = fp->buffer;
	fp->match_end = fp->buffer;
	return fp;

}

/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
/* is called.  setpgrp works though.  */
#if defined(POSIX) && !defined(ultrix) || defined(__convex__)
#define DO_SETSID
#endif

#if !defined(DO_SETSID) && (!defined(SYSV3) || defined(CRAY)) /* { */
static
void
exp_setpgrp()
{
#ifdef MIPS_BSD
    /* required on BSD side of MIPS OS <[email protected]> */
#   include <sysv/sys.s>
................................................................................

#ifdef SETPGRP_VOID
    (void) setpgrp();
#else
    (void) setpgrp(0,0);
#endif
}
#endif /* } */

/* returns fd of master side of pty */
int
exp_spawnv(file,argv)
char *file;
char *argv[];	/* some compiler complains about **argv? */
{
	int cc;
	int errorfd;	/* place to stash fileno(stderr) in child */
			/* while we're setting up new stderr */
#if defined(TIOCNOTTY) && !defined(SYSV3) && !defined(DO_SETSID)
	int ttyfd;
#endif
	int sync_fds[2];
	int sync2_fds[2];
	int status_pipe[2];
	int child_errno;
	char sync_byte;
#ifdef PTYTRAP_DIES
	int slave_write_ioctls = 1;
................................................................................
	close(status_pipe[0]);
	fcntl(status_pipe[1],F_SETFD,1);	/* close on exec */

#ifdef CRAY
	(void) close(exp_pty[0]);
#endif










#ifdef DO_SETSID
	setsid();
#else
#ifdef SYSV3
#ifndef CRAY
	exp_setpgrp();
#endif /* CRAY */
................................................................................
	time_t end_time;	/* future time at which to give up */
	int remtime;		/* remaining time in timeout */

	struct f *f;
	int return_val;
	int sys_error = 0;
#define return_normally(x)	{return_val = x; goto cleanup;}
#define return_errno(x)	{sys_error = x; return_val = -1; goto cleanup;}

	f = fdfp2f(fd,fp);
	if (!f) return_errno(ENOMEM);

	exp_buffer = f->buffer;
	exp_buffer_end = f->buffer_end;
	exp_match_end = f->match_end;
................................................................................
	setbuf(fp,(char *)0);
	return(fp);
}

int
exp_disconnect()
{
#if defined(TIOCNOTTY) && !defined(SYSV3) && !defined(POSIX)
	int ttyfd;
#endif

#ifndef EALREADY
#define EALREADY 37
#endif

	/* presumably, no stderr, so don't bother with error message */
	if (exp_disconnected) sysreturn(EALREADY);

Changes to exp_command.c.

528
529
530
531
532
533
534







535
536
537
538
539
540
541
...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
...
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
...
899
900
901
902
903
904
905
906


907
908
909
910
911
912


913
914
915
916
917
918
919
....
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
....
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
....
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
    int pgrp = getpgrp(0);
    if (-1 == ioctl(fd,TIOCSETPGRP,&pgrp)) perror("TIOCSETPGRP");
    if (-1 == ioctl(fd,TIOCSPGRP,&pgrp)) perror("TIOCSPGRP");
    if (-1 == tcsetpgrp(fd,pgrp)) perror("tcsetpgrp");
}
#endif








static
void
expSetpgrp()
{
#ifdef MIPS_BSD
    /* required on BSD side of MIPS OS <[email protected]> */
#   include <sysv/sys.s>
................................................................................

#ifdef SETPGRP_VOID
    (void) setpgrp();
#else
    (void) setpgrp(0,0);
#endif
}


/*ARGSUSED*/
static void
set_slave_name(
    ExpState *esPtr,
    char *name)
{
................................................................................
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST objv[])		/* Argument objects. */
{
    ExpState *esPtr = 0;
    int slave;
    int pid;
#ifdef TIOCNOTTY
    /* tell Saber to ignore non-use of ttyfd */
    /*SUPPRESS 591*/
    int ttyfd;
#endif /* TIOCNOTTY */
    int errorfd;	/* place to stash fileno(stderr) in child */
			/* while we're setting up new stderr */
    int master, k;
    int write_master;	/* write fd of Tcl-opened files */
    int ttyinit = TRUE;
................................................................................
	    exp_error(interp,"channel is neither readable nor writable");
	    return TCL_ERROR;
	}
	if (mode & TCL_READABLE) {
	    if (TCL_ERROR == Tcl_GetChannelHandle(channel, TCL_READABLE, &rfdc)) {
		return TCL_ERROR;
	    }
	    rfd = (int)(long) rfdc;


	}
	if (mode & TCL_WRITABLE) {
	    if (TCL_ERROR == Tcl_GetChannelHandle(channel, TCL_WRITABLE, &wfdc)) {
		return TCL_ERROR;
	    }
	    wfd = (int)(long) wfdc;


	}
	master = ((mode & TCL_READABLE)?rfd:wfd);

	/* make a new copy of file descriptor */
	if (-1 == (write_master = master = dup(master))) {
	    exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
	    return TCL_ERROR;
................................................................................
	exp_dev_tty = -1;
    }

#ifdef CRAY
    (void) close(master);
#endif

/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
/* is called.  setpgrp works though.  */
#if defined(POSIX) && !defined(ultrix)
#define DO_SETSID
#endif
#ifdef __convex__
#define DO_SETSID
#endif

#ifdef DO_SETSID
    setsid();
#else
#ifdef SYSV3
#ifndef CRAY
    expSetpgrp();
#endif /* CRAY */
................................................................................
#define SEND_STYLE_PLAIN	0x01
#define SEND_STYLE_HUMAN	0x02
#define SEND_STYLE_SLOW		0x04
#define SEND_STYLE_ZERO		0x10
#define SEND_STYLE_BREAK	0x20
    int send_style = SEND_STYLE_PLAIN;
    int want_cooked = TRUE;
    char *string;		/* string to send */
    int len = -1;		/* length of string to send */
    int zeros;		/* count of how many ascii zeros to send */

    char *chanName = 0;
    struct exp_state_list *state_list;
    struct exp_i *i;
    int j;
................................................................................
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST objv[])		/* Argument objects. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    
#ifdef TIOCNOTTY
    /* tell CenterLine to ignore non-use of ttyfd */
    /*SUPPRESS 591*/
    int ttyfd;
#endif /* TIOCNOTTY */

    if (objc > 1) {
	exp_error(interp,"usage: disconnect");
	return(TCL_ERROR);
    }






>
>
>
>
>
>
>







 







|







 







|
<
<







 







|
>
>





|
>
>







 







<
<
<
<
<
<
<
<
<







 







|







 







|
<
<







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
...
584
585
586
587
588
589
590
591


592
593
594
595
596
597
598
...
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
....
1131
1132
1133
1134
1135
1136
1137









1138
1139
1140
1141
1142
1143
1144
....
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
....
3110
3111
3112
3113
3114
3115
3116
3117


3118
3119
3120
3121
3122
3123
3124
    int pgrp = getpgrp(0);
    if (-1 == ioctl(fd,TIOCSETPGRP,&pgrp)) perror("TIOCSETPGRP");
    if (-1 == ioctl(fd,TIOCSPGRP,&pgrp)) perror("TIOCSPGRP");
    if (-1 == tcsetpgrp(fd,pgrp)) perror("tcsetpgrp");
}
#endif

/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
/* is called.  setpgrp works though.  */
#if defined(POSIX) && !defined(ultrix) || defined(__convex__)
#define DO_SETSID
#endif

#if !defined(DO_SETSID) && (!defined(SYSV3) || defined(CRAY)) /* { */
static
void
expSetpgrp()
{
#ifdef MIPS_BSD
    /* required on BSD side of MIPS OS <[email protected]> */
#   include <sysv/sys.s>
................................................................................

#ifdef SETPGRP_VOID
    (void) setpgrp();
#else
    (void) setpgrp(0,0);
#endif
}
#endif /* } */

/*ARGSUSED*/
static void
set_slave_name(
    ExpState *esPtr,
    char *name)
{
................................................................................
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST objv[])		/* Argument objects. */
{
    ExpState *esPtr = 0;
    int slave;
    int pid;
#if defined(TIOCNOTTY) && !defined(SYSV3) && !defined(DO_SETSID)


    int ttyfd;
#endif /* TIOCNOTTY */
    int errorfd;	/* place to stash fileno(stderr) in child */
			/* while we're setting up new stderr */
    int master, k;
    int write_master;	/* write fd of Tcl-opened files */
    int ttyinit = TRUE;
................................................................................
	    exp_error(interp,"channel is neither readable nor writable");
	    return TCL_ERROR;
	}
	if (mode & TCL_READABLE) {
	    if (TCL_ERROR == Tcl_GetChannelHandle(channel, TCL_READABLE, &rfdc)) {
		return TCL_ERROR;
	    }
	    rfd = (int)(intptr_t) rfdc;
	} else {
	    rfd = -1;
	}
	if (mode & TCL_WRITABLE) {
	    if (TCL_ERROR == Tcl_GetChannelHandle(channel, TCL_WRITABLE, &wfdc)) {
		return TCL_ERROR;
	    }
	    wfd = (int)(intptr_t) wfdc;
	} else {
	    wfd = -1;
	}
	master = ((mode & TCL_READABLE)?rfd:wfd);

	/* make a new copy of file descriptor */
	if (-1 == (write_master = master = dup(master))) {
	    exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
	    return TCL_ERROR;
................................................................................
	exp_dev_tty = -1;
    }

#ifdef CRAY
    (void) close(master);
#endif










#ifdef DO_SETSID
    setsid();
#else
#ifdef SYSV3
#ifndef CRAY
    expSetpgrp();
#endif /* CRAY */
................................................................................
#define SEND_STYLE_PLAIN	0x01
#define SEND_STYLE_HUMAN	0x02
#define SEND_STYLE_SLOW		0x04
#define SEND_STYLE_ZERO		0x10
#define SEND_STYLE_BREAK	0x20
    int send_style = SEND_STYLE_PLAIN;
    int want_cooked = TRUE;
    char *string = NULL;		/* string to send */
    int len = -1;		/* length of string to send */
    int zeros;		/* count of how many ascii zeros to send */

    char *chanName = 0;
    struct exp_state_list *state_list;
    struct exp_i *i;
    int j;
................................................................................
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST objv[])		/* Argument objects. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    
#if defined(TIOCNOTTY) && !defined(SYSV3) && !defined(DO_SETSID)


    int ttyfd;
#endif /* TIOCNOTTY */

    if (objc > 1) {
	exp_error(interp,"usage: disconnect");
	return(TCL_ERROR);
    }

Changes to exp_event.c.

20
21
22
23
24
25
26

27
28
29
30
31
32
33
...
116
117
118
119
120
121
122



123
124
125
126
127
128
129
#  include <sys/ptyio.h>
#endif

#include "tcl.h"
#include "exp_prog.h"
#include "exp_command.h"	/* for ExpState defs */
#include "exp_event.h"


typedef struct ThreadSpecificData {
    int rr;		/* round robin ptr */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

................................................................................
    switch (esPtr->bg_status) {
	case blocked:
	    exp_arm_background_channelhandler_force(esPtr);
	    break;
	case disarm_req_while_blocked:
	    exp_disarm_background_channelhandler_force(esPtr);
	    break;



    }
}

/* this can only be called at the beginning of the bg handler in which */
/* case we know the status must be "armed" */
void
exp_block_background_channelhandler(esPtr)






>







 







>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#  include <sys/ptyio.h>
#endif

#include "tcl.h"
#include "exp_prog.h"
#include "exp_command.h"	/* for ExpState defs */
#include "exp_event.h"
#include "exp_log.h"

typedef struct ThreadSpecificData {
    int rr;		/* round robin ptr */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

................................................................................
    switch (esPtr->bg_status) {
	case blocked:
	    exp_arm_background_channelhandler_force(esPtr);
	    break;
	case disarm_req_while_blocked:
	    exp_disarm_background_channelhandler_force(esPtr);
	    break;
	default:
	    expDiagLog("Unexpected value %d of bg-handler in %s",
		esPtr->bg_status, __func__);
    }
}

/* this can only be called at the beginning of the bg handler in which */
/* case we know the status must be "armed" */
void
exp_block_background_channelhandler(esPtr)

Changes to exp_inter.c.

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
...
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
....
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
static void
intEcho(
    ExpState *esPtr,
    int skipBytes,
    int matchBytes)
{
    int seenBytes;	/* either printed or echoed */
    int echoBytes;
    int offsetBytes;

    /* write is unlikely to fail, since we just read from same descriptor */
    seenBytes = esPtr->printed + esPtr->echoed;
    if (skipBytes >= seenBytes) {
	echoBytes = matchBytes;
	offsetBytes = skipBytes;
    } else if ((matchBytes + skipBytes - seenBytes) > 0) {
................................................................................
{
	exp_configure_count++;
	return 0;
}
			
#define finish(x)	{ status = x; goto done; }

static char return_cmd[] = "return";
static char interpreter_cmd[] = "interpreter";

/*ARGSUSED*/
int
Exp_InteractObjCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST initial_objv[])		/* Argument objects. */
................................................................................
#ifndef SIMPLE_EVENT
    /* loop waiting (in event handler) for input */
    for (;;) {
	int te;	/* result of Tcl_Eval */
	int rc;	/* return code from ready.  This is further refined by matcher. */
	int cc;			/* # of chars from read() */
	struct action *action = 0;
	time_t previous_time;
	time_t current_time;
	int matchLen;	/* # of chars matched */
	int skip;		/* # of chars not involved in match */
	int print;		/* # of chars to print */
	int oldprinted;		/* old version of u->printed */
	int change;		/* if action requires cooked mode */
	int attempt_match = TRUE;
	struct input *soonest_input;
	int timeout;	/* current as opposed to default_timeout */
	Tcl_Time temp_time;

	/* calculate how long to wait */
	/* by finding shortest remaining timeout */
	if (timeout_simple) {
	    timeout = default_timeout;






|
|







 







<
<
<







 







|

|





|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
...
702
703
704
705
706
707
708



709
710
711
712
713
714
715
....
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
static void
intEcho(
    ExpState *esPtr,
    int skipBytes,
    int matchBytes)
{
    int seenBytes;	/* either printed or echoed */
    int echoBytes = 0;
    int offsetBytes = 0;

    /* write is unlikely to fail, since we just read from same descriptor */
    seenBytes = esPtr->printed + esPtr->echoed;
    if (skipBytes >= seenBytes) {
	echoBytes = matchBytes;
	offsetBytes = skipBytes;
    } else if ((matchBytes + skipBytes - seenBytes) > 0) {
................................................................................
{
	exp_configure_count++;
	return 0;
}
			
#define finish(x)	{ status = x; goto done; }




/*ARGSUSED*/
int
Exp_InteractObjCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST initial_objv[])		/* Argument objects. */
................................................................................
#ifndef SIMPLE_EVENT
    /* loop waiting (in event handler) for input */
    for (;;) {
	int te;	/* result of Tcl_Eval */
	int rc;	/* return code from ready.  This is further refined by matcher. */
	int cc;			/* # of chars from read() */
	struct action *action = 0;
	time_t previous_time = 0;
	time_t current_time;
	int matchLen = 0;	/* # of chars matched */
	int skip;		/* # of chars not involved in match */
	int print;		/* # of chars to print */
	int oldprinted;		/* old version of u->printed */
	int change;		/* if action requires cooked mode */
	int attempt_match = TRUE;
	struct input *soonest_input = NULL;
	int timeout;	/* current as opposed to default_timeout */
	Tcl_Time temp_time;

	/* calculate how long to wait */
	/* by finding shortest remaining timeout */
	if (timeout_simple) {
	    timeout = default_timeout;

Changes to exp_log.c.

86
87
88
89
90
91
92


93
94
95
96
97
98
99
    int lenChars;
{
    int wc;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (esPtr->valid)
	wc = expWriteCharsUni(esPtr,buf,lenChars);



    if (tsdPtr->logChannel && ((esPtr->fdout == 1) || expDevttyIs(esPtr))) {
      Tcl_DString ds;
      Tcl_DStringInit (&ds);
      Tcl_UniCharToUtfDString (buf,lenChars,&ds);
      Tcl_WriteChars(tsdPtr->logChannel,Tcl_DStringValue (&ds), Tcl_DStringLength (&ds));
      Tcl_DStringFree (&ds);






>
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    int lenChars;
{
    int wc;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (esPtr->valid)
	wc = expWriteCharsUni(esPtr,buf,lenChars);
    else
	wc = -1;

    if (tsdPtr->logChannel && ((esPtr->fdout == 1) || expDevttyIs(esPtr))) {
      Tcl_DString ds;
      Tcl_DStringInit (&ds);
      Tcl_UniCharToUtfDString (buf,lenChars,&ds);
      Tcl_WriteChars(tsdPtr->logChannel,Tcl_DStringValue (&ds), Tcl_DStringLength (&ds));
      Tcl_DStringFree (&ds);

Changes to exp_pty.c.

131
132
133
134
135
136
137

138

139
140
141
142
143
144
145
	i_read_errno = errno;	/* errno can be overwritten by the */
				/* time we return */
	alarm(0);
	return(cc);
}

static RETSIGTYPE (*oldAlarmHandler)();

static RETSIGTYPE (*oldHupHandler)();

static time_t current_time;	/* time when testing began */

/* if TRUE, begin testing, else end testing */
/* returns -1 for failure, 0 for success */
int
exp_pty_test_start()
{






>

>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	i_read_errno = errno;	/* errno can be overwritten by the */
				/* time we return */
	alarm(0);
	return(cc);
}

static RETSIGTYPE (*oldAlarmHandler)();
#ifndef O_NOCTTY
static RETSIGTYPE (*oldHupHandler)();
#endif
static time_t current_time;	/* time when testing began */

/* if TRUE, begin testing, else end testing */
/* returns -1 for failure, 0 for success */
int
exp_pty_test_start()
{

Changes to exp_trap.c.

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
315
316
317
318
319
320
321
322


323
324
325
326
327
328
329
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
	exp_error(interp,"invalid signal %s",s);
	
	return -1;
}

/*ARGSUSED*/
int
Exp_TrapObjCmd(clientData, interp, objc, objv)
ClientData clientData;
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
{
	char *action = 0;
	int n;		/* number of signals in list */
	Tcl_Obj **list;	/* list of signals */
	char *arg;
	int len;	/* length of action */
	int i;
................................................................................
	int rc = TCL_OK;
	int new_code = FALSE;	/* if action result should overwrite orig */
	Tcl_Interp *new_interp = interp;/* interp in which to evaluate */
					/* action when signal occurs */

	objc--; objv++;

	while (objc) {


	  arg = Tcl_GetString(*objv);

		if (streq(arg,"-code")) {
			objc--; objv++; 
			new_code = TRUE;
		} else if (streq(arg,"-interp")) {
			objc--; objv++; 
................................................................................
		} else if (streq(arg,"-number")) {
			objc--; objv++;
			show_number = TRUE;
		} else if (streq(arg,"-max")) {
			objc--; objv++;
			show_max = TRUE;
		} else break;
	}

	if (show_name || show_number || show_max) {
		if (objc > 0) goto usage_error;
		if (show_max) {
		  Tcl_SetObjResult(interp,Tcl_NewIntObj(NSIG-1));
		}







<
|
|
|
|







 







|
>
>







 







|







293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
	exp_error(interp,"invalid signal %s",s);
	
	return -1;
}

/*ARGSUSED*/
int

Exp_TrapObjCmd(ClientData clientData,
	       Tcl_Interp *interp,
	       int objc,
	       Tcl_Obj *CONST objv[])
{
	char *action = 0;
	int n;		/* number of signals in list */
	Tcl_Obj **list;	/* list of signals */
	char *arg;
	int len;	/* length of action */
	int i;
................................................................................
	int rc = TCL_OK;
	int new_code = FALSE;	/* if action result should overwrite orig */
	Tcl_Interp *new_interp = interp;/* interp in which to evaluate */
					/* action when signal occurs */

	objc--; objv++;

	if (objc <= 0) goto usage_error;

	do {
	  arg = Tcl_GetString(*objv);

		if (streq(arg,"-code")) {
			objc--; objv++; 
			new_code = TRUE;
		} else if (streq(arg,"-interp")) {
			objc--; objv++; 
................................................................................
		} else if (streq(arg,"-number")) {
			objc--; objv++;
			show_number = TRUE;
		} else if (streq(arg,"-max")) {
			objc--; objv++;
			show_max = TRUE;
		} else break;
	} while(objc);

	if (show_name || show_number || show_max) {
		if (objc > 0) goto usage_error;
		if (show_max) {
		  Tcl_SetObjResult(interp,Tcl_NewIntObj(NSIG-1));
		}

Changes to exp_tty.c.

581
582
583
584
585
586
587
588
589
590
591
592
593
594

595
596
597
598

599

600
601
602
603
604
605
606
...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
...
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
;
	int abnormalExit = FALSE;
	char buf[MAX_ARGLIST];
	char *bufp = buf;
	int total_len = 0, arg_len;

	int stty_args_recognized = TRUE;
	int cmd_is_stty = FALSE;
	int cooked = FALSE;
	int was_raw, was_echo;

	if (argc == 1) return TCL_OK;

	if (streq(argv[1],"stty")) {

		expDiagLogU("system stty is deprecated, use stty\r\n");

		cmd_is_stty = TRUE;
		was_raw = exp_israw();

		was_echo = exp_isecho();

	}

	if (argc > 2 && cmd_is_stty) {
		exp_ioctled_devtty = TRUE;

		for (i=2;i<argc;i++) {
			if (streq(argv[i],"raw") ||
................................................................................
				expErrorLog("are you disconnected or in a batch, at, or cron script?");
				/* user could've conceivably closed /dev/tty as well */
			    }
			    exp_error(interp,"system stty: ioctl(user): %s\r\n",Tcl_PosixError(interp));
			    return(TCL_ERROR);
			}
			if (cmd_is_stty) {
			    char buf [11];
			    sprintf(buf,"%sraw %secho",
				    (was_raw?"":"-"),
				    (was_echo?"":"-"));
			    Tcl_SetResult (interp, buf, TCL_VOLATILE);
			}
			return(TCL_OK);
		}
	}

	for (i = 1;i<argc;i++) {
		total_len += (1 + (arg_len = strlen(argv[i])));
................................................................................
		if (cooked) {
			/* find out user's new defn of 'cooked' */
			tty_cooked = tty_current;
		}
	}

	if (cmd_is_stty) {
	    char buf [11];
	    sprintf(buf,"%sraw %secho",
		    (was_raw?"":"-"),
		    (was_echo?"":"-"));
	    Tcl_SetResult (interp, buf, TCL_VOLATILE);
	}

/* following macros stolen from Tcl's tclUnix.h file */
/* we can't include the whole thing because it depends on other macros */
/* that come out of Tcl's Makefile, sigh */

#if 0






|

|



|
>


<
|
>
|
>







 







|
<
<
<
<







 







|
<
<
<
<







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
...
633
634
635
636
637
638
639
640




641
642
643
644
645
646
647
...
693
694
695
696
697
698
699
700




701
702
703
704
705
706
707
;
	int abnormalExit = FALSE;
	char buf[MAX_ARGLIST];
	char *bufp = buf;
	int total_len = 0, arg_len;

	int stty_args_recognized = TRUE;
	int cmd_is_stty;
	int cooked = FALSE;
	const char *was_raw = "-raw", *was_echo = "-echo";

	if (argc == 1) return TCL_OK;

	cmd_is_stty = streq(argv[1],"stty");
	if (cmd_is_stty) {
		expDiagLogU("system stty is deprecated, use stty\r\n");


		if (exp_israw())
			was_raw++;
		if (exp_isecho())
			was_echo++;
	}

	if (argc > 2 && cmd_is_stty) {
		exp_ioctled_devtty = TRUE;

		for (i=2;i<argc;i++) {
			if (streq(argv[i],"raw") ||
................................................................................
				expErrorLog("are you disconnected or in a batch, at, or cron script?");
				/* user could've conceivably closed /dev/tty as well */
			    }
			    exp_error(interp,"system stty: ioctl(user): %s\r\n",Tcl_PosixError(interp));
			    return(TCL_ERROR);
			}
			if (cmd_is_stty) {
			    Tcl_AppendResult (interp, was_raw, " ", was_echo, NULL);




			}
			return(TCL_OK);
		}
	}

	for (i = 1;i<argc;i++) {
		total_len += (1 + (arg_len = strlen(argv[i])));
................................................................................
		if (cooked) {
			/* find out user's new defn of 'cooked' */
			tty_cooked = tty_current;
		}
	}

	if (cmd_is_stty) {
	    Tcl_AppendResult (interp, was_raw, " ", was_echo, NULL);




	}

/* following macros stolen from Tcl's tclUnix.h file */
/* we can't include the whole thing because it depends on other macros */
/* that come out of Tcl's Makefile, sigh */

#if 0

Changes to exp_tty.h.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
extern int exp_stdin_is_tty;
extern int exp_stdout_is_tty;

void exp_tty_raw(int set);
void exp_tty_echo(int set);
void exp_tty_break(Tcl_Interp *interp, int fd);
int exp_tty_raw_noecho(Tcl_Interp *interp, exp_tty *tty_old, int *was_raw, int *was_echo);

int exp_israw(void);
int exp_isecho(void);

void exp_tty_set(Tcl_Interp *interp, exp_tty *tty, int raw, int echo);
int exp_tty_set_simple(exp_tty *tty);
int exp_tty_get_simple(exp_tty *tty);

#endif	/* __EXP_TTY_H__ */






>








15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
extern int exp_stdin_is_tty;
extern int exp_stdout_is_tty;

void exp_tty_raw(int set);
void exp_tty_echo(int set);
void exp_tty_break(Tcl_Interp *interp, int fd);
int exp_tty_raw_noecho(Tcl_Interp *interp, exp_tty *tty_old, int *was_raw, int *was_echo);
int exp_tty_cooked_echo(Tcl_Interp *interp, exp_tty *tty_old, int *was_raw, int *was_echo);
int exp_israw(void);
int exp_isecho(void);

void exp_tty_set(Tcl_Interp *interp, exp_tty *tty, int raw, int echo);
int exp_tty_set_simple(exp_tty *tty);
int exp_tty_get_simple(exp_tty *tty);

#endif	/* __EXP_TTY_H__ */

Changes to exp_win.c.

74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
	int rows;
} exp_winsize;
#endif

static exp_winsize winsize = {0, 0};
static exp_winsize win2size = {0, 0};

int exp_window_size_set(fd)
int fd;
{

#ifdef TIOCSWINSZ
	ioctl(fd,TIOCSWINSZ,&winsize);
#endif
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
	ioctl(fd,TIOCSSIZE,&winsize);
#endif
}

int exp_window_size_get(fd)
int fd;
{

#ifdef TIOCGWINSZ
	ioctl(fd,TIOCGWINSZ,&winsize);
#endif
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
	ioctl(fd,TIOCGSIZE,&winsize);
#endif
#if !defined(EXP_WIN)
	winsize.rows = 0;
	winsize.columns = 0;
#endif
}

void
exp_win_rows_set(rows)
char *rows;
{
	winsize.rows = atoi(rows);
	exp_window_size_set(exp_dev_tty);
}

char*
exp_win_rows_get()
................................................................................
    static char rows [20];
	exp_window_size_get(exp_dev_tty);
	sprintf(rows,"%d",winsize.rows);
    return rows;
}

void
exp_win_columns_set(columns)
char *columns;
{
	winsize.columns = atoi(columns);
	exp_window_size_set(exp_dev_tty);
}

char*
exp_win_columns_get()
................................................................................
    return columns;
}

/*
 * separate copy of everything above - used for handling user stty requests
 */

int exp_win2_size_set(fd)
int fd;
{
#ifdef TIOCSWINSZ
			ioctl(fd,TIOCSWINSZ,&win2size);
#endif
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
			ioctl(fd,TIOCSSIZE,&win2size);
#endif
}

int exp_win2_size_get(fd)
int fd;
{
#ifdef TIOCGWINSZ
	ioctl(fd,TIOCGWINSZ,&win2size);
#endif
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
	ioctl(fd,TIOCGSIZE,&win2size);
#endif
}

void
exp_win2_rows_set(fd,rows)
int fd;
char *rows;
{
	exp_win2_size_get(fd);
	win2size.rows = atoi(rows);
	exp_win2_size_set(fd);
}

char*
exp_win2_rows_get(fd)
int fd;
{
    static char rows [20];
	exp_win2_size_get(fd);
	sprintf(rows,"%d",win2size.rows);
#if !defined(EXP_WIN)
	win2size.rows = 0;
	win2size.columns = 0;
#endif
    return rows;
}

void
exp_win2_columns_set(fd,columns)
int fd;
char *columns;
{
	exp_win2_size_get(fd);
	win2size.columns = atoi(columns);
	exp_win2_size_set(fd);
}

char*
exp_win2_columns_get(fd)
int fd;
{
    static char columns [20];
	exp_win2_size_get(fd);
	sprintf(columns,"%d",win2size.columns);
    return columns;
}
 






|
<

>








|
<

>













|
<







 







|
<







 







|
|









|
|










|
<
<







|
<












|
<
<







|
<







74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
...
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166


167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
	int rows;
} exp_winsize;
#endif

static exp_winsize winsize = {0, 0};
static exp_winsize win2size = {0, 0};

int exp_window_size_set(int fd)

{
	return
#ifdef TIOCSWINSZ
	ioctl(fd,TIOCSWINSZ,&winsize);
#endif
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
	ioctl(fd,TIOCSSIZE,&winsize);
#endif
}

int exp_window_size_get(int fd)

{
	return
#ifdef TIOCGWINSZ
	ioctl(fd,TIOCGWINSZ,&winsize);
#endif
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
	ioctl(fd,TIOCGSIZE,&winsize);
#endif
#if !defined(EXP_WIN)
	winsize.rows = 0;
	winsize.columns = 0;
#endif
}

void
exp_win_rows_set(const char *rows)

{
	winsize.rows = atoi(rows);
	exp_window_size_set(exp_dev_tty);
}

char*
exp_win_rows_get()
................................................................................
    static char rows [20];
	exp_window_size_get(exp_dev_tty);
	sprintf(rows,"%d",winsize.rows);
    return rows;
}

void
exp_win_columns_set(const char *columns)

{
	winsize.columns = atoi(columns);
	exp_window_size_set(exp_dev_tty);
}

char*
exp_win_columns_get()
................................................................................
    return columns;
}

/*
 * separate copy of everything above - used for handling user stty requests
 */

static void
exp_win2_size_set(int fd)
{
#ifdef TIOCSWINSZ
			ioctl(fd,TIOCSWINSZ,&win2size);
#endif
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
			ioctl(fd,TIOCSSIZE,&win2size);
#endif
}

static void
exp_win2_size_get(int fd)
{
#ifdef TIOCGWINSZ
	ioctl(fd,TIOCGWINSZ,&win2size);
#endif
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
	ioctl(fd,TIOCGSIZE,&win2size);
#endif
}

void
exp_win2_rows_set(int fd,const char *rows)


{
	exp_win2_size_get(fd);
	win2size.rows = atoi(rows);
	exp_win2_size_set(fd);
}

char*
exp_win2_rows_get(int fd)

{
    static char rows [20];
	exp_win2_size_get(fd);
	sprintf(rows,"%d",win2size.rows);
#if !defined(EXP_WIN)
	win2size.rows = 0;
	win2size.columns = 0;
#endif
    return rows;
}

void
exp_win2_columns_set(int fd,const char *columns)


{
	exp_win2_size_get(fd);
	win2size.columns = atoi(columns);
	exp_win2_size_set(fd);
}

char*
exp_win2_columns_get(int fd)

{
    static char columns [20];
	exp_win2_size_get(fd);
	sprintf(columns,"%d",win2size.columns);
    return columns;
}
 

Changes to exp_win.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
*/

#include <tcl.h> /* For _ANSI_ARGS_ */

int exp_window_size_set();
int exp_window_size_get();

void  exp_win_rows_set    _ANSI_ARGS_ ((char* rows));
char* exp_win_rows_get    _ANSI_ARGS_ ((void));
void  exp_win_columns_set _ANSI_ARGS_ ((char* columns));
char* exp_win_columns_get _ANSI_ARGS_ ((void));

void  exp_win2_rows_set    _ANSI_ARGS_ ((int fd, char* rows));
char* exp_win2_rows_get    _ANSI_ARGS_ ((int fd));
void  exp_win2_columns_set _ANSI_ARGS_ ((int fd, char* columns));
char* exp_win2_columns_get _ANSI_ARGS_ ((int fd));






|

|


|

|

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
*/

#include <tcl.h> /* For _ANSI_ARGS_ */

int exp_window_size_set();
int exp_window_size_get();

void  exp_win_rows_set    _ANSI_ARGS_ ((const char* rows));
char* exp_win_rows_get    _ANSI_ARGS_ ((void));
void  exp_win_columns_set _ANSI_ARGS_ ((const char* columns));
char* exp_win_columns_get _ANSI_ARGS_ ((void));

void  exp_win2_rows_set    _ANSI_ARGS_ ((int fd, const char* rows));
char* exp_win2_rows_get    _ANSI_ARGS_ ((int fd));
void  exp_win2_columns_set _ANSI_ARGS_ ((int fd, const char* columns));
char* exp_win2_columns_get _ANSI_ARGS_ ((int fd));

Changes to expect.c.

2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
....
2943
2944
2945
2946
2947
2948
2949

2950


2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
    ExpState *esPtr = 0;

    int i;			/* misc temporary */
    struct exp_cmd_descriptor eg;
    struct exp_state_list *state_list;	/* list of ExpStates to watch */
    struct exp_state_list *slPtr;	/* temp for interating over state_list */
    ExpState **esPtrs;
    int mcount;			/* number of esPtrs to watch */

    struct eval_out eo;		/* final case of interest */

    int result;			/* Tcl result */
    
    time_t start_time_total;	/* time at beginning of this procedure */
    time_t start_time = 0;	/* time when restart label hit */
    time_t current_time = 0;	/* current time (when we last looked)*/
    time_t end_time;		/* future time at which to give up */

    ExpState *last_esPtr;	/* for differentiating when multiple f's */
				/* to print out better debugging messages */
    int last_case;		/* as above but for case */
    int first_time = 1;		/* if not "restarted" */
    
    int key;			/* identify this expect command instance */
    int configure_count;	/* monitor exp_configure_count */

    int timeout;		/* seconds */
    int remtime;		/* remaining time in timeout */
    int reset_timer;		/* should timer be reset after continue? */
    Tcl_Time temp_time;
    Tcl_Obj* new_cmd = NULL;

................................................................................
	    
    if (!def) {
	if (!chan) {
	    esPtr = expStateCurrent(interp,0,0,0);
	} else {
	    esPtr = expStateFromChannelName(interp,chan,0,0,0,(char*)cmd);
	}

	if (!esPtr) return(TCL_ERROR);


    }

    *at = i;
    *Default = def;
    *esOut = esPtr;
    return TCL_OK;
}


/*ARGSUSED*/
int
Exp_MatchMaxObjCmd(






|








|







|







 







>
|
>
>




<







2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
....
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957

2958
2959
2960
2961
2962
2963
2964
    ExpState *esPtr = 0;

    int i;			/* misc temporary */
    struct exp_cmd_descriptor eg;
    struct exp_state_list *state_list;	/* list of ExpStates to watch */
    struct exp_state_list *slPtr;	/* temp for interating over state_list */
    ExpState **esPtrs;
    int mcount = 0;		/* number of esPtrs to watch */

    struct eval_out eo;		/* final case of interest */

    int result;			/* Tcl result */
    
    time_t start_time_total;	/* time at beginning of this procedure */
    time_t start_time = 0;	/* time when restart label hit */
    time_t current_time = 0;	/* current time (when we last looked)*/
    time_t end_time = 0;	/* future time at which to give up */

    ExpState *last_esPtr;	/* for differentiating when multiple f's */
				/* to print out better debugging messages */
    int last_case;		/* as above but for case */
    int first_time = 1;		/* if not "restarted" */
    
    int key;			/* identify this expect command instance */
    int configure_count = 0;	/* monitor exp_configure_count */

    int timeout;		/* seconds */
    int remtime;		/* remaining time in timeout */
    int reset_timer;		/* should timer be reset after continue? */
    Tcl_Time temp_time;
    Tcl_Obj* new_cmd = NULL;

................................................................................
	    
    if (!def) {
	if (!chan) {
	    esPtr = expStateCurrent(interp,0,0,0);
	} else {
	    esPtr = expStateFromChannelName(interp,chan,0,0,0,(char*)cmd);
	}
	if (!esPtr)
	    return(TCL_ERROR);

	*esOut = esPtr;
    }

    *at = i;
    *Default = def;

    return TCL_OK;
}


/*ARGSUSED*/
int
Exp_MatchMaxObjCmd(

Changes to pty_termios.c.

59
60
61
62
63
64
65








66
67
68
69
70
71
72
..
98
99
100
101
102
103
104

105
106
107
108
109
110
111
...
368
369
370
371
372
373
374

375
376

377
378

379

380
381
382
383
384
385
386
...
425
426
427
428
429
430
431

432
433
434
435
436
437
438
...
631
632
633
634
635
636
637
638

639

640
641
642
643
644
645
646
#  include <unistd.h>
#endif
#ifdef HAVE_INTTYPES_H
#  include <inttypes.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>









#ifdef NO_STDLIB_H
#include "../compat/stdlib.h"
#else
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
................................................................................
#endif

#include "exp_win.h"

#include "exp_tty_in.h"
#include "exp_rename.h"
#include "exp_pty.h"


void expDiagLog();
void expDiagLogPtr();

#include <errno.h>
/*extern char *sys_errlist[];*/

................................................................................
#define R_OK 04
#define W_OK 02
#endif

int
exp_getptymaster()
{

	char *hex, *bank;
	struct stat stat_buf;

	int master = -1;
	int slave = -1;

	int num;


	exp_pty_error = 0;

#define TEST_PTY 1

#if defined(HAVE_PTMX) || defined(HAVE_PTMX_BSD)
#undef TEST_PTY
................................................................................
#endif

#if defined(HAVE_PTC) && !defined(HAVE__GETPTY)	/* old SGI, version 3 */
#undef TEST_PTY
	master = open("/dev/ptc", O_RDWR);
	if (master >= 0) {
		int ptynum;


		if (fstat(master, &stat_buf) < 0) {
			close(master);
			return(-1);
		}
		ptynum = minor(stat_buf.st_rdev);
		sprintf(slave_name,"/dev/ttyq%d",ptynum);
................................................................................

int
exp_getptyslave(
    int ttycopy,
    int ttyinit,
    CONST char *stty_args)
{
	int slave, slave2;

	char buf[10240];


	if (0 > (slave = open(slave_name, O_RDWR))) {
		static char buf[500];
		exp_pty_error = buf;
		sprintf(exp_pty_error,"open(%s,rw) = %d (%s)",slave_name,slave,expErrnoMsg(errno));
		return(-1);
	}






>
>
>
>
>
>
>
>







 







>







 







>

<
>


>

>







 







>







 







|
>

>







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396
397
398
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
#  include <unistd.h>
#endif
#ifdef HAVE_INTTYPES_H
#  include <inttypes.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if defined(HAVE_OPENPTY)
#include <termios.h>
#if defined(HAVE_LIBUTIL_H)
#include <libutil.h>
#else
#include <pty.h>
#endif
#endif

#ifdef NO_STDLIB_H
#include "../compat/stdlib.h"
#else
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
................................................................................
#endif

#include "exp_win.h"

#include "exp_tty_in.h"
#include "exp_rename.h"
#include "exp_pty.h"
#include "exp_int.h"

void expDiagLog();
void expDiagLogPtr();

#include <errno.h>
/*extern char *sys_errlist[];*/

................................................................................
#define R_OK 04
#define W_OK 02
#endif

int
exp_getptymaster()
{
#if !defined(HAVE_CONVEX_GETPTY) && !defined(HAVE_PTYM) && !defined(HAVE_SCO_CLIST_PTYS) && defined(TEST_PTY)
	char *hex, *bank;

#endif
	int master = -1;
	int slave = -1;
#ifdef HAVE_SCO_CLIST_PTYS
	int num;
#endif

	exp_pty_error = 0;

#define TEST_PTY 1

#if defined(HAVE_PTMX) || defined(HAVE_PTMX_BSD)
#undef TEST_PTY
................................................................................
#endif

#if defined(HAVE_PTC) && !defined(HAVE__GETPTY)	/* old SGI, version 3 */
#undef TEST_PTY
	master = open("/dev/ptc", O_RDWR);
	if (master >= 0) {
		int ptynum;
		struct stat stat_buf;

		if (fstat(master, &stat_buf) < 0) {
			close(master);
			return(-1);
		}
		ptynum = minor(stat_buf.st_rdev);
		sprintf(slave_name,"/dev/ttyq%d",ptynum);
................................................................................

int
exp_getptyslave(
    int ttycopy,
    int ttyinit,
    CONST char *stty_args)
{
	int slave;
#if defined(HAVE_PTMX_BSD)
	char buf[10240];
#endif

	if (0 > (slave = open(slave_name, O_RDWR))) {
		static char buf[500];
		exp_pty_error = buf;
		sprintf(exp_pty_error,"open(%s,rw) = %d (%s)",slave_name,slave,expErrnoMsg(errno));
		return(-1);
	}