diff --git a/edit.c b/edit.c index ffeea36..3dac2c5 100644 --- a/edit.c +++ b/edit.c @@ -1,4 +1,4 @@ -/** $MirOS: src/bin/mksh/edit.c,v 1.3 2005/05/23 16:23:18 tg Exp $ */ +/** $MirOS: src/bin/mksh/edit.c,v 1.4 2005/05/25 23:31:05 tg Exp $ */ /* $OpenBSD: edit.c,v 1.29 2005/04/13 02:33:08 deraadt Exp $ */ /* $OpenBSD: edit.h,v 1.8 2005/03/28 21:28:22 deraadt Exp $ */ /* $OpenBSD: emacs.c,v 1.37 2005/03/30 17:16:37 deraadt Exp $ */ @@ -10,7 +10,7 @@ #include #include -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.3 2005/05/23 16:23:18 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.4 2005/05/25 23:31:05 tg Exp $"); #define BEL 0x07 @@ -72,8 +72,7 @@ x_init(void) if (setsig(&sigtraps[SIGWINCH], x_sigwinch, SS_RESTORE_ORIG|SS_SHTRAP)) sigtraps[SIGWINCH].flags |= TF_SHELL_USES; - got_sigwinch = 1; /* force initial check */ - check_sigwinch(); + check_sigwinch(); /* force initial check */ x_init_emacs(); } @@ -88,7 +87,6 @@ x_sigwinch(int sig __attribute__((unused))) static void check_sigwinch(void) { - if (got_sigwinch) { struct winsize ws; got_sigwinch = 0; @@ -111,7 +109,6 @@ check_sigwinch(void) if (ws.ws_row && (vp = typeset("LINES", 0, 0, 0, 0))) setint(vp, (long) ws.ws_row); } - } } /* @@ -426,6 +423,9 @@ x_file_glob(int flags __attribute__((unused)), const char *str, escaping = 1; continue; } + /* specially escape escaped [ for globbing */ + if (escaping && toglob[i] == '[') + toglob[idx++] = QCHAR; toglob[idx] = toglob[i]; idx++; @@ -440,7 +440,7 @@ x_file_glob(int flags __attribute__((unused)), const char *str, s = pushs(SWSTR, ATEMP); s->start = s->str = toglob; source = s; - if (yylex(ONEWORD) != LWORD) { + if (yylex(ONEWORD|LQCHAR) != LWORD) { source = sold; internal_errorf(0, "fileglob: substitute error"); return 0; @@ -877,7 +877,7 @@ x_escape(const char *s, size_t len, int (*putbuf_func) (const char *, size_t)) int rval=0; for (add = 0, wlen = len; wlen - add > 0; add++) { - if (strchr("\\$()[]{}*&;#|<>\"'`", s[add]) || strchr(ifs, s[add])) { + if (strchr("\\$()[{}*&;#|<>\"'`", s[add]) || strchr(ifs, s[add])) { if (putbuf_func(s, add) != 0) { rval = -1; break; @@ -2473,6 +2473,7 @@ x_version(int c __attribute__((unused))) int lim = x_lastcp() - xbp; char *v = strdup(ksh_version + 4); + check_sigwinch(); /* mksh hack ;-) */ xbuf = xbp = xcp = v; xend = xep = v + strlen(v); x_redraw(lim); diff --git a/funcs.c b/funcs.c index 777bce0..144c018 100644 --- a/funcs.c +++ b/funcs.c @@ -1,4 +1,4 @@ -/** $MirOS: src/bin/mksh/funcs.c,v 1.8 2005/05/25 13:46:00 tg Exp $ */ +/** $MirOS: src/bin/mksh/funcs.c,v 1.9 2005/05/25 23:31:06 tg Exp $ */ /* $OpenBSD: c_ksh.c,v 1.27 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: c_sh.c,v 1.29 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: c_test.c,v 1.17 2005/03/30 17:16:37 deraadt Exp $ */ @@ -13,7 +13,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.8 2005/05/25 13:46:00 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.9 2005/05/25 23:31:06 tg Exp $"); int c_cd(char **wp) @@ -2822,18 +2822,6 @@ c_ulimit(char **wp) char option; } limits[] = { /* Do not use options -H, -S or -a */ -#ifdef RLIMIT_CPU - { "time(cpu-seconds)", RLIMIT, RLIMIT_CPU, RLIMIT_CPU, - 1, 't' }, -#endif -#ifdef RLIMIT_TIME - { "humantime(seconds)", RLIMIT, RLIMIT_TIME, RLIMIT_TIME, - 1, 'T' }, -#endif -#ifdef RLIMIT_FSIZE - { "file(blocks)", RLIMIT, RLIMIT_FSIZE, RLIMIT_FSIZE, - 512, 'f' }, -#endif #ifdef RLIMIT_CORE { "coredump(blocks)", RLIMIT, RLIMIT_CORE, RLIMIT_CORE, 512, 'c' }, @@ -2842,9 +2830,13 @@ c_ulimit(char **wp) { "data(KiB)", RLIMIT, RLIMIT_DATA, RLIMIT_DATA, 1024, 'd' }, #endif -#ifdef RLIMIT_STACK - { "stack(KiB)", RLIMIT, RLIMIT_STACK, RLIMIT_STACK, - 1024, 's' }, +#ifdef RLIMIT_FSIZE + { "file(blocks)", RLIMIT, RLIMIT_FSIZE, RLIMIT_FSIZE, + 512, 'f' }, +#endif +#ifdef RLIMIT_LOCKS + { "flocks", RLIMIT, RLIMIT_LOCKS, RLIMIT_LOCKS, + -1, 'L' }, #endif #ifdef RLIMIT_MEMLOCK { "lockedmem(KiB)", RLIMIT, RLIMIT_MEMLOCK, RLIMIT_MEMLOCK, @@ -2862,6 +2854,18 @@ c_ulimit(char **wp) { "processes", RLIMIT, RLIMIT_NPROC, RLIMIT_NPROC, 1, 'p' }, #endif +#ifdef RLIMIT_STACK + { "stack(KiB)", RLIMIT, RLIMIT_STACK, RLIMIT_STACK, + 1024, 's' }, +#endif +#ifdef RLIMIT_TIME + { "humantime(seconds)", RLIMIT, RLIMIT_TIME, RLIMIT_TIME, + 1, 'T' }, +#endif +#ifdef RLIMIT_CPU + { "time(cpu-seconds)", RLIMIT, RLIMIT_CPU, RLIMIT_CPU, + 1, 't' }, +#endif #ifdef RLIMIT_VMEM { "vmemory(KiB)", RLIMIT, RLIMIT_VMEM, RLIMIT_VMEM, 1024, 'v' }, @@ -2869,10 +2873,6 @@ c_ulimit(char **wp) #ifdef RLIMIT_SWAP { "swap(KiB)", RLIMIT, RLIMIT_SWAP, RLIMIT_SWAP, 1024, 'w' }, -#endif -#ifdef RLIMIT_LOCKS - { "flocks", RLIMIT, RLIMIT_LOCKS, RLIMIT_LOCKS, - -1, 'L' }, #endif { NULL, 0, 0, 0, 0, 0 } }; diff --git a/lex.c b/lex.c index dfd92ae..36ebff4 100644 --- a/lex.c +++ b/lex.c @@ -1,11 +1,11 @@ -/** $MirOS: src/bin/mksh/lex.c,v 1.1 2005/05/23 03:06:08 tg Exp $ */ +/** $MirOS: src/bin/mksh/lex.c,v 1.2 2005/05/25 23:31:07 tg Exp $ */ /* $OpenBSD: lex.c,v 1.36 2005/03/30 17:16:37 deraadt Exp $ */ #include "sh.h" #include #include -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.1 2005/05/23 03:06:08 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.2 2005/05/25 23:31:07 tg Exp $"); /* Structure to keep track of the lexing state and the various pieces of info * needed for each particular state. @@ -342,6 +342,13 @@ yylex(int cf) } } break; + case QCHAR: + if (cf & LQCHAR) { + *wp++ = QCHAR; + *wp++ = getsc(); + break; + } + /* FALLTHRU */ default: *wp++ = CHAR, *wp++ = c; } diff --git a/main.c b/main.c index f490259..b015da3 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/** $MirOS: src/bin/mksh/main.c,v 1.6 2005/05/25 13:46:01 tg Exp $ */ +/** $MirOS: src/bin/mksh/main.c,v 1.7 2005/05/25 23:31:07 tg Exp $ */ /* $OpenBSD: main.c,v 1.38 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: tty.c,v 1.8 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: io.c,v 1.21 2005/03/30 17:16:37 deraadt Exp $ */ @@ -10,7 +10,7 @@ #include #include -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.6 2005/05/25 13:46:01 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.7 2005/05/25 23:31:07 tg Exp $"); extern char **environ; @@ -46,11 +46,10 @@ static const char *initcoms [] = { /* Aliases that are builtin commands in at&t */ "login=exec login", NULL, - /* this is what at&t ksh seems to track, with the addition of emacs */ + /* this is what at&t ksh seems to track, with the addition of emacs */ "alias", "-tU", "cat", "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls", - "mail", "make", "mv", "pr", "rm", "sed", "sh", "vi", "who", - NULL, + "make", "mv", "pr", "rm", "sed", "sh", "vi", "who", NULL, NULL }; diff --git a/mksh.1 b/mksh.1 index 105f8f4..f784754 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,13 +1,11 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.4 2005/05/25 14:15:40 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.5 2005/05/25 23:31:07 tg Exp $ .\" $OpenBSD: ksh.1,v 1.98 2005/05/12 09:18:24 jmc Exp $ .\" $OpenBSD: sh.1tbl,v 1.53 2004/12/10 01:56:56 jaredy Exp $ -.\" -.\" Public Domain -.\" +.\"- .Dd May 22, 2005 .Dt MKSH 1 .Os MirOS -.\" define Mx macro for portable mksh, just in case... +.\" this macro only exists in MirNroff by default .de Mx .nr cF \\n(.f .nr cZ \\n(.s @@ -202,7 +200,8 @@ In the absence of fatal errors, the exit status is that of the last command executed, or zero, if no command is executed. .Ss Command syntax -The shell begins parsing its input by breaking it into +The shell begins parsing its input by removing any backslash-newline +combinations, then breaking it into .Em words . Words, which are sequences of characters, are delimited by unquoted whitespace characters (space, tab, and newline) or meta-characters @@ -471,7 +470,7 @@ a (syntactically correct) reserved word. For example, the following are all valid: .Bd -literal -offset indent $ { echo foo; echo bar; } -$ { echo foo; echo bar\*(Ltnewline\*(Gt } +$ { echo foo; echo bar\*(Ltnewline\*(Gt} $ { { echo foo; echo bar; } } .Ed .Pp @@ -1184,6 +1183,10 @@ If is omitted, the string .Dq parameter null or not set is used instead. +Currently a bug, if +.Ar word +is a variable which expands to the null string, the +error message is also printed. .El .Pp In the above modifiers, the @@ -1487,8 +1490,7 @@ colon, or two adjacent colons, is treated as a .Sq \&. (the current directory). .It Ev PGRP -The current process group, see -.Xr getpgrp 2 . +The current process group (read-only). .It Ev PPID The process ID of the shell's parent (read-only). .It Ev PS1 @@ -1916,7 +1918,8 @@ escapes for .Ql ` , .Ql \e , and -.Ql \enewline . +.Ql \enewline ; +any backslash preceding double quotes is removed. If multiple here documents are used on the same command line, they are saved in order. .It \*(Lt\*(Lt- Ar marker @@ -2026,11 +2029,13 @@ integers may be prefixed with .Sq 0X or .Sq 0x -(specifying base 16), similar to AT&T ksh, +(specifying base 16), similar to AT&T +.Nm ksh , or .Sq 0 -(base 8), as an mksh extension, -in all forms of arithmetic expressions, +(base 8), as an +.Nm +extension, in all forms of arithmetic expressions, except as numeric arguments to the .Ic test command. @@ -2165,8 +2170,8 @@ Some notes concerning co-processes: .It The only way to close the co-process's input (so the co-process reads an end-of-file) is to redirect the input to a numbered file descriptor and then -close that file descriptor e.g.\& -.Ic exec 3\*(Gt&p; exec 3\*(Gt&- . +close that file descriptor: +.Ic exec 3\*(Gt&p; exec 3\*(Gt&- .It In order for co-processes to share a common output, the shell must keep the write portion of the output pipe open. @@ -2470,7 +2475,8 @@ argument to the .Fl t test may be left out and defaults to 1). .It -Tilde expansion after equal signs is disabled. +Tilde expansion after equal signs (not assignments) is disabled, +although not strictly forbidden by POSIX, for consistency with other shells. .El .Ss Strict Bourne shell mode When the @@ -2508,6 +2514,15 @@ Sequences of .Sq ((...)) are not interpreted as arithmetic expressions. .El +.Pp +This does not make +.Nm +a real bourne shell emulation, though. +Access to many enhanced features is still available, and +.Ql ^ +as synonym for +.Ql | +has probably not been in use since the 1980s anyway. .Ss Command execution After evaluation of command-line arguments, redirections, and parameter assignments, the type of command is determined: a special built-in, a @@ -3795,7 +3810,7 @@ characters), or if it is a unary operator like or .Sq Fl n . Use tests like -.Dq if \&[ \&"X$foo\&" = Xbar \&] +.Dq if \&[ x\&"$foo\&" = x"bar" \&] instead. .Pp .It Xo @@ -4070,7 +4085,7 @@ except zero padding is used instead of space padding. .Pp .It Xo .Ic ulimit -.Op Fl acdfHlmnpSsTtv +.Op Fl acdfHLlmnpSsTtvw .Op Ar value .Xc Display or set process limits. @@ -4108,6 +4123,8 @@ blocks on files written by the shell and its child processes (files of any size may be read). .It Fl H Set the hard limit only (the default is to set both hard and soft limits). +.It Fl L Ar n +Control flocks; documentation is missing. .It Fl l Ar n Impose a limit of .Ar n @@ -4142,6 +4159,10 @@ CPU seconds spent in user mode to be used by each process. Impose a limit of .Ar n kibibytes on the amount of virtual memory used. +.It Fl w Ar n +Impose a limit of +.Ar n +kibibytes on the amount of swap space used. .El .Pp As far as @@ -4473,7 +4494,7 @@ an (if the command can be prefixed with a count); and any keys the command is bound to by default, written using caret notation e.g. the ASCII ESC character is written as ^[. -^[A-Z] sequences are not case sensitive. +These control sequences are not case sensitive. A count prefix for a command is entered using the sequence .Pf ^[ Ns Ar n , where @@ -4547,11 +4568,6 @@ is appended. If there is no command or file name with the current partial word as its prefix, a bell character is output (usually causing a beep to be sounded). -.\" XXX -Currently being considered a bug, -if the file name contains \fB[\fR or \fB]\fR, it cannot be completed, even if -the character is escaped, in \fBemacs\fR mode. -This surprisingly works in \fBvi\fR mode; please submit a fix. .It complete-command: ^X^[ Automatically completes as much as is unique of the command name having the partial word up to the cursor as its prefix, as in the @@ -4569,6 +4585,7 @@ If only one completion is possible, match as in the .Ic complete command above. +Note that ^I is usually generated by the TAB (tabulator) key. .It Xo delete-char-backward: .Op Ar n .No ERASE , ^? , ^H @@ -4826,13 +4843,6 @@ colon commands). .El .Pp -Note that the ^X stands for control-X; also -.Aq esc , -.Aq space , -and -.Aq tab -are used for escape, space, and tab, respectively (no kidding). -.Pp Like .Xr vi 1 , there are two modes: @@ -5367,6 +5377,7 @@ Shell database. .Xr dup 2 , .Xr execve 2 , .Xr getgid 2 , +.Xr getpgrp 2 , .Xr getuid 2 , .Xr open 2 , .Xr pipe 2 , @@ -5425,9 +5436,3 @@ The author is aware of this and there is no need to report it. This does not work because the last command of a pipe sequence is run in a subshell. -.Pp -For another known bug, refer to the comment above the -.Em complete-command -paragraph in the section -.Sx Emacs editing mode -above. diff --git a/sh.h b/sh.h index dee735a..0a79a54 100644 --- a/sh.h +++ b/sh.h @@ -1,4 +1,4 @@ -/** $MirOS: src/bin/mksh/sh.h,v 1.7 2005/05/25 13:46:01 tg Exp $ */ +/** $MirOS: src/bin/mksh/sh.h,v 1.8 2005/05/25 23:31:08 tg Exp $ */ /* $OpenBSD: sh.h,v 1.27 2005/03/28 21:33:04 deraadt Exp $ */ /* $OpenBSD: shf.h,v 1.5 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: table.h,v 1.6 2004/12/18 20:55:52 millert Exp $ */ @@ -995,6 +995,7 @@ typedef union { #define ESACONLY BIT(7) /* only accept esac keyword */ #define CMDWORD BIT(8) /* parsing simple command (alias related) */ #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */ +#define LQCHAR BIT(10) /* source string contains QCHAR */ #define HERES 10 /* max << in line */