From ilya Thu Jan 7 01:34:30 1999 Subject: Port of pdksh to OS/2 To: michael@cs.mun.ca Date: Thu, 7 Jan 1999 01:34:30 -0500 (EST) X-Mailer: ELM [version 2.5 PL0b1] Status: RO Content-Length: 22777 Lines: 731 Dear Michael, it looks like pdksh's OS/2 port was not updated for quite some time. Below is the cumulative patch of my changes to pdksh 5.2.7 during the last several years, merged with the source for 5.2.13. The description of the patch is in the first chunk. Enjoy, Ilya diff -pru pdksh-5.2.13/os2/NEWS.os2 pdksh-5.2.13.minchange/os2/NEWS.os2 --- pdksh-5.2.13/os2/NEWS.os2 Sun Jun 2 09:14:22 1996 +++ pdksh-5.2.13.minchange/os2/NEWS.os2 Wed Jan 6 23:08:28 1999 @@ -1,3 +1,29 @@ +Version 5.2.13+ + + 1. Test suite works (with one obscure failure). + + 2. Works in xterm too. + + 3. Works in DOS too (with RSX extender present). + + 4. Can include PM and fullscreen applications into pipelines. However, if + a PM or fullscreen application is specified standalone in an interactive + session, will start it asyncroneously, as before (to do this needed to + change the signature of ksh_execve()). + + 5. Could overwrite arguments when looking for scripts with extensions. + + 6. History file works. + + 7. Can read scripts from STDIN. + + 8. When starting EMX program, the wildcards might have been expanded + twice, say + + expr 5 "*" 7 + + did not work. + Version 5.2.6 1. The bug where hereis documents would leave temporary files behind has diff -pru pdksh-5.2.13/c_sh.c pdksh-5.2.13.minchange/c_sh.c --- pdksh-5.2.13/c_sh.c Mon Oct 27 10:50:10 1997 +++ pdksh-5.2.13.minchange/c_sh.c Wed Jan 6 22:22:50 1999 @@ -321,9 +321,11 @@ c_read(wp) break; while (1) { c = shf_getc(shf); - if (c == '\0' + if (c == #ifdef OS2 - || c == '\r' + '\r' +#else + '\0' #endif /* OS2 */ ) continue; diff -pru pdksh-5.2.13/edit.c pdksh-5.2.13.minchange/edit.c --- pdksh-5.2.13/edit.c Wed Oct 22 09:32:02 1997 +++ pdksh-5.2.13.minchange/edit.c Wed Jan 6 22:22:50 1999 @@ -153,7 +153,8 @@ int x_getc() { #ifdef OS2 - unsigned char c = _read_kbd(0, 1, 0); + unsigned char c; + read(0, &c, 1); return c == 0 ? 0xE0 : c; #else /* OS2 */ char c; @@ -982,6 +983,9 @@ glob_path(flags, pat, wp, path) /* Check that each match is executable... */ words = (char **) XPptrv(*wp); for (i = j = oldsize; i < newsize; i++) { + /* globit() added extra chars, + so search_access() is safe + even on OS/2. */ if (search_access(words[i], X_OK, (int *) 0) >= 0) { words[j] = words[i]; if (!(flags & XCF_FULLPATH)) diff -pru pdksh-5.2.13/emacs.c pdksh-5.2.13.minchange/emacs.c --- pdksh-5.2.13/emacs.c Wed Feb 26 09:54:36 1997 +++ pdksh-5.2.13.minchange/emacs.c Wed Jan 6 22:22:50 1999 @@ -307,7 +307,7 @@ static struct x_defbindings const x_defb { XFUNC_mv_forw, 3, 'M' }, { XFUNC_next_com, 3, 'P' }, { XFUNC_prev_com, 3, 'H' }, -#else /* OS2 */ +#endif /* OS2 */ /* These for ansi arrow keys: arguablely shouldn't be here by * default, but its simpler/faster/smaller than using termcap * entries. @@ -317,7 +317,6 @@ static struct x_defbindings const x_defb { XFUNC_next_com, 2, 'B' }, { XFUNC_mv_forw, 2, 'C' }, { XFUNC_mv_back, 2, 'D' }, -#endif /* OS2 */ }; int diff -pru pdksh-5.2.13/exec.c pdksh-5.2.13.minchange/exec.c --- pdksh-5.2.13/exec.c Mon Oct 27 10:51:48 1997 +++ pdksh-5.2.13.minchange/exec.c Thu Jan 7 00:36:44 1999 @@ -416,7 +416,7 @@ execute(t, flags) #endif restoresigs(); cleanup_proc_env(); - ksh_execve(t->str, t->args, ap); + ksh_execve(t->str, t->args, ap, flags); if (errno == ENOEXEC) scriptexec(t, ap); else @@ -808,8 +808,16 @@ scriptexec(tp, ap) if (a1) *tp->args-- = a1; # ifdef OS2 - if (a0 != a2 && search_access(a0, X_OK, (int *) 0)) + { +# include + char path[MAXPATHLEN]; + + if (a0 != a2 && strlen(a0) <= MAXPATHLEN - 5) { + strcpy(path,a0); + if (search_access(path, X_OK, (int *) 0)) a0 = a2; + } + } # endif /* OS2 */ shell = a0; } @@ -838,7 +846,7 @@ scriptexec(tp, ap) #endif /* SHARPBANG */ *tp->args = shell; - ksh_execve(tp->args[0], tp->args, ap); + ksh_execve(tp->args[0], tp->args, ap, 0); /* report both the program that was run and the bogus shell */ errorf("%s: %s: %s", tp->str, shell, strerror(errno)); @@ -1229,6 +1237,8 @@ search(name, path, mode, errnop) XcheckN(xs, xp, p - sp); memcpy(xp, sp, p - sp); xp += p - sp; + if (ISDIRSEP(xp[-1])) + xp--; *xp++ = DIRSEP; } sp = p; diff -pru pdksh-5.2.13/jobs.c pdksh-5.2.13.minchange/jobs.c --- pdksh-5.2.13/jobs.c Wed Aug 6 19:13:12 1997 +++ pdksh-5.2.13.minchange/jobs.c Wed Jan 6 22:22:50 1999 @@ -630,6 +630,7 @@ exchild(t, flags, close_fd) Flag(FMONITOR) = 0; #endif /* JOBS */ Flag(FTALKING) = 0; + if (tty_fd >= 0) flags = flags | XINTACT; /* Needed on OS/2.*/ tty_close(); cleartraps(); execute(t, (flags & XERROK) | XEXEC); /* no return */ diff -pru pdksh-5.2.13/lex.c pdksh-5.2.13.minchange/lex.c --- pdksh-5.2.13/lex.c Mon Oct 27 13:12:24 1997 +++ pdksh-5.2.13.minchange/lex.c Wed Jan 6 22:22:50 1999 @@ -1049,7 +1049,6 @@ getsc_line(s) if (interactive) { pprompt(prompt, 0); #ifdef OS2 - setmode (0, O_TEXT); #endif /* OS2 */ } else s->line++; @@ -1072,9 +1071,6 @@ getsc_line(s) XcheckN(s->xs, xp, Xlength(s->xs, xp)); xp--; /* ...and move back again */ } -#ifdef OS2 - setmode(0, O_BINARY); -#endif /* OS2 */ /* flush any unwanted input so other programs/builtins * can read it. Not very optimal, but less error prone * than flushing else where, dealing with redirections, diff -pru pdksh-5.2.13/os2/config.h pdksh-5.2.13.minchange/os2/config.h --- pdksh-5.2.13/os2/config.h Sun Jun 2 09:14:22 1996 +++ pdksh-5.2.13.minchange/os2/config.h Wed Jan 6 22:22:50 1999 @@ -149,7 +149,7 @@ /* #undef HAVE_SYS_SIGLIST */ /* Define if you have a sane header file */ -/* #define HAVE_TERMIOS_H 1 */ +#define HAVE_TERMIOS_H 1 /* Define if you have a memset() function in your C library */ #define HAVE_MEMSET 1 diff -pru pdksh-5.2.13/os2/configure.cmd pdksh-5.2.13.minchange/os2/configure.cmd --- pdksh-5.2.13/os2/configure.cmd Sun Jun 2 09:16:26 1996 +++ pdksh-5.2.13.minchange/os2/configure.cmd Wed Jan 6 22:22:50 1999 @@ -30,7 +30,8 @@ set ushell=sh if exist conftest.c erase conftest.c if exist confdefs.h erase confdefs.h if %verbose% == yes echo Searching for sed -for %%i in (%path%) do if exist %%i\sed.exe goto s_success +:::::for %%i in (%path%) do if exist %%i\sed.exe goto s_success +sed --version && goto s_success echo No sed in search path. Copying Makefile for gcc. You will need echo to edit it if you are not using standard defaults. copy os2\Makefile Makefile @@ -45,6 +46,7 @@ goto end :s_success if %verbose% == yes echo checking for compiler for %%i in (%path%) do if exist %%i\gcc.exe goto g_success +gcc --version && goto g_success rem for the future we'll use sed processing for %%i in (%path%) do if exist %%i\bcc.exe goto b_success for %%i in (%path%) do if exist %%i\icc.exe goto i_success diff -pru pdksh-5.2.13/os2/os2.c pdksh-5.2.13.minchange/os2/os2.c --- pdksh-5.2.13/os2/os2.c Mon Feb 19 14:57:32 1996 +++ pdksh-5.2.13.minchange/os2/os2.c Thu Jan 7 00:52:50 1999 @@ -4,20 +4,17 @@ #define INCL_WINPROGRAMLIST #include #include "config.h" -#include +#include "sh.h" /* To get inDOS. */ #include #include +#include +#include #include #include #include #include #include -void noinherit(int fd) -{ - DosSetFHState(fd, OPEN_FLAGS_NOINHERIT); -} - static int isfullscreen(void) { PTIB ptib; @@ -27,6 +24,55 @@ static int isfullscreen(void) return (ppib -> pib_ultype != SSF_TYPE_WINDOWABLEVIO); } +static int +quoted_strlen(char *s) +{ + int ret = 0; + int seen_space = 0; + while (*s) { + if (seen_space == 0 && *s == ' ') { + ret += 2; + seen_space = 1; + } else if (*s == '\"') { + if (seen_space == 0) { + seen_space = 1; + ret += 4; + } else ret += 2; + } else ret++; + s++; + } + return ret; +} + +static char * +quoted_strcpy(char *targ, char* src) +{ + int seen_space = 0; + char *s = src, *t = targ; + + while (*s) { + if ((*s == ' ') || (*s == '\"')) { + seen_space = 1; + break; + } + s++; + } + if (seen_space) { + *targ++ = '\"'; + } + while (*src) { + if (*src == '\"') { + *targ++ = '\\'; + } + *targ++ = *src++; + } + if (seen_space) { + *targ++ = '\"'; + } + *targ = '\0'; + return t; +} + static int newsession(int type, int mode, char *cmd, char **args, char **env) { @@ -39,17 +85,17 @@ newsession(int type, int mode, char *cmd static char queue[18]; static HQUEUE qid = -1; char *ap, *ep, *p; - + char object[256] = {0}; for ( cnt = 1, len = 0; args[cnt] != NULL; cnt++ ) - len += strlen(args[cnt]) + 1; + len += quoted_strlen(args[cnt]) + 1; p = ap = alloca(len + 2); *p = 0; for ( cnt = 1, len = 0; args[cnt] != NULL; cnt++ ) { if ( cnt > 1 ) *p++ = ' '; - strcpy(p, args[cnt]); + quoted_strcpy(p, args[cnt]); p += strlen(p); } for ( cnt = 0, len = 0; env[cnt] != NULL; cnt++ ) @@ -84,6 +130,9 @@ newsession(int type, int mode, char *cmd sd.IconFile = NULL; sd.PgmHandle = 0; sd.PgmControl = 0; + sd.Reserved = 0; + sd.ObjectBuffer = object; + sd.ObjectBuffLen = sizeof(object); if ( DosStartSession(&sd, &sid, &pid) ) return errno = ENOEXEC, -1; @@ -104,7 +153,7 @@ newsession(int type, int mode, char *cmd exit(0); } -int ksh_execve(char *cmd, char **args, char **env) +int ksh_execve(char *cmd, char **args, char **env, int flags) { ULONG apptype; char path[256], *p; @@ -115,33 +164,78 @@ int ksh_execve(char *cmd, char **args, c if ( *p == '/' ) *p = '\\'; + if (_emx_env & 0x1000) { /* RSX, do best we can do. */ + int len = strlen(cmd); + + if (len > 4 && stricmp(cmd + len - 4, ".bat") == 0) { + /* execve would fail anyway, but most probably segfault. */ + errno = ENOEXEC; + return -1; + } + goto do_execve; + } + + if ( inDOS ) { + fprintf(stderr, "ksh_execve requires OS/2 or RSX!\n"); + exit(255); + } + if ( DosQueryAppType(path, &apptype) == 0 ) { if (apptype & FAPPTYP_DOS) return newsession(isfullscreen() ? SSF_TYPE_VDM : SSF_TYPE_WINDOWEDVDM, - P_NOWAIT, path, args, env); + P_WAIT, path, args, env); if ((apptype & FAPPTYP_WINDOWSREAL) || (apptype & FAPPTYP_WINDOWSPROT) || (apptype & FAPPTYP_WINDOWSPROT31)) return newsession(isfullscreen() ? PROG_WINDOW_AUTO : PROG_SEAMLESSCOMMON, - P_NOWAIT, path, args, env); + P_WAIT, path, args, env); if ( (apptype & FAPPTYP_EXETYPE) == FAPPTYP_WINDOWAPI ) { printf(""); /* kludge to prevent PM apps from core dumping */ - return newsession(SSF_TYPE_PM, P_NOWAIT, path, args, env); + /* Start new session if interactive and not a part of a pipe. */ + return newsession(SSF_TYPE_PM, + ( (flags & XINTACT) && (flags & XPIPE) + /* _isterm(0) && _isterm(1) && _isterm(2) */ + ? P_NOWAIT + : P_WAIT), + path, args, env); } if ( (apptype & FAPPTYP_EXETYPE) == FAPPTYP_NOTWINDOWCOMPAT || (apptype & FAPPTYP_EXETYPE) == FAPPTYP_NOTSPEC ) if ( !isfullscreen() ) - return newsession(SSF_TYPE_FULLSCREEN, P_NOWAIT, path, args, env); + return newsession(SSF_TYPE_FULLSCREEN, + ( (flags & XINTACT) && (flags & XPIPE) + /* _isterm(0) && _isterm(1) && _isterm(2) */ + ? P_NOWAIT + : P_WAIT), + path, args, env); + } + do_execve: + { + /* P_QUOTE is too agressive, it quotes `@args_from_file' too, + which breaks emxomfld calling LINK386 when EMXSHELL=ksh. + Thus we check whether we need to quote, and delegate the hard + work to P_QUOTE if needed. */ + char **pp = args; + int do_quote = 0; + for (; !do_quote && *pp; pp++) { + for (p = *pp; *p; p++) { + if (*p == '*' || *p == '?') { + do_quote = 1; + break; + } + } + } + + if ( (rc = spawnve(P_OVERLAY | (do_quote ? P_QUOTE : 0), + path, args, env)) != -1 ) + exit(rc); } - if ( (rc = execve(path, args, env)) != -1 ) - exit(rc); - return -1; } diff -pru pdksh-5.2.13/os2/os2bugs pdksh-5.2.13.minchange/os2/os2bugs --- pdksh-5.2.13/os2/os2bugs Sun Jun 2 09:15:24 1996 +++ pdksh-5.2.13.minchange/os2/os2bugs Wed Jan 6 22:22:50 1999 @@ -1,26 +1,19 @@ Bugs and Limitations - 6/96 + 1/99 1. Some of the makefile targets are not yet working. Those known to work include all, uninstall,ksh, config.h, makefile, - debugtools (only check-fd and check-sigs.), clean, & distclean. - make check does not work because of a bug in os2 port of ksh. You - need to run ksh Bugs ksh, or sh Bugs sh as appropriate. + debugtools (only check-fd and check-sigs.), test, clean, & distclean. + You need to run ksh Bugs ksh, or sh Bugs sh as appropriate. 2. You cannot start a full screen session from the windowed ksh command line. 3. Job control is not working and may never work in os/2 (no sigstp, sigcont, etc). -4. make check does not work even after you get all of the perl issues - taken care of. See bug 5 for the reason. Use 'ksh Bugs ksh' with - the supplied Bugs file to check a build. - -5. The command 'ksh < filename' does not work properly on this release. - This is the cause of the make check failure. Extra \r (carriage returns) - appear in the input data. - -6. ls [B]* fails even when a file Bozo exists. ls [b]* will work +4. ls [B]* fails even when a file Bozo exists. ls [b]* will work due to case folding. The bug is in the way case folding is managed. ls b* or ls B* will work as expected. +5. regress.t:regression-13 test fails. I do not understand why it can + work on *nix. In fact cat does not get SIGPIPE, but gets write failure. diff -pru pdksh-5.2.13/sh.h pdksh-5.2.13.minchange/sh.h --- pdksh-5.2.13/sh.h Sun Aug 3 19:00:40 1997 +++ pdksh-5.2.13.minchange/sh.h Wed Jan 6 22:41:44 1999 @@ -204,17 +204,18 @@ typedef RETSIGTYPE (*handler_t) ARGS((in /* Special cases for execve(2) */ #ifdef OS2 -extern int ksh_execve(char *cmd, char **args, char **env); +extern int ksh_execve(char *cmd, char **args, char **env, int flags); #else /* OS2 */ # if defined(OS_ISC) && defined(_POSIX_SOURCE) /* Kludge for ISC 3.2 (and other versions?) so programs will run correctly. */ -# define ksh_execve(p, av, ev) do { \ +# define ksh_execve(p, av, ev, flags) \ + do { \ __setostype(0); \ execve(p, av, ev); \ __setostype(1); \ } while (0) # else /* OS_ISC && _POSIX */ -# define ksh_execve(p, av, ev) execve(p, av, ev) +# define ksh_execve(p, av, ev, flags) execve(p, av, ev) # endif /* OS_ISC && _POSIX */ #endif /* OS2 */ @@ -268,11 +269,15 @@ extern int ksh_execve(char *cmd, char ** # define EXTERN_DEFINED #endif +#ifdef OS2 +# define inDOS (!(_emx_env & 0x200)) +#endif + #ifndef EXECSHELL /* shell to exec scripts (see also $SHELL initialization in main.c) */ # ifdef OS2 -# define EXECSHELL "c:\\os2\\cmd.exe" -# define EXECSHELL_STR "OS2_SHELL" +# define EXECSHELL ( inDOS ? "c:\\command.com" : "c:\\os2\\cmd.exe") +# define EXECSHELL_STR ( inDOS ? "COMSPEC" : "OS2_SHELL") # else /* OS2 */ # define EXECSHELL "/bin/sh" # define EXECSHELL_STR "EXECSHELL" diff -pru pdksh-5.2.13/shf.c pdksh-5.2.13.minchange/shf.c --- pdksh-5.2.13/shf.c Thu Feb 1 19:31:32 1996 +++ pdksh-5.2.13.minchange/shf.c Thu Jan 7 00:00:26 1999 @@ -556,6 +556,12 @@ shf_getse(buf, bsize, shf) shf->rnleft -= ncopy; buf += ncopy; bsize -= ncopy; +#ifdef OS2 + if (end && buf > orig_buf + 1 && buf[-2] == '\r') { + buf--; + buf[-1] = '\n'; + } +#endif } while (!end && bsize); *buf = '\0'; return buf; diff -pru pdksh-5.2.13/tests/cdhist.t pdksh-5.2.13.minchange/tests/cdhist.t --- pdksh-5.2.13/tests/cdhist.t Fri Dec 8 21:35:02 1995 +++ pdksh-5.2.13.minchange/tests/cdhist.t Wed Jan 6 22:22:50 1999 @@ -1,6 +1,8 @@ name: cd-history description: Test someone's CD history package (uses arrays) + Fails on OS/2, since directory names are prepended with drive letter +expected-fail: $^O eq 'os2' stdin: # go to known place before doing anything cd / diff -pru pdksh-5.2.13/tests/glob.t pdksh-5.2.13.minchange/tests/glob.t --- pdksh-5.2.13/tests/glob.t Tue Nov 12 13:27:40 1996 +++ pdksh-5.2.13.minchange/tests/glob.t Wed Jan 6 22:22:50 1999 @@ -16,6 +16,8 @@ expected-stdout: name: glob-bad-2 description: Check that symbolic links aren't stat()'d + Fails on OS/2: no symlinks +expected-fail: $^O eq 'os2' file-setup: dir 755 "dir" file-setup: symlink 644 "dir/abc" non-existant-file diff -pru pdksh-5.2.13/tests/history.t pdksh-5.2.13.minchange/tests/history.t --- pdksh-5.2.13/tests/history.t Tue Nov 12 13:22:12 1996 +++ pdksh-5.2.13.minchange/tests/history.t Wed Jan 6 22:22:50 1999 @@ -472,6 +472,8 @@ name: history-ed-1 description: Basic (ed) editing works (assumes you have generic ed editor that prints no prompts). + Fails on OS/2: why FCEDIT would be ed? +expected-fail: $^O eq 'os2' arguments: !-i! env-setup: !ENV=./Env!HISTFILE=hist.file! file-setup: file 644 "Env" @@ -494,6 +496,8 @@ expected-stderr-pattern: name: history-ed-2 description: Correct command is edited when number given + Fails on OS/2: why FCEDIT would be ed? +expected-fail: $^O eq 'os2' arguments: !-i! env-setup: !ENV=./Env!HISTFILE=hist.file! file-setup: file 644 "Env" @@ -525,6 +529,8 @@ description: in history. (NOTE: will fail if using COMPLEX HISTORY compile time option) (ksh88 fails 'cause it lists the fc command) + Fails on OS/2: why FCEDIT would be ed? +expected-fail: $^O eq 'os2' arguments: !-i! env-setup: !ENV=./Env!HISTFILE=hist.file! file-setup: file 644 "Env" diff -pru pdksh-5.2.13/tests/regress.t pdksh-5.2.13.minchange/tests/regress.t --- pdksh-5.2.13/tests/regress.t Fri Aug 15 20:01:18 1997 +++ pdksh-5.2.13.minchange/tests/regress.t Wed Jan 6 22:22:50 1999 @@ -411,7 +411,8 @@ script: while [ "$a" != xxx ] ; do last=$x read x - /bin/cat /dev/null | sed 's/x/y/' + if test -x /bin/cat; then cat=/bin/cat; else cat=cat; fi + $cat /dev/null | sed 's/x/y/' a=x$a done echo $last @@ -719,6 +720,8 @@ name: regression-48 description: Check that (here doc) temp files are not left behind after an exec. stdin: + if test -x /bin/echo; then echo=/bin/echo; else echo=echo.exe; fi + export echo mkdir foo || exit 1 TMPDIR=$PWD/foo $0 <<- 'EOF' x() { @@ -729,11 +732,11 @@ stdin: E_O_F echo "done ($?)" } - exec /bin/echo subtest-1 hi + exec $echo subtest-1 hi EOF echo subtest-1 foo/* TMPDIR=$PWD/foo $0 <<- 'EOF' - sed 's/^/X /' << E_O_F; exec /bin/echo subtest-2 hi + sed 's/^/X /' << E_O_F; exec $echo subtest-2 hi a few lines diff -pru pdksh-5.2.13/tests/th pdksh-5.2.13.minchange/tests/th --- pdksh-5.2.13/tests/th Fri Mar 21 15:00:48 1997 +++ pdksh-5.2.13.minchange/tests/th Wed Jan 6 22:27:04 1999 @@ -96,8 +96,8 @@ # s tag can be used several times. # -require 'signal.ph'; -require 'errno.ph'; +require 'signal.ph' unless $^O eq 'os2'; +require 'errno.ph' unless $^O eq 'os2'; require 'getopts.pl'; ($prog = $0) =~ s#.*/##; @@ -209,7 +209,7 @@ die "$prog: couldn't cd to $pwd - $!\n" if (!$program_kludge) { $test_prog = "$pwd/$test_prog" if substr($test_prog, 0, 1) ne '/'; - die "$prog: $test_prog is not executable - bye\n" if ! -x $test_prog; + die "$prog: $test_prog is not executable - bye\n" if ! -x $test_prog and $^O ne 'os2'; } @trap_sigs = ('TERM', 'QUIT', 'INT', 'PIPE', 'HUP'); @@ -379,12 +379,12 @@ run_test } } elsif ($type eq 'symlink') { local($oumask) = umask($perm); - local($ret) = symlink($rest, $name); + local($ret) = eval 'symlink($rest, $name)' && !$@; umask($oumask); if (!$ret) { print STDERR "$prog:$test{':long-name'}: couldn't create symlink $name - $!\n"; - return undef; + return undef unless $@; } } } @@ -877,12 +877,17 @@ read_test # Syntax check on specific fields if (defined $test{'expected-fail'}) { - if ($test{'expected-fail'} !~ /^(yes|no)$/) { - print STDERR + if ($test{'expected-fail'} =~ /^(yes|no)$/) { + $test{'expected-fail'} = $1 eq 'yes'; + } else { + $res = eval $test{'expected-fail'}; + if ($@) { + print STDERR "$prog:$test{':long-name'}: bad value for expected-fail field\n"; - return undef; + return undef; + } + $test{'expected-fail'} = $res; } - $test{'expected-fail'} = $1 eq 'yes'; } else { $test{'expected-fail'} = 0; } diff -pru pdksh-5.2.13/tests/unclass1.t pdksh-5.2.13.minchange/tests/unclass1.t --- pdksh-5.2.13/tests/unclass1.t Tue Sep 10 08:54:06 1996 +++ pdksh-5.2.13.minchange/tests/unclass1.t Wed Jan 6 22:22:52 1999 @@ -58,6 +58,8 @@ name: xxx-exec-environment-2 description: Check to make sure exec doesn't change environment if a program isn't exec-ed + Fails on OS/2: _emx_sig environment variable changes +expected-fail: $^O eq 'os2' stdin: env > bar1 FOO=bar exec; env > bar2 diff -pru pdksh-5.2.13/tree.h pdksh-5.2.13.minchange/tree.h --- pdksh-5.2.13/tree.h Fri Jan 3 12:23:50 1997 +++ pdksh-5.2.13.minchange/tree.h Wed Jan 6 22:22:52 1999 @@ -105,6 +105,8 @@ struct ioword { #define XERROK BIT(8) /* non-zero exit ok (for set -e) */ #define XCOPROC BIT(9) /* starting a co-process */ +#define XINTACT BIT(29) /* starting from interactive session */ + /* * flags to control expansion of words (assumed by t->evalflags to fit * in a short) diff -pru pdksh-5.2.13/tty.c pdksh-5.2.13.minchange/tty.c --- pdksh-5.2.13/tty.c Fri Sep 20 13:20:04 1996 +++ pdksh-5.2.13.minchange/tty.c Wed Jan 6 22:22:52 1999 @@ -110,7 +110,7 @@ tty_init(init_ttystate) tty_devtty = 1; /* SCO can't job control on /dev/tty, so don't try... */ -#if !defined(__SCO__) +#if !defined(__SCO__) && !defined(OS2) if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) { #ifdef __NeXT /* rlogin on NeXT boxes does not set up the controlling tty, @@ -138,7 +138,7 @@ tty_init(init_ttystate) } # endif /* __mips */ } -#else /* !__SCO__ */ +#else /* !__SCO__ && !OS2 */ tfd = -1; #endif /* __SCO__ */ @@ -148,6 +148,12 @@ tty_init(init_ttystate) tfd = 0; else if (isatty(2)) tfd = 2; +#ifdef OS2 /* try what we skipped before */ + else if ((tfd = open("/dev/tty", O_RDWR, 0)) >= 0) { + do_close = 1; + setmode (tfd, O_BINARY); + } +#endif else { warningf(FALSE, "Can't find tty file descriptor"); return;