しらいです。

 file & directory 管理ツール FDclone 2.07 の patch その 5
です。

MD5 (FD-2.07.patch) = 79e2286ea0bbcb7863a42b2c79375687

Submitted-by: shirai@chandra2
Archive-name: FD-2.07.patch/part05

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is `FD-2.07.shar.05' (part 5 of FD-2.07.patch).
# Do not concatenate these parts, unpack them in order with `/bin/sh'.
# File `FD-2.07.patch' is being continued...
#
echo=echo
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if test ! -r _sh01053/seq; then
  $echo 'Please unpack part 1 first!'
  exit 1
fi
shar_sequence=`cat _sh01053/seq`
if test "$shar_sequence" != 5; then
  $echo 'Please unpack part' "$shar_sequence" 'next!'
  exit 1
fi
if test ! -f _sh01053/new; then
  $echo 'x -' 'STILL SKIPPING' 'FD-2.07.patch'
else
  $echo 'x -' 'continuing file' 'FD-2.07.patch'
  sed 's/^X//' << 'SHAR_EOF' >> FD-2.07.patch &&
+               VOID_C Xdup2(fd, STDIN_FILENO, pathstdin);
+               VOID_C Xdup2(fd, STDOUT_FILENO, pathstdout);
+               VOID_C Xdup2(fd, STDERR_FILENO, pathstderr);
+               term_safeclose(fd, _PATH_DEVNULL);
+       }
+# endif
+
+       return(pid);
+#endif /* USESETSID */
+}
+
+/*ARGSUSED*/
+static VOID NEAR Xgrantpt(fd, path)
+int fd;
+char *path;
+{
+#ifdef USEDEVPTMX
+       extern int grantpt __P_((int));         /* for Linux */
+
+       VOID_C grantpt(fd);
+#else  /* !USEDEVPTMX */
+       struct group *grp;
+       gid_t gid;
+
+       gid = ((grp = getgrnam(TTY_GROUP))) ? grp -> gr_gid : (gid_t)-1;
+
+       VOID_C chown(path, getuid(), gid);
+       VOID_C chmod(path, 0620);
+#endif /* !USEDEVPTMX */
+}
+
+/*ARGSUSED*/
+static VOID NEAR Xunlockpt(fd, path)
+int fd;
+char *path;
+{
+#ifdef USEDEVPTMX
+# ifdef        TIOCSPTLCK
+       int n;
+
+       n = 0;
+       VOID_C Xioctl(fd, TIOCSPTLCK, &n);
+# else
+       VOID_C unlockpt(fd);
+# endif
+#else  /* !USEDEVPTMX */
+# ifdef        BSD44
+       VOID_C revoke(path);
+# endif
+#endif /* !USEDEVPTMX */
+}
+
+/*ARGSUSED*/
+static int NEAR Xptsname(fd, path, spath, size)
+int fd;
+char *path, *spath;
+ALLOC_T size;
+{
+#ifdef USEDEVPTMX
+# ifdef        TIOCGPTN
+       int n;
+
+       if (Xioctl(fd, TIOCGPTN, &n) < 0) return(-1);
+       snprintf2(spath, size, "%s/%d", _PATH_DEVPTS, n);
+# else
+       if (!(path = ptsname(fd))) return(-1);
+       snprintf2(spath, size, "%s", path);
+# endif
+#else  /* !USEDEVPTMX */
+       snprintf2(spath, size, "%s", path);
+       if ((path = strrchr(spath, '/'))) *(++path) = 't';
+#endif /* !USEDEVPTMX */
+
+       return(0);
+}
+
+int Xopenpty(amaster, spath, size)
+int *amaster;
+char *spath;
+ALLOC_T size;
+{
+       char path[MAXPATHLEN];
+       int master, slave;
+
+#ifdef USEDEVPTMX
+       snprintf2(path, sizeof(path), "%s", _PATH_DEVPTMX);
+       if ((master = Xopen(path, O_RDWR, 0, XF_IGNOREERR)) < 0) return(-1);
+
+       Xgrantpt(master, path);
+       Xunlockpt(master, path);
+       if (Xptsname(master, path, spath, size) < 0
+       || (slave = Xopen(spath, O_RDWR | O_NOCTTY, 0, XF_IGNOREERR)) < 0) {
+               term_safeclose(master, pathpty);
+               return(-1);
+       }
+#else  /* !USEDEVPTMX */
+       char *cp1, *cp2;
+       int n;
+
+       n = snprintf2(path, sizeof(path), "%sXX", _PATH_PTY);
+       n -= 2;
+       master = slave = -1;
+       for (cp1 = pty_char1; *cp1; cp1++) {
+               path[n] = *cp1;
+               for (cp2 = pty_char2; *cp2; cp2++) {
+                       path[n + 1] = *cp2;
+                       master = Xopen(path, O_RDWR, 0, XF_IGNOREERR);
+                       if (master < 0) {
+                               if (errno == ENOENT) break;
+                               continue;
+                       }
+
+                       VOID_C Xptsname(master, path, spath, size);
+                       Xgrantpt(master, spath);
+                       Xunlockpt(master, spath);
+                       slave = Xopen(spath, O_RDWR, 0, XF_IGNOREERR);
+                       if (slave >= 0) break;
+
+                       term_safeclose(master, pathpty);
+               }
+
+               if (master >= 0 && slave >= 0) break;
+       }
+
+       if (!*cp1) {
+               errno = ENOENT;
+               return(-1);
+       }
+#endif /* !USEDEVPTMX */
+
+       *amaster = master;
+       term_safeclose(slave, pathpty);
+
+       return(0);
+}
+
+#if    defined (IRIX) || defined (DECOSF1V2) || defined (DECOSF1V3)
+#undef I_PUSH
+#endif
+
+int Xlogin_tty(path, tty, ws)
+char *path, *tty, *ws;
+{
+       int fd;
+
+       VOID_C Xsetsid();
+
+       Xclose(STDIN_FILENO, pathstdin);
+       Xclose(STDOUT_FILENO, pathstdout);
+       Xclose(STDERR_FILENO, pathstderr);
+       if ((fd = Xopen(path, O_RDWR, 0, XF_IGNOREERR)) < 0) return(-1);
+
+#ifdef I_PUSH
+       if (Xioctl(fd, I_PUSH, "ptem") < 0
+       || Xioctl(fd, I_PUSH, "ldterm") < 0) {
+               Xclose(fd, path);
+               return(-1);
+       }
+# if   defined (SOLARIS) || defined (NEWS_OS6)
+       VOID_C Xioctl(fd, I_PUSH, "ttcompat");
+# endif
+#endif /* I_PUSH */
+#ifdef TIOCSCTTY
+       if (Xioctl(fd, TIOCSCTTY, NULL) < 0) {
+               Xclose(fd, path);
+               return(-1);
+       }
+#endif
+
+       VOID_C Xdup2(fd, STDIN_FILENO, pathstdin);
+       VOID_C Xdup2(fd, STDOUT_FILENO, pathstdout);
+       VOID_C Xdup2(fd, STDERR_FILENO, pathstderr);
+       term_loadtermio(fd, tty, ws);
+       term_safeclose(fd, path);
+
+       return(0);
+}
+
+p_id_t Xforkpty(fdp, tty, ws)
+int *fdp;
+char *tty, *ws;
+{
+       char path[MAXPATHLEN];
+       p_id_t pid;
+       u_char uc;
+       int n, fds[2];
+
+       if (Xpipe(fds) < 0) return((p_id_t)-1);
+
+       if (Xopenpty(fdp, path, sizeof(path)) < 0) {
+               pid = (p_id_t)-1;
+       }
+       else if ((pid = Xfork()) < (p_id_t)0) term_safeclose(*fdp, pathpty);
+       else if (pid) VOID_C Xread(fds[0], &uc, sizeof(uc), -1, NULL);
+       else {
+               term_safeclose(*fdp, pathpty);
+               n = Xlogin_tty(path, tty, ws);
+               uc = '\n';
+               VOID_C Xwrite(fds[1], &uc, sizeof(uc), -1, NULL);
+               if (n < 0) _exit(1);
+       }
+
+       term_safeclose(fds[0], NULL);
+       term_safeclose(fds[1], NULL);
+
+       return(pid);
+}
+#endif /* !_NOPTY */
diff -urNP ../FD-2.06d/shell.c ./shell.c
--- ../FD-2.06d/shell.c Tue May 10 00:00:00 2005
+++ ./shell.c   Thu May 26 00:00:00 2005
@@ -16,6 +16,10 @@
X #include "system.h"
X #endif
X 
+#ifndef        _NOPTY
+#include "termemu.h"
+#endif
+
X extern int mark;
X extern off_t marksize;
X extern char fullpath[];
@@ -1594,6 +1598,9 @@
X       if (history[n][size]) free(history[n][size]);
X       for (i = size; i > 0; i--) history[n][i] = history[n][i - 1];
X       history[n][0] = s;
+#ifndef        _NOPTY
+       sendparent(TE_SETHISTORY, n, s, uniq);
+#endif
X 
X       return(1);
X }
diff -urNP ../FD-2.06d/system.c ./system.c
--- ../FD-2.06d/system.c        Tue May 10 00:00:00 2005
+++ ./system.c  Thu May 26 00:00:00 2005
@@ -101,6 +101,7 @@
X #include "term.h"
X extern VOID calcwin __P_((VOID_A));
X extern VOID main_fd __P_((char **));
+extern VOID setlinecol __P_((VOID_A));
X extern VOID checkscreen __P_((int, int));
X # ifdef       SIGWINCH
X extern VOID pollscreen __P_((int));
@@ -152,9 +153,12 @@
X # define      DOSFDOFFSET     (1 << (8 * sizeof(int) - 2))
X # endif
X extern char *deftmpdir;
-# define       Xttyiomode      ttyiomode
-# define       Xstdiomode      stdiomode
-# define       Xtermmode       termmode
+# ifndef       _NOPTY
+#include "termemu.h"
+extern VOID sendparent __P_((int, ...));
+extern char *ptyterm;
+extern int parentfd;
+# endif
X #else /* !FD */
X # ifdef       __TURBOC__
X extern unsigned _stklen = 0x8000;
@@ -346,7 +350,7 @@
X extern VOID checkmail __P_((int));
X # endif
X # ifndef      NOALIAS
-extern VOID NEAR freealias __P_((shaliastable *));
+extern VOID freealias __P_((shaliastable *));
X extern int checkalias __P_((syntaxtree *, char *, int, int));
X # endif
X # ifndef      NOJOB
@@ -2389,7 +2393,7 @@
X # if  !MSDOS && defined (FD)
X               freeterment();
X # endif
-               VOID_C closetty();
+               closetty(&ttyio, &ttyout);
X               muntrace();
X       }
X #endif        /* DEBUG */
@@ -2683,7 +2687,7 @@
X       p_id_t pid;
X       int i, stop;
X 
-       if ((pid = fork()) < (p_id_t)0) return((p_id_t)-1);
+       if ((pid = Xfork()) < (p_id_t)0) return((p_id_t)-1);
X # ifdef       DEBUG
X       if (!pid) {
X               extern VOID (*__free_hook) __P_((VOID_P));
@@ -2832,7 +2836,7 @@
X #  endif      /* USESGTTY */
X               if (interactive && !nottyout) {
X #  ifdef      FD
-                       Xstdiomode();
+                       stdiomode();
X #  endif
X                       dispjob(lastjob, stderr);
X               }
@@ -2950,6 +2954,9 @@
X               }
X       }
X #endif        /* FD && !_NOEDITMODE */
+#if    defined (FD) && !defined (_NOPTY)
+       sendparent(TE_SETSHFLAG, n, val);
+#endif
X }
X 
X static int NEAR getoption(argc, argv, isopt)
@@ -4386,6 +4393,9 @@
X       if (_putshellvar(s, len) < 0) return(-1);
X       exportlist = expandvar(exportlist, s, len);
X       exportvar = putvar(exportvar, strdup2(s), len);
+#if    defined (FD) && !defined (_NOPTY)
+       sendparent(TE_PUTEXPORTVAR, s, len);
+#endif
X 
X       return(0);
X }
@@ -4405,6 +4415,9 @@
X       if (_putshellvar(s, len) < 0) return(-1);
X       if (searchvar(exportlist, s, len, '\0') >= 0)
X               exportvar = putvar(exportvar, strdup2(s), len);
+#if    defined (FD) && !defined (_NOPTY)
+       sendparent(TE_PUTSHELLVAR, s, len);
+#endif
X 
X       return(0);
X }
@@ -4455,6 +4468,9 @@
X                       exportlist[i] = exportlist[i + 1];
X               exportlist[i] = NULL;
X       }
+#if    defined (FD) && !defined (_NOPTY)
+       sendparent(TE_UNSET, ident, len);
+#endif
X 
X       return(0);
X }
@@ -6107,8 +6123,23 @@
X char *path, *argv[], *envp[];
X #endif
X {
+#if    defined (FD) && !defined (_NOPTY)
+       char *cp;
+       int len;
+#endif
X       int fd, ret;
X 
+#if    defined (FD) && !defined (_NOPTY)
+       if (parentfd >= 0 && ptyterm && *ptyterm) {
+               len = sizeof("TERM") - 1;
+               cp = malloc2(len + strlen(ptyterm) + 2);
+               memcpy(cp, "TERM", len);
+               cp[len] = '=';
+               strcpy(&(cp[len + 1]), ptyterm);
+               envp = putvar(envp, cp, len);
+       }
+#endif /* FD && !_NOPTY */
+
X       execve(path, argv, envp);
X       if (errno != ENOEXEC) {
X               if (errno == EACCES) {
@@ -8005,6 +8036,9 @@
X       for (i = 1; n < argc; i++, n++) argvar[i] = strdup2(argv[n]);
X       argvar[i] = NULL;
X       freevar(var);
+#if    defined (FD) && !defined (_NOPTY)
+       sendparent(TE_SETVAR, &argvar, argvar);
+#endif
X 
X       return(RET_SUCCESS);
X }
@@ -8308,6 +8342,9 @@
X                       ret = RET_FAIL;
X                       ERRBREAK;
X               }
+#if    defined (FD) && !defined (_NOPTY)
+               sendparent(TE_SETEXPORT, argv[n]);
+#endif
X       }
X 
X       return(ret);
@@ -8334,6 +8371,9 @@
X                       ret = RET_FAIL;
X                       ERRBREAK;
X               }
+#if    defined (FD) && !defined (_NOPTY)
+               sendparent(TE_SETRONLY, argv[n]);
+#endif
X       }
X 
X       return(ret);
@@ -9008,6 +9048,9 @@
X                       return(RET_FAIL);
X               }
X               free(dirstack[0]);
+# if   defined (FD) && !defined (_NOPTY)
+               sendparent(TE_POPVAR, &dirstack);
+# endif
X       }
X       else {
X               if (chdir3((trp -> comm) -> argv[1], 0) < 0) {
@@ -9023,6 +9066,9 @@
X       }
X       dirstack[0] = strdup2(path);
X       dodirs(trp);
+# if   defined (FD) && !defined (_NOPTY)
+       sendparent(TE_PUSHVAR, &dirstack, path);
+# endif
X 
X       return(RET_SUCCESS);
X }
@@ -9049,6 +9095,9 @@
X       memmove((char *)&(dirstack[0]), (char *)&(dirstack[1]),
X               i * sizeof(char *));
X       dodirs(trp);
+# if   defined (FD) && !defined (_NOPTY)
+       sendparent(TE_POPVAR, &dirstack);
+# endif
X 
X       return(RET_SUCCESS);
X }
@@ -9170,13 +9219,13 @@
X       }
X       else {
X               n = sigvecset(1);
-               Xttyiomode(0);
-               mode = Xtermmode(1);
+               ttyiomode(0);
+               mode = termmode(1);
X               shellmode = 0;
X               main_fd(&((trp -> comm) -> argv[1]));
X               shellmode = 1;
-               Xtermmode(mode);
-               Xstdiomode();
+               termmode(mode);
+               stdiomode();
X               sigvecset(n);
X       }
X 
@@ -9370,6 +9419,12 @@
X #endif
X       functr -> flags |= ST_TOP;
X       setshfunc(ident, functr);
+#if    defined (FD) && !defined (_NOPTY)
+       if (parentfd >= 0 && mypid == shellpid) {
+               sendparent(TE_ADDFUNCTION, ident, functr);
+               nownstree(functr);
+       }
+#endif
X 
X       return(RET_SUCCESS);
X }
@@ -9394,6 +9449,9 @@
X               shellfunc[i].func = shellfunc[i + 1].func;
X       }
X       shellfunc[i].ident = NULL;
+#if    defined (FD) && !defined (_NOPTY)
+       sendparent(TE_DELETEFUNCTION, ident, len);
+#endif
X 
X       return(0);
X }
@@ -10824,9 +10882,9 @@
X                               buf = readline(definput);
X                       }
X                       else {
-                               Xttyiomode(1);
+                               ttyiomode(1);
X                               buf = inputshellstr(ps, -1, NULL);
-                               Xstdiomode();
+                               stdiomode();
X                               if (!buf) continue;
X                               if (buf == (char *)-1) {
X                                       buf = NULL;
@@ -10900,8 +10958,7 @@
X # if  MSDOS
X               inittty(1);
X # endif
-               getwsize(0, 0);
-               calcwin();
+               checkscreen(0, 0);
X       }
X # ifndef      _NOCUSTOMIZE
X       saveorigenviron();
diff -urNP ../FD-2.06d/term.c ./term.c
--- ../FD-2.06d/term.c  Tue May 10 00:00:00 2005
+++ ./term.c    Thu May 26 00:00:00 2005
@@ -105,8 +105,6 @@
X # include <term.h>
X # define      tgetnum2(s)             (s)
X # define      tgetflag2(s)            (s)
-# define       tgoto2(s, p1, p2)       tparm(s, p2, p1, \
-                                       0, 0, 0, 0, 0, 0, 0)
X # define      TERM_pc                 pad_char
X # define      TERM_bc                 NULL
X # define      TERM_co                 columns
@@ -219,11 +217,9 @@
X extern int tgetnum __P_((char *));
X extern int tgetflag __P_((char *));
X extern char *tgetstr __P_((char *, char **));
-extern char *tgoto __P_((char *, int, int));
X extern int tputs __P_((char *, int, int (*)__P_((tputs_t))));
X # define      tgetnum2                tgetnum
X # define      tgetflag2               tgetflag
-# define       tgoto2                  tgoto
X # define      TERM_pc                 "pc"
X # define      TERM_bc                 "bc"
X # define      TERM_co                 "co"
@@ -477,7 +473,7 @@
X       "\033OA",             /* K_UP */
X       "\033OD",             /* K_LEFT */
X       "\033OC",             /* K_RIGHT */
-       "\033[4~",            /* K_HOME */
+       "\033[1~",            /* K_HOME */
X       "\b",                 /* K_BS */
X       NULL,                   /* K_F0 */
X       "\033[11~",           /* K_F(1) */
@@ -560,8 +556,8 @@
X       NULL,                   /* K_EOL */
X       NULL,                   /* K_ESF */
X       NULL,                   /* K_ESR */
-       "\033[5~",            /* K_PPAGE */
X       "\033[6~",            /* K_NPAGE */
+       "\033[5~",            /* K_PPAGE */
X       NULL,                   /* K_STAB */
X       NULL,                   /* K_CTAB */
X       NULL,                   /* K_CATAB */
@@ -582,7 +578,7 @@
X       NULL,                   /* K_COMM */
X       NULL,                   /* K_COPY */
X       NULL,                   /* K_CREAT */
-       "\033[1~",            /* K_END */
+       "\033[4~",            /* K_END */
X       NULL,                   /* K_EXIT */
X       NULL,                   /* K_FIND */
X       NULL,                   /* K_HELP */
@@ -613,8 +609,8 @@
X       "",                   /* T_METAMODE */
X       "",                   /* T_NOMETAMODE */
X #endif
-#if    MSDOS
X       "",                   /* T_SCROLL */
+#if    MSDOS
X       "",                   /* T_KEYPAD */
X       "",                   /* T_NOKEYPAD */
X       "\033[>5l",                /* T_NORMALCURSOR */
@@ -623,11 +619,6 @@
X       "\033[s",             /* T_SETCURSOR */
X       "\033[u",             /* T_RESETCURSOR */
X #else /* !MSDOS */
-# ifdef        USETERMINFO
-       "\033[%i%p1%d;%p2%dr",        /* T_SCROLL */
-# else
-       "\033[%i%d;%dr",      /* T_SCROLL */
-# endif
X # ifdef       BOW
X       /* hack for bowpad */
X       "",                   /* T_KEYPAD */
@@ -666,7 +657,7 @@
X #if   MSDOS
X       "\033[%d;%dH",                /* C_LOCATE */
X #else
-# if   defined (LINUX) || defined (USETERMINFO)
+# ifdef        USETERMINFO
X       "\033[%i%p1%d;%p2%dH",        /* C_LOCATE */
X # else
X       "\033[%i%d;%dH",      /* C_LOCATE */
@@ -681,7 +672,7 @@
X       "\n",                 /* C_DOWN */
X       "\033[C",             /* C_RIGHT */
X       "\b",                 /* C_LEFT */
-#if    !MSDOS && defined (USETERMINFO)
+#ifdef USETERMINFO
X       "\033[%p1%dA",                /* C_NUP */
X       "\033[%p1%dB",                /* C_NDOWN */
X       "\033[%p1%dC",                /* C_NRIGHT */
@@ -1113,7 +1104,7 @@
X # endif       /* !USESGTTY */
X #endif        /* !MSDOS */
X       if (!dumbterm) {
-               putterms(T_KEYPAD);
+               putterm(T_KEYPAD);
X               tflush();
X       }
X       isttyiomode = isnl + 1;
@@ -1151,7 +1142,7 @@
X # endif       /* !USESGTTY */
X #endif        /* !MSDOS */
X       if (!dumbterm) {
-               putterms(T_NOKEYPAD);
+               putterm(T_NOKEYPAD);
X               tflush();
X       }
X       isttyiomode = 0;
@@ -1167,8 +1158,10 @@
X 
X       oldmode = mode;
X       if (init >= 0 && mode != init) {
-               putterms((init) ? T_INIT : T_END);
-               tflush();
+               if (!dumbterm) {
+                       putterms((init) ? T_INIT : T_END);
+                       tflush();
+               }
X               mode = init;
X       }
X 
@@ -1320,7 +1313,7 @@
X # if  !MSDOS
X       if (!usegetcursor) return(-1);
X # endif
-       if (getxy(&x, &y) < 0) x = y = -1;
+       if (getxy(&x, &y) < 0) x = y = 0;
X # if  MSDOS
X       if ((cp = tparamstr(termstr[C_LOCATE], 0, 999))) {
X               for (i = 0; cp[i]; i++) bdos(0x06, cp[i], 0);
@@ -1335,7 +1328,7 @@
X       tflush();
X # endif
X       i = getxy(xp, yp);
-       if (x >= 0 && y >= 0) locate(x, y);
+       if (x > 0 && y > 0) locate(--x, --y);
X 
X       return(i);
X }
@@ -1343,10 +1336,7 @@
X int getxy(xp, yp)
X int *xp, *yp;
X {
-# if   !MSDOS
-       char *tty;
-# endif
-       char *format, buf[sizeof(SIZEFMT) + 4];
+       char *format, buf[sizeof(SIZEFMT) + 6];
X       int i, j, tmp, count, *val[2];
X 
X       format = SIZEFMT;
@@ -1356,14 +1346,14 @@
X               bdos(0x06, GETSIZE[i], 0);
X # else
X       if (!usegetcursor) return(-1);
-       saveterm(ttyio, &tty, NULL);
-       noecho2();
-       write(ttyio, GETSIZE, sizeof(GETSIZE) - 1);
+       tputs2(GETSIZE, 1);
+       tflush();
X # endif
X 
X       i = 0;
+       buf[i] = '\0';
X       do {
-               if (!kbhit2(WAITKEYPAD * 1000L)) break;
+               if (!kbhit2(WAITKEYPAD * 1000L * 2)) break;
X # if  MSDOS
X               buf[i] = bdos(0x07, 0x00, 0);
X # else
@@ -1383,10 +1373,6 @@
X               if (buf[i] == format[sizeof(SIZEFMT) - 2]) break;
X       }
X       keyflush();
-# if   !MSDOS
-       loadterm(ttyio, tty, NULL);
-       if (tty) free(tty);
-# endif
X       if (!i || buf[i] != format[sizeof(SIZEFMT) - 2]) return(-1);
X       buf[++i] = '\0';
X 
@@ -1902,7 +1888,7 @@
X       /* Hack for HP-UX 10.20 */
X       cp = NULL;
X       if (tgetstr2(&cp, TERM_AB) || tgetstr2(&cp, TERM_Sb)) {
-               if (termstr[T_FGCOLOR]) free(termstr[T_BGCOLOR]);
+               if (termstr[T_BGCOLOR]) free(termstr[T_BGCOLOR]);
X               termstr[T_BGCOLOR] = cp;
X       }
X # endif
@@ -2167,9 +2153,9 @@
X int initterm(VOID_A)
X {
X       if (!(termflags & F_TERMENT)) getterment(NULL);
+       termmode(1);
X       if (!dumbterm) {
-               putterms(T_KEYPAD);
-               termmode(1);
+               putterm(T_KEYPAD);
X               tflush();
X       }
X       termflags |= F_INITTERM;
@@ -2180,9 +2166,9 @@
X int endterm(VOID_A)
X {
X       if (!(termflags & F_INITTERM)) return(-1);
+       termmode(0);
X       if (!dumbterm) {
-               putterms(T_NOKEYPAD);
-               termmode(0);
+               putterm(T_NOKEYPAD);
X               tflush();
X       }
X       termflags &= ~F_INITTERM;
@@ -2190,6 +2176,15 @@
X       return(0);
X }
X 
+int putterm(n)
+int n;
+{
+       if (n < 0 || n >= MAXTERMSTR) return(-1);
+       if (!termstr[n]) return(0);
+
+       return(tputs2(termstr[n], 1));
+}
+
X #if   MSDOS
X # ifdef       USEVIDEOBIOS
X static int NEAR bioslocate(x, y)
@@ -2573,15 +2568,6 @@
X }
X # endif       /* !USEVIDEOBIOS */
X 
-int putterm(n)
-int n;
-{
-       if (n < 0 || n >= MAXTERMSTR) return(-1);
-       if (!termstr[n]) return(0);
-
-       return(cputs2(termstr[n]));
-}
-
X /*ARGSUSED*/
X int kbhit2(usec)
X long usec;
@@ -2601,9 +2587,9 @@
X       if (nextchar) return(1);
X       reg.x.ax = 0x4406;
X       reg.x.bx = ttyio;
-       putterms(T_METAMODE);
+       putterm(T_METAMODE);
X       int86(0x21, &reg, &reg);
-       putterms(T_NOMETAMODE);
+       putterm(T_NOMETAMODE);
X 
X       return((reg.x.flags & 1) ? 0 : reg.h.al);
X #else /* !NOTUSEBIOS */
@@ -2690,16 +2676,16 @@
X               if (strchr(specialkey, key >> 8)) break;
X               if ((top += 2) >= KEYBUFWORKMAX) top = KEYBUFWORKMIN;
X       }
-       putterms(T_METAMODE);
+       putterm(T_METAMODE);
X       ch = (bdos(0x07, 0x00, 0) & 0xff);
-       putterms(T_NOMETAMODE);
+       putterm(T_NOMETAMODE);
X       keybuftop = getkeybuf(KEYBUFWORKTOP);
X       if (!(key & 0xff)) {
X               while (kbhit2(1000000L / SENSEPERSEC)) {
X                       if (keybuftop != getkeybuf(KEYBUFWORKTOP)) break;
-                       putterms(T_METAMODE);
+                       putterm(T_METAMODE);
X                       bdos(0x07, 0x00, 0);
-                       putterms(T_NOMETAMODE);
+                       putterm(T_NOMETAMODE);
X               }
X               ch = '\0';
X               nextchar = (key >> 8);
@@ -2873,13 +2859,11 @@
X       return(fputc(c & 0x7f, ttyout));
X }
X 
-int putterm(n)
+int tputs2(s, n)
+char *s;
X int n;
X {
-       if (n < 0 || n >= MAXTERMSTR) return(-1);
-       if (!termstr[n]) return(0);
-
-       return(tputs(termstr[n], 1, putch3));
+       return(tputs(s, n, putch3));
X }
X 
X int putterms(n)
@@ -2888,7 +2872,7 @@
X       if (n < 0 || n >= MAXTERMSTR) return(-1);
X       if (!termstr[n]) return(0);
X 
-       return(tputs(termstr[n], n_line, putch3));
+       return(tputs2(termstr[n], n_line));
X }
X 
X int kbhit2(usec)
@@ -3047,10 +3031,12 @@
X {
X       char *cp;
X 
-       if ((cp = tparamstr(termstr[T_SCROLL], s, e))) {
-               tputs(cp, n_line, putch3);
-               free(cp);
+       if (!(cp = tparamstr(termstr[T_SCROLL], s, e)) || !*cp) {
+               if (cp) free(cp);
+               return(-1);
X       }
+       tputs2(cp, 1);
+       free(cp);
X 
X       return(0);
X }
@@ -3058,20 +3044,14 @@
X int locate(x, y)
X int x, y;
X {
-# ifdef        DEBUG
X       char *cp;
X 
-       _mtrace_file = "tgoto(start)";
-       cp = tgoto2(termstr[C_LOCATE], x, y);
-       if (_mtrace_file) _mtrace_file = NULL;
-       else {
-               _mtrace_file = "tgoto(end)";
-               malloc(0);      /* dummy malloc */
+       if (!(cp = tparamstr(termstr[C_LOCATE], y, x)) || !*cp) {
+               if (cp) free(cp);
+               return(-1);
X       }
-       tputs(cp, n_line, putch3);
-# else
-       tputs(tgoto2(termstr[C_LOCATE], x, y), n_line, putch3);
-# endif
+       tputs2(cp, 1);
+       free(cp);
X 
X       return(0);
X }
@@ -3116,10 +3096,10 @@
X 
X       if (dumbterm) /*EMPTY*/;
X       else if (usegetcursor || x < 0 || y < 0) {
-               setscroll(-1, -1);
-               if (maxlocate(&ty, &tx) >= 0) {
-                       x = tx;
-                       y = ty;
+               VOID_C setscroll(-1, -1);
+               if (maxlocate(&ty, &tx) >= 0 && (tx > x || ty > y)) {
+                       if (tx > x) x = tx;
+                       if (ty > y) y = ty;
X                       VOID_C setwsize(ttyio, x, y);
X               }
X       }
@@ -3135,7 +3115,7 @@
X       if (n_line <= 0 || (ymax > 0 && n_line < ymax))
X               return("Line size too small");
X 
-       if (xmax > 0 && ymax > 0) setscroll(-1, n_line - 1);
+       if (xmax > 0 && ymax > 0) VOID_C setscroll(-1, -1);
X 
X       return(NULL);
X }
@@ -3231,14 +3211,14 @@
X       }
X 
X       if ((cp = tparamstr(termstr[T_FGCOLOR], fg, 0))) {
-               cputs2(cp);
+               tputs2(cp, 1);
X               free(cp);
X       }
X       else cprintf2("\033[%dm", fg + ANSI_NORMAL);
X 
X       if (bg < 0) /*EMPTY*/;
X       else if ((cp = tparamstr(termstr[T_BGCOLOR], bg, 0))) {
-               cputs2(cp);
+               tputs2(cp, 1);
X               free(cp);
X       }
X       else cprintf2("\033[%dm", bg + ANSI_REVERSE);
@@ -3252,13 +3232,9 @@
X       char *cp;
X 
X       if (n1 < 0 || !termstr[n1] || !(cp = tparamstr(termstr[n1], c, c)))
-               while (c--) putterm(n2);
+               while (c--) putterms(n2);
X       else {
-#if    MSDOS
-               cputs2(cp);
-#else
-               tputs(cp, 1, putch3);
-#endif
+               tputs2(cp, n_line);
X               free(cp);
X       }
X 
diff -urNP ../FD-2.06d/term.h ./term.h
--- ../FD-2.06d/term.h  Tue May 10 00:00:00 2005
+++ ./term.h    Thu May 26 00:00:00 2005
@@ -184,12 +184,14 @@
X #endif
X extern int initterm __P_((VOID_A));
X extern int endterm __P_((VOID_A));
+extern int putterm __P_((int));
X extern int putch2 __P_((int));
X extern int cputs2 __P_((char *));
-extern int putterm __P_((int));
X #if   MSDOS
+#define        tputs2(s,n)     cputs2(s)
X #define       putterms        putterm
X #else
+extern int tputs2 __P_((char *, int));
X extern int putterms __P_((int));
X #endif
X extern int kbhit2 __P_((long));
@@ -233,4 +235,4 @@
X #define       ANSI_NORMAL     30
X #define       ANSI_REVERSE    40
X 
-#endif /* __TERM_H_ */
+#endif /* !__TERM_H_ */
diff -urNP ../FD-2.06d/termemu.c ./termemu.c
--- ../FD-2.06d/termemu.c       Thu Jan  1 09:00:00 1970
+++ ./termemu.c Thu May 26 00:00:00 2005
@@ -0,0 +1,856 @@
+/*
+ *     termemu.c
+ *
+ *     terminal emulation
+ */
+
+#include "fd.h"
+#ifndef        _NOPTY
+
+#include <fcntl.h>
+#include <sys/time.h>
+#include "func.h"
+#include "kanji.h"
+#include "termemu.h"
+
+#ifdef USESELECTH
+#include <sys/select.h>
+#endif
+
+#ifdef _NOORIGSHELL
+#include <signal.h>
+#include "termio.h"
+#include "wait.h"
+#else
+#include "system.h"
+# ifndef       NOJOB
+extern jobtable *joblist;
+extern int maxjobs;
+# endif
+#endif
+
+#ifndef        FD_SET
+typedef struct fd_set {
+       u_int fds_bits[1];
+} fd_set;
+# define       FD_ZERO(p)      (((p) -> fds_bits[0]) = 0)
+# define       FD_SET(n, p)    (((p) -> fds_bits[0]) |= ((u_int)1 << (n)))
+#endif /* !FD_SET */
+
+extern int hideclock;
+extern int internal_status;
+
+int ptymode = 0;
+char *ptyterm = NULL;
+int ptymenukey = -1;
+ptyinfo_t ptylist[MAXWINDOWS];
+p_id_t emupid = (p_id_t)0;
+int emufd = -1;
+int parentfd = -1;
+char *ptytmpfile = NULL;
+
+static VOID NEAR doscroll __P_((int, int, int, int));
+static int NEAR genbackend __P_((VOID_A));
+static VOID NEAR sendvar __P_((int, char **));
+#ifndef        _NOORIGSHELL
+static VOID NEAR sendheredoc __P_((int, heredoc_t *));
+static VOID NEAR sendrlist __P_((int, redirectlist *));
+static VOID NEAR sendcommand __P_((int, command_t *, syntaxtree *));
+static VOID NEAR sendstree __P_((int, syntaxtree *));
+#endif
+static VOID NEAR awakechild __P_((char *, char *, int));
+#if    !defined (_NOORIGSHELL) && !defined (NOJOB)
+static int trap_hup __P_((VOID_A));
+static int NEAR recvmacro __P_((char **, char **, int *));
+#endif
+static int NEAR callmacro __P_((char *, char *, int));
+
+
+static VOID NEAR doscroll(n, c, x, y)
+int n, c, x, y;
+{
+       Xlocate(x, y);
+       while (c--) Xputterms(n);
+}
+
+VOID regionscroll(n, c, x, y, min, max)
+int n, c, x, y, min, max;
+{
+       int y1, y2;
+
+       if (min < 0) min = 0;
+       if (max < 0) max = n_line - 1;
+       if (min <= 0 && max >= n_line - 1) {
+               doscroll(n, c, x, y);
+               return;
+       }
+
+       if (Xsetscroll(min, max) >= 0) {
+               doscroll(n, c, x, y);
+               Xsetscroll(-1, -1);
+               Xlocate(x, y);
+               return;
+       }
+
+       y1 = y2 = -1;
+       switch(n) {
+               case C_DOWN:
+               case C_SCROLLFORW:
+               case C_NEWLINE:
+                       if (y != max) break;
+                       y1 = min;
+                       if (max < n_line - 1) y2 = max - c + 1;
+                       break;
+               case C_UP:
+               case C_SCROLLREV:
+                       if (y != min) break;
+                       if (max < n_line - 1) y1 = max - c + 1;
+                       y2 = min;
+                       break;
+               case L_DELETE:
+                       if (max >= n_line - 1) break;
+                       y1 = y;
+                       y2 = max - c + 1;
+                       break;
+               case L_INSERT:
+                       if (max >= n_line - 1) break;
+                       y1 = max - c + 1;
+                       y2 = y;
+                       break;
+               default:
+                       break;
+       }
+
+       if (y1 < 0 && y2 < 0) doscroll(n, c, x, y);
+       else {
+               n = (y1 < y2) ? y1 : y2;
+               if (c > max - n + 1) c = max - n + 1;
+               if (y1 > 0) doscroll(L_DELETE, c, 0, y1);
+               if (y2 > 0) doscroll(L_INSERT, c, 0, y2);
+               Xlocate(x, y);
+       }
+}
+
+int selectpty(fd, fds, result, timeout)
+int fd, fds[];
+char result[];
+int timeout;
+{
+       fd_set readfds;
+       struct timeval tv, *t;
+       int i, n, max;
+
+       max = -1;
+       FD_ZERO(&readfds);
+       if (fd < 0) max = 0;
+       else {
+               max = fd;
+               FD_SET(fd, &readfds);
+       }
+       for (i = 0; i < MAXWINDOWS; i++) {
+               if (!(ptylist[i].pid)) continue;
+               if (fds[i] > max) max = fds[i];
+               FD_SET(fds[i], &readfds);
+       }
+
+       if (!max) return(0);
+
+       if (timeout < 0) t = NULL;
+       else if (!timeout) {
+               tv.tv_sec = 0L;
+               tv.tv_usec = 1L;
+               t = &tv;
+       }
+       else {
+               tv.tv_sec = (long)timeout;
+               tv.tv_usec = 0L;
+               t = &tv;
+       }
+
+       if ((n = select(max + 1, &readfds, NULL, NULL, t)) < 0) return(-1);
+       for (i = 0; i < MAXWINDOWS; i++)
+               result[i] = (ptylist[i].pid && FD_ISSET(fds[i], &readfds))
+                       ? 1 : 0;
+       if (fd >= 0) result[i] = (FD_ISSET(fd, &readfds)) ? 1 : 0;
+
+       return(n);
+}
+
+static int NEAR genbackend(VOID_A)
+{
+       char path[MAXPATHLEN];
+       p_id_t pid;
+       int i, fds[2];
+
+       if (emupid) return(0);
+
+       if (pipe(fds) < 0) return(-1);
+       VOID_C fcntl(fds[0], F_SETFL, O_NONBLOCK);
+       VOID_C fcntl(fds[1], F_SETFL, O_NONBLOCK);
+
+       for (i = 0; i < MAXWINDOWS; i++) {
+               if (Xopenpty(&(ptylist[i].fd), path, sizeof(path)) < 0) break;
+               ptylist[i].pid = (p_id_t)0;
+               ptylist[i].path = strdup2(path);
+               ptylist[i].pipe = -1;
+               ptylist[i].status = 0;
+       }
+
+       if (i < MAXWINDOWS || (pid = Xfork()) < (p_id_t)0) {
+               safeclose(fds[0]);
+               safeclose(fds[1]);
+               while (--i >= 0) {
+                       free(ptylist[i].path);
+                       ptylist[i].path = NULL;
+                       safeclose(ptylist[i].fd);
+                       ptylist[i].fd = -1;
+               }
+               return(-1);
+       }
+
+       if (!pid) {
+#ifndef        _NOORIGSHELL
+               mypid = getpid();
+#endif
+               safeclose(fds[1]);
+               emufd = fds[0];
+               emupid = (p_id_t)0;
+               for (i = 0; i < MAXWINDOWS; i++) {
+                       free(ptylist[i].path);
+                       ptylist[i].path = NULL;
+                       resetptyterm(i, 1);
+               }
+               resetptyterm(i, 1);
+
+               backend();
+               for (i = 0; i < MAXWINDOWS; i++) safeclose(ptylist[i].fd);
+               _exit(0);
+       }
+
+       safeclose(fds[0]);
+       emufd = fds[1];
+       emupid = pid;
+       for (i = 0; i < MAXWINDOWS; i++) {
+               safeclose(ptylist[i].fd);
+               ptylist[i].fd = -1;
+       }
+
+       return(0);
+}
+
+VOID syncptyout(VOID_A)
+{
+       char *tty;
+
+       if (parentfd < 0) return;
+
+       savetermio(ttyio, &tty, NULL);
+       keyflush();
+       noecho2();
+       tputs2("\033[99n", 1);
+       tflush();
+       VOID_C getch2();
+       keyflush();
+       loadtermio(ttyio, tty, NULL);
+       if (tty) free(tty);
+}
+
+int recvbuf(fd, buf, nbytes)
+int fd;
+VOID_P buf;
+int nbytes;
+{
+       char *cp;
+       int n;
+
+       cp = (char *)buf;
+       for (;;) {
+               if ((n = sureread(fd, cp, nbytes)) >= nbytes) {
+                       errno = 0;
+                       return(0);
+               }
+               else if (n <= 0) break;
+               cp += n;
+               nbytes -= n;
+       }
+
+       return(-1);
+}
+
+VOID sendbuf(fd, buf, nbytes)
+int fd;
+VOID_P buf;
+int nbytes;
+{
+       VOID_C surewrite(fd, buf, nbytes);
+}
+
+int recvword(fd, np)
+int fd, *np;
+{
+       short w;
+
+       if (recvbuf(fd, &w, sizeof(w)) < 0) return(-1);
+       *np = (int)w;
+
+       return(0);
+}
+
+VOID sendword(fd, n)
+int fd, n;
+{
+       short w;
+
+       w = (short)n;
+       sendbuf(fd, &w, sizeof(w));
+}
+
+int recvstring(fd, cpp)
+int fd;
+char **cpp;
+{
+       char *cp;
+       ALLOC_T len;
+
+       if (recvbuf(fd, &cp, sizeof(cp)) < 0) return(-1);
+       if (cp) {
+               if (recvbuf(fd, &len, sizeof(len)) < 0) return(-1);
+               cp = malloc2(len + 1);
+               if (recvbuf(fd, cp, len) < 0) {
+                       free(cp);
+                       return(-1);
+               }
+               cp[len] = '\0';
+       }
+       *cpp = cp;
+
+       return(0);
+}
+
+VOID sendstring(fd, s)
+int fd;
+char *s;
+{
+       ALLOC_T len;
+
+       sendbuf(fd, &s, sizeof(s));
+       if (!s) return;
+
+       len = strlen(s);
+       sendbuf(fd, &len, sizeof(len));
+       if (len) sendbuf(fd, s, len);
+}
+
+static VOID NEAR sendvar(fd, var)
+int fd;
+char **var;
+{
+       int i, c;
+
+       sendbuf(fd, &var, sizeof(var));
+       if (!var) return;
+
+       c = countvar(var);
+       sendbuf(fd, &c, sizeof(c));
+       for (i = 0; i < c; i++) sendstring(fd, var[i]);
+}
+
+#ifndef        _NOORIGSHELL
+static VOID NEAR sendheredoc(fd, hdp)
+int fd;
+heredoc_t *hdp;
+{
+       sendbuf(fd, &hdp, sizeof(hdp));
+       if (!hdp) return;
+
+       sendbuf(fd, hdp, sizeof(*hdp));
+       sendstring(fd, hdp -> eof);
+       sendstring(fd, hdp -> filename);
+       sendstring(fd, hdp -> buf);
+}
+
+static VOID NEAR sendrlist(fd, rp)
+int fd;
+redirectlist *rp;
+{
+       sendbuf(fd, &rp, sizeof(rp));
+       if (!rp) return;
+
+       sendbuf(fd, rp, sizeof(*rp));
+       if (rp -> type & MD_HEREDOC)
+               sendheredoc(fd, (heredoc_t *)(rp -> filename));
+       else sendstring(fd, rp -> filename);
+       sendrlist(fd, rp -> next);
+}
+
+static VOID NEAR sendcommand(fd, comm, trp)
+int fd;
+command_t *comm;
+syntaxtree *trp;
+{
+       sendbuf(fd, &comm, sizeof(comm));
+       if (!comm) return;
+
+       if (trp -> flags & ST_NODE) {
+               sendstree(fd, (syntaxtree *)comm);
+               return;
+       }
+
+       sendbuf(fd, comm, sizeof(*comm));
+       if (!isstatement(comm)) sendvar(fd, comm -> argv);
+       else sendstree(fd, (syntaxtree *)(comm -> argv));
+       sendrlist(fd, comm -> redp);
+}
+
+static VOID NEAR sendstree(fd, trp)
+int fd;
+syntaxtree *trp;
+{
+       sendbuf(fd, &trp, sizeof(trp));
+       if (!trp) return;
+
+       sendbuf(fd, trp, sizeof(*trp));
+       sendcommand(fd, trp -> comm, trp);
+       sendstree(fd, trp -> next);
+}
+#endif /* !_NOORIGSHELL */
+
+#ifdef USESTDARGH
+/*VARARGS1*/
+VOID sendparent(int cmd, ...)
+#else
+/*VARARGS1*/
+VOID sendparent(cmd, va_alist)
+int cmd;
+va_dcl
+#endif
+{
+#ifndef        _NOORIGSHELL
+       syntaxtree *trp;
+#endif
+#ifndef        _NOARCHIVE
+       launchtable *lp;
+       archivetable *ap;
+#endif
+#ifdef _USEDOSEMU
+       devinfo *devp;
+#endif
+       bindtable *bindp;
+       keyseq_t *keyp;
+       va_list args;
+       char *cp, *func1, *func2, ***varp, **var;
+       u_char uc;
+       int n, fd, val;
+
+       if (parentfd < 0) return;
+#ifndef        _NOORIGSHELL
+       if (mypid != shellpid) return;
+#endif
+
+       fd = parentfd;
+       uc = cmd;
+       sendbuf(fd, &uc, sizeof(uc));
+
+       VA_START(args, cmd);
+       switch (cmd) {
+               case TE_SETVAR:
+                       varp = va_arg(args, char ***);
+                       var = va_arg(args, char **);
+                       sendbuf(fd, &varp, sizeof(varp));
+                       sendvar(fd, var);
+                       break;
+               case TE_PUSHVAR:
+                       varp = va_arg(args, char ***);
+                       cp = va_arg(args, char *);
+                       sendbuf(fd, &varp, sizeof(varp));
+                       sendstring(fd, cp);
+                       break;
+               case TE_POPVAR:
+                       varp = va_arg(args, char ***);
+                       sendbuf(fd, &varp, sizeof(varp));
+                       break;
+               case TE_CHDIR:
+#ifndef        _NOORIGSHELL
+               case TE_SETEXPORT:
+               case TE_SETRONLY:
+#endif
+#if    defined (_NOORIGSHELL) || !defined (NOALIAS)
+               case TE_DELETEALIAS:
+#endif
+#ifdef _NOORIGSHELL
+               case TE_DELETEFUNCTION:
+#endif
+                       cp = va_arg(args, char *);
+                       sendstring(fd, cp);
+                       break;
+#ifdef _NOORIGSHELL
+               case TE_PUTSHELLVAR:
+                       cp = va_arg(args, char *);
+                       func1 = va_arg(args, char *);
+                       n = va_arg(args, int);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendstring(fd, func1);
+                       sendstring(fd, cp);
+                       break;
+               case TE_ADDFUNCTION:
+                       cp = va_arg(args, char *);
+                       var = va_arg(args, char **);
+                       sendvar(fd, var);
+                       sendstring(fd, cp);
+                       break;
+#else  /* !_NOORIGSHELL */
+               case TE_PUTEXPORTVAR:
+               case TE_PUTSHELLVAR:
+               case TE_UNSET:
+               case TE_DELETEFUNCTION:
+                       cp = va_arg(args, char *);
+                       n = va_arg(args, int);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendstring(fd, cp);
+                       break;
+               case TE_SETSHFLAG:
+                       n = va_arg(args, int);
+                       val = va_arg(args, int);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendbuf(fd, &val, sizeof(val));
+                       break;
+               case TE_ADDFUNCTION:
+                       cp = va_arg(args, char *);
+                       trp = va_arg(args, syntaxtree *);
+                       sendstring(fd, cp);
+                       sendstree(fd, trp);
+                       break;
+#endif /* !_NOORIGSHELL */
+#if    defined (_NOORIGSHELL) || !defined (NOALIAS)
+               case TE_ADDALIAS:
+                       cp = va_arg(args, char *);
+                       func1 = va_arg(args, char *);
+                       sendstring(fd, func1);
+                       sendstring(fd, cp);
+                       break;
+#endif /* _NOORIGSHELL || !NOALIAS */
+               case TE_SETHISTORY:
+                       n = va_arg(args, int);
+                       cp = va_arg(args, char *);
+                       val = va_arg(args, int);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendbuf(fd, &val, sizeof(val));
+                       sendstring(fd, cp);
+                       break;
+               case TE_ADDKEYBIND:
+                       n = va_arg(args, int);
+                       bindp = va_arg(args, bindtable *);
+                       func1 = va_arg(args, char *);
+                       func2 = va_arg(args, char *);
+                       cp = va_arg(args, char *);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendbuf(fd, bindp, sizeof(*bindp));
+                       sendstring(fd, func1);
+                       sendstring(fd, func2);
+                       sendstring(fd, cp);
+                       break;
+               case TE_DELETEKEYBIND:
+#ifndef        _NOARCHIVE
+               case TE_DELETELAUNCH:
+               case TE_DELETEARCH:
+#endif
+#ifdef _USEDOSEMU
+               case TE_DELETEDRV:
+#endif
+#if    !defined (_NOORIGSHELL) && !defined (NOJOB)
+               case TE_CHANGESTATUS:
+#endif
+                       n = va_arg(args, int);
+                       sendbuf(fd, &n, sizeof(n));
+                       break;
+               case TE_SETKEYSEQ:
+                       keyp = va_arg(args, keyseq_t *);
+                       sendbuf(fd, &(keyp -> code), sizeof(keyp -> code));
+                       sendbuf(fd, &(keyp -> len), sizeof(keyp -> len));
+                       sendstring(fd, keyp -> str);
+                       break;
+#ifndef        _NOARCHIVE
+               case TE_ADDLAUNCH:
+                       n = va_arg(args, int);
+                       lp = va_arg(args, launchtable *);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendbuf(fd, lp, sizeof(*lp));
+                       sendstring(fd, lp -> ext);
+                       sendstring(fd, lp -> comm);
+                       sendvar(fd, lp -> format);
+                       sendvar(fd, lp -> lignore);
+                       sendvar(fd, lp -> lerror);
+                       break;
+               case TE_ADDARCH:
+                       n = va_arg(args, int);
+                       ap = va_arg(args, archivetable *);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendbuf(fd, &(ap -> flags), sizeof(ap -> flags));
+                       sendstring(fd, ap -> ext);
+                       sendstring(fd, ap -> p_comm);
+                       sendstring(fd, ap -> u_comm);
+                       break;
+#endif /* !_NOARCHIVE */
+#ifdef _USEDOSEMU
+               case TE_INSERTDRV:
+                       n = va_arg(args, int);
+                       devp = va_arg(args, devinfo *);
+                       sendbuf(fd, &n, sizeof(n));
+                       sendbuf(fd, devp, sizeof(*devp));
+                       sendstring(fd, devp -> name);
+                       break;
+#endif /* _USEDOSEMU */
+               default:
+                       break;
+       }
+       va_end(args);
+}
+
+static VOID NEAR awakechild(command, arg, flags)
+char *command, *arg;
+int flags;
+{
+       if (isttyiomode) {
+               flags |= F_TTYIOMODE;
+               if (isttyiomode > 1) flags |= F_TTYNL;
+       }
+
+       sendword(emufd, TE_AWAKECHILD);
+       sendword(emufd, win);
+       sendbuf(emufd, &flags, sizeof(flags));
+       sendstring(emufd, command);
+       sendstring(emufd, arg);
+}
+
+#if    !defined (_NOORIGSHELL) && !defined (NOJOB)
+static int trap_hup(VOID_A)
+{
+       int i;
+
+       for (i = 0; i < maxjobs; i++) {
+               if (!(joblist[i].pids)) continue;
+               Xkillpg(joblist[i].pids[0], SIGHUP);
+# ifdef        SIGCONT
+               Xkillpg(joblist[i].pids[0], SIGCONT);
+# endif
+       }
+
+       signal2(SIGHUP, SIG_DFL);
+       VOID_C kill(mypid, SIGHUP);
+       _exit(SIGHUP + 128);
+
+       return(0);
+}
+
+static int NEAR recvmacro(commandp, argp, flagsp)
+char **commandp, **argp;
+int *flagsp;
+{
+       char *command, *arg;
+       int flags;
+
+       Xttyiomode(1);
+       if (recvbuf(ttyio, &flags, sizeof(flags)) < 0
+       || recvstring(ttyio, &command) < 0)
+               return(-1);
+       if (recvstring(ttyio, &arg) < 0) {
+               if (command) free(command);
+               return(-1);
+       }
+
+       keyflush();
+       if (!(flags & F_TTYIOMODE)) Xstdiomode();
+       else if (!(flags & F_TTYNL)) Xttyiomode(0);
+
+       if (*commandp) free(*commandp);
+       if (*argp) free(*argp);
+       *commandp = command;
+       *argp = arg;
+       *flagsp = flags;
+
+       return(0);
+}
+#endif /* !_NOORIGSHELL && !NOJOB */
+
+static int NEAR callmacro(command, arg, flags)
+char *command, *arg;
+int flags;
+{
+       int i, n;
+
+       if (parentfd < 0) {
+               if (ptymode) {
+                       hideclock = 1;
+                       warning(0, NOPTY_K);
+               }
+               for (i = 0; i < MAXWINDOWS; i++) if (ptylist[i].pid) break;
+               if (i < MAXWINDOWS) {
+                       hideclock = 1;
+                       if (!yesno(KILL_K)) return(-1);
+                       killallpty();
+               }
+       }
+
+       if (flags & F_DOSYSTEM) n = dosystem(command);
+#ifdef _NOORIGSHELL
+       else if (flags & F_EVALMACRO) n = execusercomm(command, arg, flags);
+#endif
+       else n = execmacro(command, arg, flags);
+
+       return(n);
+}
+
+int ptymacro(command, arg, flags)
+char *command, *arg;
+int flags;
+{
+       p_id_t pid;
+       char *tty, *ws, path[MAXPATHLEN];
+       u_char uc;
+       int i, n, fd, fds[2];
+
+       if (!ptymode) return(callmacro(command, arg, flags));
+
+       if (ptylist[win].pid && emufd >= 0) {
+               awakechild(command, arg, flags);
+               return(frontend());
+       }
+
+       if (genbackend() < 0 || pipe(fds) < 0)
+               return(callmacro(command, arg, flags));
+       VOID_C fcntl(fds[0], F_SETFL, O_NONBLOCK);
+       VOID_C fcntl(fds[1], F_SETFL, O_NONBLOCK);
+
+       if (ptytmpfile) fd = -1;
+       else if ((fd = mktmpfile(path)) >= 0) {
+               ptytmpfile = strdup2(path);
+               Xclose(fd);
+       }
+
+       n = sigvecset(0);
+       if ((pid = Xfork()) < (p_id_t)0) {
+               if (fd >= 0 && ptytmpfile) {
+                       rmtmpfile(ptytmpfile);
+                       free(ptytmpfile);
+                       ptytmpfile = NULL;
+               }
+               sigvecset(n);
+               safeclose(fds[0]);
+               safeclose(fds[1]);
+               return(callmacro(command, arg, flags));
+       }
+
+       if (!pid) {
+#ifndef        _NOORIGSHELL
+               mypid = getpid();
+#endif
+               savetermio(ttyio, &tty, &ws);
+               if (Xlogin_tty(ptylist[win].path, tty, ws) < 0) _exit(1);
+               if (tty) free(tty);
+               if (ws) free(ws);
+               n_line = FILEPERROW;
+               VOID_C setwsize(STDIN_FILENO, n_column, n_line);
+
+               for (i = 0; i < MAXWINDOWS; i++) {
+                       ptylist[i].pid = (p_id_t)0;
+                       free(ptylist[i].path);
+                       ptylist[i].path = NULL;
+                       ptylist[i].pipe = -1;
+                       ptylist[i].status = 0;
+               }
+               emupid = (p_id_t)0;
+               safeclose(emufd);
+               emufd = -1;
+               dup2(STDIN_FILENO, ttyio);
+               maxfile = -1;
+
+               setdefterment();
+               setdefkeyseq();
+
+               safeclose(fds[0]);
+               parentfd = newdup(fds[1]);
+               closeonexec(parentfd);
+               uc = '\n';
+               sendbuf(parentfd, &uc, sizeof(uc));
+
+               for (;;) {
+                       syncptyout();
+                       setlinecol();
+                       n = callmacro(command, arg, flags);
+                       n = (n < 0) ? 1 :
+                               ((internal_status < -1) ? 4 : internal_status);
+#if    defined (_NOORIGSHELL) || defined (NOJOB)
+                       break;
+#else  /* !_NOORIGSHELL && !NOJOB */
+                       for (i = 0; i < maxjobs; i++)
+                               if (joblist[i].pids) break;
+                       if (i >= maxjobs) break;
+                       VOID_C signal2(SIGHUP, (sigcst_t)trap_hup);
+                       sendparent(TE_CHANGESTATUS, n);
+                       if (recvmacro(&command, &arg, &flags) < 0) break;
+#endif /* !_NOORIGSHELL && !NOJOB */
+               }
+
+               safeclose(parentfd);
+
+               _exit(n);
+       }
+
+       safeclose(fds[1]);
+       ptylist[win].pid = pid;
+       ptylist[win].pipe = fds[0];
+       ptylist[win].status = -1;
+
+       sigvecset(n);
+       if (recvbuf(ptylist[win].pipe, &uc, sizeof(uc)) < 0)
+               return(callmacro(command, arg, flags));
+
+       return(frontend());
+}
+
+VOID killpty(n, statusp)
+int n, *statusp;
+{
+       if (ptylist[n].pid) {
+               VOID_C Xkillpg(ptylist[n].pid, SIGHUP);
+#ifdef SIGCONT
+               VOID_C Xkillpg(ptylist[n].pid, SIGCONT);
+#endif
+               VOID_C waitstatus(ptylist[n].pid, 0, statusp);
+               ptylist[n].pid = (p_id_t)0;
+               ptylist[n].status = 0;
+               changewin(n, (p_id_t)0);
+       }
+
+       safeclose(ptylist[n].pipe);
+       ptylist[n].pipe = -1;
+}
+
+VOID killallpty(VOID_A)
+{
+       int i;
+
+       for (i = 0; i < MAXWINDOWS; i++) {
+               killpty(i, NULL);
+               free(ptylist[i].path);
+               ptylist[i].path = NULL;
+       }
+
+       if (emupid) {
+               VOID_C kill(emupid, SIGHUP);
+#ifdef SIGCONT
+               VOID_C kill(emupid, SIGCONT);
+#endif
+               VOID_C waitstatus(emupid, 0, NULL);
+               emupid = (p_id_t)0;
+       }
+       if (ptytmpfile) {
+               rmtmpfile(ptytmpfile);
+               free(ptytmpfile);
+               ptytmpfile = NULL;
+       }
+
+       safeclose(emufd);
+       emufd = -1;
+}
+#endif /* !_NOPTY */
diff -urNP ../FD-2.06d/termemu.h ./termemu.h
--- ../FD-2.06d/termemu.h       Thu Jan  1 09:00:00 1970
+++ ./termemu.h Thu May 26 00:00:00 2005
@@ -0,0 +1,57 @@
+/*
+ *     termemu.h
+ *
+ *     type definitions for "termemu.c"
+ */
+
+typedef struct _ptyinfo_t {
+       p_id_t pid;
+       char *path;
+       int fd;
+       int pipe;
+       int status;
+} ptyinfo_t;
+
+extern ptyinfo_t ptylist[];
+
+#define        TE_PUTCH2               (K_MAX + 1)
+#define        TE_CPUTS2               (K_MAX + 2)
+#define        TE_PUTTERM              (K_MAX + 3)
+#define        TE_PUTTERMS             (K_MAX + 4)
+#define        TE_SETSCROLL            (K_MAX + 5)
+#define        TE_LOCATE               (K_MAX + 6)
+#define        TE_CPUTNL               (K_MAX + 7)
+#define        TE_CHGCOLOR             (K_MAX + 8)
+#define        TE_MOVECURSOR           (K_MAX + 9)
+#define        TE_CHANGEWIN            (K_MAX + 10)
+#define        TE_CHANGEWSIZE          (K_MAX + 11)
+#define        TE_INSERTWIN            (K_MAX + 12)
+#define        TE_DELETEWIN            (K_MAX + 13)
+#define        TE_CHANGEKCODE          (K_MAX + 14)
+#define        TE_AWAKECHILD           (K_MAX + 99)
+
+#define        TE_SETVAR               1
+#define        TE_PUSHVAR              2
+#define        TE_POPVAR               3
+#define        TE_CHDIR                4
+#define        TE_PUTEXPORTVAR         5
+#define        TE_PUTSHELLVAR          6
+#define        TE_UNSET                7
+#define        TE_SETEXPORT            8
+#define        TE_SETRONLY             9
+#define        TE_SETSHFLAG            10
+#define        TE_ADDFUNCTION          11
+#define        TE_DELETEFUNCTION       12
+#define        TE_ADDALIAS             13
+#define        TE_DELETEALIAS          14
+#define        TE_SETHISTORY           15
+#define        TE_ADDKEYBIND           16
+#define        TE_DELETEKEYBIND        17
+#define        TE_SETKEYSEQ            18
+#define        TE_ADDLAUNCH            19
+#define        TE_DELETELAUNCH         20
+#define        TE_ADDARCH              21
+#define        TE_DELETEARCH           22
+#define        TE_INSERTDRV            23
+#define        TE_DELETEDRV            24
+#define        TE_CHANGESTATUS         99
diff -urNP ../FD-2.06d/termio.c ./termio.c
--- ../FD-2.06d/termio.c        Tue May 10 00:00:00 2005
+++ ./termio.c  Thu May 26 00:00:00 2005
@@ -103,6 +103,10 @@
X };
X #endif        /* MSDOS */
X 
+#ifdef CYGWIN
+static int save_ttyio = -1;
+#endif
+
X 
X #ifdef        LSI_C
X int safe_dup(oldd)
@@ -346,6 +350,9 @@
X 
X       *fdp = fd;
X       *fpp = fp;
+#ifdef CYGWIN
+       save_ttyio = fd;
+#endif
X 
X       return(0);
X }
@@ -366,7 +373,7 @@
X 
X #if   MSDOS
X /*ARGSUSED*/
-VOID loadterm(fd, tty, ws)
+VOID loadtermio(fd, tty, ws)
X int fd;
X char *tty, *ws;
X {
@@ -381,7 +388,7 @@
X # endif       /* !DJGPP */
X }
X 
-VOID saveterm(fd, ttyp, wsp)
+VOID savetermio(fd, ttyp, wsp)
X int fd;
X char **ttyp, **wsp;
X {
@@ -500,7 +507,7 @@
X # endif       /* USETERMIOS */
X 
X /*ARGSUSED*/
-VOID loadterm(fd, tty, ws)
+VOID loadtermio(fd, tty, ws)
X int fd;
X char *tty, *ws;
X {
@@ -522,7 +529,7 @@
X # endif
X }
X 
-VOID saveterm(fd, ttyp, wsp)
+VOID savetermio(fd, ttyp, wsp)
X int fd;
X char **ttyp, **wsp;
X {
@@ -574,3 +581,21 @@
X       } while (0);
X }
X #endif        /* !MSDOS */
+
+#ifdef CYGWIN
+p_id_t Xfork(VOID_A)
+{
+       p_id_t pid;
+       char *buf;
+
+       /* Cygwin's fork() breaks ISIG */
+       if (save_ttyio >= 0) savetermio(save_ttyio, &buf, NULL);
+       pid = fork();
+       if (save_ttyio >= 0) {
+               loadtermio(save_ttyio, buf, NULL);
+               if (buf) free(buf);
+       }
+
+       return(pid);
+}
+#endif /* CYGWIN */
diff -urNP ../FD-2.06d/termio.h ./termio.h
--- ../FD-2.06d/termio.h        Tue May 10 00:00:00 2005
+++ ./termio.h  Thu May 26 00:00:00 2005
@@ -184,6 +184,14 @@
X # endif
X #endif        /* !_PATH_TTY */
X 
+#if    defined (CYGWIN) && !defined (__PATHNAME_H_)
+# ifdef        USEPID_T
+typedef pid_t          p_id_t;
+# else
+typedef long           p_id_t;
+# endif
+#endif /* CYGWIN && !__PATHNAME_H_ */
+
X #ifdef        LSI_C
X extern int safe_dup __P_((int));
X extern int safe_dup2 __P_((int, int));
@@ -212,7 +220,12 @@
X extern int Xtcflush __P_((int, int));
X # endif
X #endif        /* !MSDOS */
-extern VOID loadterm __P_((int, char *, char *));
-extern VOID saveterm __P_((int, char **, char **));
+extern VOID loadtermio __P_((int, char *, char *));
+extern VOID savetermio __P_((int, char **, char **));
+#ifdef CYGWIN
+extern p_id_t Xfork __P_((VOID_A));
+#else
+#define        Xfork           fork
+#endif
X 
X #endif        /* !__TERMIO_H_ */
diff -urNP ../FD-2.06d/types.h ./types.h
--- ../FD-2.06d/types.h Tue May 10 00:00:00 2005
+++ ./types.h   Thu May 26 00:00:00 2005
@@ -319,6 +319,8 @@
X #define       F_NOKANJICONV   0004000
X #define       F_TTYIOMODE     0010000
X #define       F_TTYNL         0020000
+#define        F_EVALMACRO     0040000
+#define        F_DOSYSTEM      0100000
X 
X #ifdef        _NOORIGSHELL
X typedef struct _aliastable {
diff -urNP ../FD-2.06d/version.h ./version.h
--- ../FD-2.06d/version.h       Tue May 10 00:00:00 2005
+++ ./version.h Thu May 26 00:00:00 2005
@@ -5,4 +5,4 @@
X  */
X 
X char *distributor = NULL;
-static char version[] = "@(#)fd.c  2.06d 05/10/05";
+static char version[] = "@(#)fd.c  2.07 05/26/05";
SHAR_EOF
  $echo 'File' 'FD-2.07.patch' 'is complete' &&
  $shar_touch -am 05242311105 'FD-2.07.patch' &&
  chmod 0644 'FD-2.07.patch' ||
  $echo 'restore of' 'FD-2.07.patch' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'FD-2.07.patch:' 'MD5 check failed'
79e2286ea0bbcb7863a42b2c79375687  FD-2.07.patch
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'FD-2.07.patch'`"
    test 239621 -eq "$shar_count" ||
    $echo 'FD-2.07.patch:' 'original size' '239621,' 'current size' "$shar_count!"
  fi
fi
$echo 'You have unpacked the last part'
rm -fr _sh01053
exit 0
-- 
                                               しらい たかし