[Midnightbsd-cvs] src [7009] trunk/bin/sh: import /bin/sh from FreeBSD 9.2
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Jun 6 21:10:43 EDT 2015
Revision: 7009
http://svnweb.midnightbsd.org/src/?rev=7009
Author: laffer1
Date: 2015-06-06 21:10:43 -0400 (Sat, 06 Jun 2015)
Log Message:
-----------
import /bin/sh from FreeBSD 9.2
Modified Paths:
--------------
trunk/bin/sh/alias.c
trunk/bin/sh/eval.c
trunk/bin/sh/input.c
trunk/bin/sh/jobs.c
trunk/bin/sh/jobs.h
trunk/bin/sh/main.c
trunk/bin/sh/mknodes.c
trunk/bin/sh/mksyntax.c
trunk/bin/sh/myhistedit.h
trunk/bin/sh/parser.c
trunk/bin/sh/parser.h
trunk/bin/sh/sh.1
trunk/bin/sh/var.c
trunk/bin/sh/var.h
Modified: trunk/bin/sh/alias.c
===================================================================
--- trunk/bin/sh/alias.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/alias.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -68,7 +68,18 @@
if (equal(name, ap->name)) {
INTOFF;
ckfree(ap->val);
+ /* See HACK below. */
+#ifdef notyet
ap->val = savestr(val);
+#else
+ {
+ size_t len = strlen(val);
+ ap->val = ckmalloc(len + 2);
+ memcpy(ap->val, val, len);
+ ap->val[len] = ' ';
+ ap->val[len+1] = '\0';
+ }
+#endif
INTON;
return;
}
Modified: trunk/bin/sh/eval.c
===================================================================
--- trunk/bin/sh/eval.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/eval.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -906,6 +906,15 @@
if (pipe(pip) < 0)
error("Pipe call failed: %s", strerror(errno));
}
+ if (cmdentry.cmdtype == CMDNORMAL &&
+ cmd->ncmd.redirect == NULL &&
+ varlist.list == NULL &&
+ (mode == FORK_FG || mode == FORK_NOJOB) &&
+ !disvforkset() && !iflag && !mflag) {
+ vforkexecshell(jp, argv, environment(), path,
+ cmdentry.u.index, flags & EV_BACKCMD ? pip : NULL);
+ goto parent;
+ }
if (forkshell(jp, cmd, mode) != 0)
goto parent; /* at end of routine */
if (flags & EV_BACKCMD) {
Modified: trunk/bin/sh/input.c
===================================================================
--- trunk/bin/sh/input.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/input.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -186,7 +186,7 @@
if (rl_cp == NULL)
rl_cp = el_gets(el, &el_len);
if (rl_cp == NULL)
- nr = 0;
+ nr = el_len == 0 ? 0 : -1;
else {
nr = el_len;
if (nr > BUFSIZ - 1)
Modified: trunk/bin/sh/jobs.c
===================================================================
--- trunk/bin/sh/jobs.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/jobs.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -57,6 +57,7 @@
#undef CEOF /* syntax.h redefines this */
#endif
#include "redir.h"
+#include "exec.h"
#include "show.h"
#include "main.h"
#include "parser.h"
@@ -458,14 +459,15 @@
int
-waitcmd(int argc, char **argv)
+waitcmd(int argc __unused, char **argv __unused)
{
struct job *job;
int status, retval;
struct job *jp;
- if (argc > 1) {
- job = getjob(argv[1]);
+ nextopt("");
+ if (*argptr != NULL) {
+ job = getjob(*argptr);
} else {
job = NULL;
}
@@ -884,7 +886,55 @@
}
+pid_t
+vforkexecshell(struct job *jp, char **argv, char **envp, const char *path, int idx, int pip[2])
+{
+ pid_t pid;
+ struct jmploc jmploc;
+ struct jmploc *savehandler;
+ TRACE(("vforkexecshell(%%%td, %s, %p) called\n", jp - jobtab, argv[0],
+ (void *)pip));
+ INTOFF;
+ flushall();
+ savehandler = handler;
+ pid = vfork();
+ if (pid == -1) {
+ TRACE(("Vfork failed, errno=%d\n", errno));
+ INTON;
+ error("Cannot fork: %s", strerror(errno));
+ }
+ if (pid == 0) {
+ TRACE(("Child shell %d\n", (int)getpid()));
+ if (setjmp(jmploc.loc))
+ _exit(exception == EXEXEC ? exerrno : 2);
+ if (pip != NULL) {
+ close(pip[0]);
+ if (pip[1] != 1) {
+ dup2(pip[1], 1);
+ close(pip[1]);
+ }
+ }
+ handler = &jmploc;
+ shellexec(argv, envp, path, idx);
+ }
+ handler = savehandler;
+ if (jp) {
+ struct procstat *ps = &jp->ps[jp->nprocs++];
+ ps->pid = pid;
+ ps->status = -1;
+ ps->cmd = nullstr;
+ jp->foreground = 1;
+#if JOBS
+ setcurjob(jp);
+#endif
+ }
+ INTON;
+ TRACE(("In parent shell: child = %d\n", (int)pid));
+ return pid;
+}
+
+
/*
* Wait for job to finish.
*
Modified: trunk/bin/sh/jobs.h
===================================================================
--- trunk/bin/sh/jobs.h 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/jobs.h 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -91,6 +92,7 @@
void showjobs(int, int);
struct job *makejob(union node *, int);
pid_t forkshell(struct job *, union node *, int);
+pid_t vforkexecshell(struct job *, char **, char **, const char *, int, int []);
int waitforjob(struct job *, int *);
int stoppedjobs(void);
int backgndpidset(void);
Modified: trunk/bin/sh/main.c
===================================================================
--- trunk/bin/sh/main.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/main.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -266,14 +266,7 @@
void
readcmdfile(const char *name)
{
- int fd;
-
- INTOFF;
- if ((fd = open(name, O_RDONLY)) >= 0)
- setinputfd(fd, 1);
- else
- error("cannot open %s: %s", name, strerror(errno));
- INTON;
+ setinputfile(name, 1);
cmdloop(0);
popfile();
}
Modified: trunk/bin/sh/mknodes.c
===================================================================
--- trunk/bin/sh/mknodes.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/mknodes.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
Modified: trunk/bin/sh/mksyntax.c
===================================================================
--- trunk/bin/sh/mksyntax.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/mksyntax.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -103,29 +104,19 @@
static FILE *cfile;
static FILE *hfile;
-static const char *syntax[513];
-static int base;
-static int size; /* number of values which a char variable can have */
-static int nbits; /* number of bits in a character */
-static int digit_contig;/* true if digits are contiguous */
-static void filltable(const char *);
-static void init(void);
+static void add_default(void);
+static void finish(void);
+static void init(const char *);
static void add(const char *, const char *);
-static void print(const char *);
static void output_type_macros(void);
-static void digit_convert(void);
int
main(int argc __unused, char **argv __unused)
{
- char c;
- char d;
- int sign;
int i;
char buf[80];
int pos;
- static char digit[] = "0123456789";
/* Create output files */
if ((cfile = fopen("syntax.c", "w")) == NULL) {
@@ -139,33 +130,8 @@
fputs(writer, hfile);
fputs(writer, cfile);
- /* Determine the characteristics of chars. */
- c = -1;
- sign = (c > 0) ? 0 : 1;
- for (nbits = 1 ; ; nbits++) {
- d = (1 << nbits) - 1;
- if (d == c)
- break;
- }
-#if 0
- printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
-#endif
- if (nbits > 9) {
- fputs("Characters can't have more than 9 bits\n", stderr);
- exit(2);
- }
- size = (1 << nbits) + 1;
- base = 1;
- if (sign)
- base += 1 << (nbits - 1);
- digit_contig = 1;
- for (i = 0 ; i < 10 ; i++) {
- if (digit[i] != '0' + i)
- digit_contig = 0;
- }
-
fputs("#include <sys/cdefs.h>\n", hfile);
- fputs("#include <ctype.h>\n", hfile);
+ fputs("#include <limits.h>\n\n", hfile);
/* Generate the #define statements in the header file */
fputs("/* Syntax classes */\n", hfile);
@@ -186,8 +152,8 @@
fprintf(hfile, "/* %s */\n", is_entry[i].comment);
}
putc('\n', hfile);
- fprintf(hfile, "#define SYNBASE %d\n", base);
- fprintf(hfile, "#define PEOF %d\n\n", -base);
+ fputs("#define SYNBASE (1 - CHAR_MIN)\n", hfile);
+ fputs("#define PEOF -SYNBASE\n\n", hfile);
putc('\n', hfile);
fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
@@ -198,10 +164,13 @@
putc('\n', hfile);
/* Generate the syntax tables. */
+ fputs("#include \"parser.h\"\n", cfile);
fputs("#include \"shell.h\"\n", cfile);
fputs("#include \"syntax.h\"\n\n", cfile);
- init();
+
fputs("/* syntax table used when not in quotes */\n", cfile);
+ init("basesyntax");
+ add_default();
add("\n", "CNL");
add("\\", "CBACK");
add("'", "CSQUOTE");
@@ -210,9 +179,11 @@
add("$", "CVAR");
add("}", "CENDVAR");
add("<>();&| \t", "CSPCL");
- print("basesyntax");
- init();
+ finish();
+
fputs("\n/* syntax table used when in double quotes */\n", cfile);
+ init("dqsyntax");
+ add_default();
add("\n", "CNL");
add("\\", "CBACK");
add("\"", "CENDQUOTE");
@@ -221,17 +192,21 @@
add("}", "CENDVAR");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
- print("dqsyntax");
- init();
+ finish();
+
fputs("\n/* syntax table used when in single quotes */\n", cfile);
+ init("sqsyntax");
+ add_default();
add("\n", "CNL");
add("\\", "CSBACK");
add("'", "CENDQUOTE");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
- print("sqsyntax");
- init();
+ finish();
+
fputs("\n/* syntax table used when in arithmetic */\n", cfile);
+ init("arisyntax");
+ add_default();
add("\n", "CNL");
add("\\", "CBACK");
add("`", "CBQUOTE");
@@ -240,102 +215,95 @@
add("}", "CENDVAR");
add("(", "CLP");
add(")", "CRP");
- print("arisyntax");
- filltable("0");
+ finish();
+
fputs("\n/* character classification table */\n", cfile);
+ init("is_type");
add("0123456789", "ISDIGIT");
add("abcdefghijklmnopqrstuvwxyz", "ISLOWER");
add("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ISUPPER");
add("_", "ISUNDER");
add("#?$!-*@", "ISSPECL");
- print("is_type");
- if (! digit_contig)
- digit_convert();
+ finish();
+
exit(0);
}
-
/*
- * Clear the syntax table.
+ * Output the header and declaration of a syntax table.
*/
static void
-filltable(const char *dftval)
+init(const char *name)
{
- int i;
+ fprintf(hfile, "extern const char %s[];\n", name);
+ fprintf(cfile, "const char %s[SYNBASE + CHAR_MAX + 1] = {\n", name);
+}
- for (i = 0 ; i < size ; i++)
- syntax[i] = dftval;
+
+static void
+add_one(const char *key, const char *type)
+{
+ fprintf(cfile, "\t[SYNBASE + %s] = %s,\n", key, type);
}
/*
- * Initialize the syntax table with default values.
+ * Add default values to the syntax table.
*/
static void
-init(void)
+add_default(void)
{
- filltable("CWORD");
- syntax[0] = "CEOF";
- syntax[base + CTLESC] = "CCTL";
- syntax[base + CTLVAR] = "CCTL";
- syntax[base + CTLENDVAR] = "CCTL";
- syntax[base + CTLBACKQ] = "CCTL";
- syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
- syntax[base + CTLARI] = "CCTL";
- syntax[base + CTLENDARI] = "CCTL";
- syntax[base + CTLQUOTEMARK] = "CCTL";
- syntax[base + CTLQUOTEEND] = "CCTL";
+ add_one("PEOF", "CEOF");
+ add_one("CTLESC", "CCTL");
+ add_one("CTLVAR", "CCTL");
+ add_one("CTLENDVAR", "CCTL");
+ add_one("CTLBACKQ", "CCTL");
+ add_one("CTLBACKQ + CTLQUOTE", "CCTL");
+ add_one("CTLARI", "CCTL");
+ add_one("CTLENDARI", "CCTL");
+ add_one("CTLQUOTEMARK", "CCTL");
+ add_one("CTLQUOTEEND", "CCTL");
}
/*
- * Add entries to the syntax table.
+ * Output the footer of a syntax table.
*/
static void
-add(const char *p, const char *type)
+finish(void)
{
- while (*p)
- syntax[*p++ + base] = type;
+ fputs("};\n", cfile);
}
-
/*
- * Output the syntax table.
+ * Add entries to the syntax table.
*/
static void
-print(const char *name)
+add(const char *p, const char *type)
{
- int i;
- int col;
+ for (; *p; ++p) {
+ char c = *p;
+ switch (c) {
+ case '\t': c = 't'; break;
+ case '\n': c = 'n'; break;
+ case '\'': c = '\''; break;
+ case '\\': c = '\\'; break;
- fprintf(hfile, "extern const char %s[];\n", name);
- fprintf(cfile, "const char %s[%d] = {\n", name, size);
- col = 0;
- for (i = 0 ; i < size ; i++) {
- if (i == 0) {
- fputs(" ", cfile);
- } else if ((i & 03) == 0) {
- fputs(",\n ", cfile);
- col = 0;
- } else {
- putc(',', cfile);
- while (++col < 9 * (i & 03))
- putc(' ', cfile);
+ default:
+ fprintf(cfile, "\t[SYNBASE + '%c'] = %s,\n", c, type);
+ continue;
}
- fputs(syntax[i], cfile);
- col += strlen(syntax[i]);
+ fprintf(cfile, "\t[SYNBASE + '\\%c'] = %s,\n", c, type);
}
- fputs("\n};\n", cfile);
}
-
/*
* Output character classification macros (e.g. is_digit). If digits are
* contiguous, we can test for them quickly.
@@ -342,12 +310,13 @@
*/
static const char *macro[] = {
- "#define is_digit(c)\t((is_type+SYNBASE)[(int)c] & ISDIGIT)",
+ "#define is_digit(c)\t((unsigned int)((c) - '0') <= 9)",
"#define is_eof(c)\t((c) == PEOF)",
"#define is_alpha(c)\t((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER))",
"#define is_name(c)\t((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER|ISUNDER))",
"#define is_in_name(c)\t((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))",
"#define is_special(c)\t((is_type+SYNBASE)[(int)c] & (ISSPECL|ISDIGIT))",
+ "#define digit_val(c)\t((c) - '0')",
NULL
};
@@ -356,41 +325,6 @@
{
const char **pp;
- if (digit_contig)
- macro[0] = "#define is_digit(c)\t((unsigned int)((c) - '0') <= 9)";
for (pp = macro ; *pp ; pp++)
fprintf(hfile, "%s\n", *pp);
- if (digit_contig)
- fputs("#define digit_val(c)\t((c) - '0')\n", hfile);
- else
- fputs("#define digit_val(c)\t(digit_value[c])\n", hfile);
}
-
-
-
-/*
- * Output digit conversion table (if digits are not contiguous).
- */
-
-static void
-digit_convert(void)
-{
- int maxdigit;
- static char digit[] = "0123456789";
- char *p;
- int i;
-
- maxdigit = 0;
- for (p = digit ; *p ; p++)
- if (*p > maxdigit)
- maxdigit = *p;
- fputs("extern const char digit_value[];\n", hfile);
- fputs("\n\nconst char digit_value[] = {\n", cfile);
- for (i = 0 ; i <= maxdigit ; i++) {
- for (p = digit ; *p && *p != i ; p++);
- if (*p == '\0')
- p = digit;
- fprintf(cfile, " %d,\n", (int)(p - digit));
- }
- fputs("};\n", cfile);
-}
Modified: trunk/bin/sh/myhistedit.h
===================================================================
--- trunk/bin/sh/myhistedit.h 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/myhistedit.h 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
Modified: trunk/bin/sh/parser.c
===================================================================
--- trunk/bin/sh/parser.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/parser.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -240,9 +241,9 @@
n2 = andor();
tok = readtoken();
if (tok == TBACKGND) {
- if (n2->type == NPIPE) {
+ if (n2 != NULL && n2->type == NPIPE) {
n2->npipe.backgnd = 1;
- } else if (n2->type == NREDIR) {
+ } else if (n2 != NULL && n2->type == NREDIR) {
n2->type = NBACKGND;
} else {
n3 = (union node *)stalloc(sizeof (struct nredir));
Modified: trunk/bin/sh/parser.h
===================================================================
--- trunk/bin/sh/parser.h 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/parser.h 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -39,7 +40,7 @@
#define CTLENDVAR '\371'
#define CTLBACKQ '\372'
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
-/* CTLBACKQ | CTLQUOTE == '\205' */
+/* CTLBACKQ | CTLQUOTE == '\373' */
#define CTLARI '\374'
#define CTLENDARI '\375'
#define CTLQUOTEMARK '\376'
Modified: trunk/bin/sh/sh.1
===================================================================
--- trunk/bin/sh/sh.1 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/sh.1 2015-06-07 01:10:43 UTC (rev 7009)
@@ -30,9 +30,10 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
+.\" $FreeBSD: release/9.2.0/bin/sh/sh.1 252611 2013-07-03 21:31:13Z jilles $
.\" $MidnightBSD$
.\"
-.Dd November 5, 2011
+.Dd June 14, 2013
.Dt SH 1
.Os
.Sh NAME
@@ -1036,6 +1037,9 @@
The file creation mask as set by
.Ic umask .
.It
+Resource limits as set by
+.Ic ulimit .
+.It
References to open files.
.It
Traps as set by
@@ -1061,6 +1065,9 @@
If job control is enabled in an interactive shell,
commands grouped in parentheses can be suspended and continued as a unit.
.Pp
+For compatibility with other shells,
+two open parentheses in sequence should be separated by whitespace.
+.Pp
The second form never forks another shell,
so it is slightly more efficient.
Grouping commands together this way allows the user to
@@ -1604,6 +1611,16 @@
.Ic times
returns information about the same process
if they are the only command in a command substitution.
+.Pp
+If a command substitution of the
+.Li $(
+form begins with a subshell,
+the
+.Li $(
+and
+.Li (\&
+must be separated by whitespace
+to avoid ambiguity with arithmetic expansion.
.Ss Arithmetic Expansion
Arithmetic expansion provides a mechanism for evaluating an arithmetic
expression and substituting its value.
Modified: trunk/bin/sh/var.c
===================================================================
--- trunk/bin/sh/var.c 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/var.c 2015-06-07 01:10:43 UTC (rev 7009)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -94,6 +95,7 @@
struct var vps4;
struct var vvers;
static struct var voptind;
+struct var vdisvfork;
int forcelocal;
@@ -125,6 +127,8 @@
#endif
{ &voptind, 0, "OPTIND=1",
getoptsreset },
+ { &vdisvfork, VUNSET, "SH_DISABLE_VFORK=",
+ NULL },
{ NULL, 0, NULL,
NULL }
};
Modified: trunk/bin/sh/var.h
===================================================================
--- trunk/bin/sh/var.h 2015-05-22 22:50:06 UTC (rev 7008)
+++ trunk/bin/sh/var.h 2015-06-07 01:10:43 UTC (rev 7009)
@@ -79,6 +79,7 @@
extern struct var vps1;
extern struct var vps2;
extern struct var vps4;
+extern struct var vdisvfork;
#ifndef NO_HISTORY
extern struct var vhistsize;
extern struct var vterm;
@@ -109,6 +110,7 @@
#endif
#define mpathset() ((vmpath.flags & VUNSET) == 0)
+#define disvforkset() ((vdisvfork.flags & VUNSET) == 0)
void initvar(void);
void setvar(const char *, const char *, int);
More information about the Midnightbsd-cvs
mailing list