[Midnightbsd-cvs] src: bin/sh: Bring in changes from CURRENT.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Mon Jun 30 20:20:29 EDT 2008
Log Message:
-----------
Bring in changes from CURRENT.
This fixes the GNU autotools problems with newer software.
Tags:
----
RELENG_0_2
Modified Files:
--------------
src/bin/sh:
TOUR (r1.2 -> r1.2.2.1)
arith.h (r1.2 -> r1.2.2.1)
arith.y (r1.2 -> r1.2.2.1)
builtins.def (r1.2 -> r1.2.2.1)
cd.c (r1.3 -> r1.3.2.1)
error.c (r1.2 -> r1.2.2.1)
eval.c (r1.2 -> r1.2.2.1)
exec.c (r1.2 -> r1.2.2.1)
exec.h (r1.2 -> r1.2.2.1)
expand.c (r1.2 -> r1.2.2.1)
input.c (r1.2 -> r1.2.2.1)
jobs.c (r1.2 -> r1.2.2.1)
jobs.h (r1.2 -> r1.2.2.1)
main.c (r1.2 -> r1.2.2.1)
mkbuiltins (r1.2 -> r1.2.2.1)
options.c (r1.2 -> r1.2.2.1)
parser.c (r1.2 -> r1.2.2.1)
parser.h (r1.2 -> r1.2.2.1)
sh.1 (r1.2 -> r1.2.2.1)
shell.h (r1.2 -> r1.2.2.1)
var.c (r1.2 -> r1.2.2.1)
var.h (r1.2 -> r1.2.2.1)
-------------- next part --------------
Index: mkbuiltins
===================================================================
RCS file: /home/cvs/src/bin/sh/mkbuiltins,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/mkbuiltins -L bin/sh/mkbuiltins -u -r1.2 -r1.2.2.1
--- bin/sh/mkbuiltins
+++ bin/sh/mkbuiltins
@@ -67,9 +67,14 @@
const struct builtincmd builtincmd[] = {'
awk '{ for (i = 2 ; i <= NF ; i++) {
- printf "\t{ \"%s\", %d },\n", $i, NR-1
+ if ($i == "-s") {
+ spc = 1;
+ } else {
+ printf "\t{ \"%s\", %d, %d },\n", $i, NR-1, spc
+ spc = 0;
+ }
}}' $temp
-echo ' { NULL, 0 }
+echo ' { NULL, 0, 0 }
};'
exec > ${objdir}/builtins.h
@@ -86,6 +91,7 @@
struct builtincmd {
char *name;
int code;
+ int special;
};
extern int (*const builtinfunc[])(int, char **);
Index: expand.c
===================================================================
RCS file: /home/cvs/src/bin/sh/expand.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/expand.c -L bin/sh/expand.c -u -r1.2 -r1.2.2.1
--- bin/sh/expand.c
+++ bin/sh/expand.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/expand.c,v 1.47.2.1 2005/11/06 20:39:47 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/expand.c,v 1.47.2.5 2008/04/27 20:43:26 stefanf Exp $");
#include <sys/types.h>
#include <sys/time.h>
@@ -99,7 +99,7 @@
STATIC int subevalvar(char *, char *, int, int, int, int);
STATIC char *evalvar(char *, int);
STATIC int varisset(char *, int);
-STATIC void varvalue(char *, int, int);
+STATIC void varvalue(char *, int, int, int);
STATIC void recordregion(int, int, int);
STATIC void removerecordregions(int);
STATIC void ifsbreakup(char *, struct arglist *);
@@ -634,7 +634,7 @@
int easy;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
- varflags = *p++;
+ varflags = (unsigned char)*p++;
subtype = varflags & VSTYPE;
var = p;
special = 0;
@@ -670,7 +670,7 @@
if (set && subtype != VSPLUS) {
/* insert the value of the variable */
if (special) {
- varvalue(var, varflags & VSQUOTE, flag & EXP_FULL);
+ varvalue(var, varflags & VSQUOTE, subtype, flag);
if (subtype == VSLENGTH) {
varlen = expdest - stackblock() - startloc;
STADJUST(-varlen, expdest);
@@ -764,6 +764,11 @@
goto record;
break;
+ case VSERROR:
+ c = p - var - 1;
+ error("${%.*s%s}: Bad substitution", c, var,
+ (c > 0 && *p != CTLENDVAR) ? "..." : "");
+
default:
abort();
}
@@ -837,7 +842,7 @@
*/
STATIC void
-varvalue(char *name, int quoted, int allow_split)
+varvalue(char *name, int quoted, int subtype, int flag)
{
int num;
char *p;
@@ -849,7 +854,7 @@
#define STRTODEST(p) \
do {\
- if (allow_split) { \
+ if (flag & (EXP_FULL | EXP_CASE) && subtype != VSLENGTH) { \
syntax = quoted? DQSYNTAX : BASESYNTAX; \
while (*p) { \
if (syntax[(int)*p] == CCTL) \
@@ -884,7 +889,7 @@
}
break;
case '@':
- if (allow_split && quoted) {
+ if (flag & EXP_FULL && quoted) {
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
STRTODEST(p);
if (*ap)
Index: exec.c
===================================================================
RCS file: /home/cvs/src/bin/sh/exec.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/exec.c -L bin/sh/exec.c -u -r1.2 -r1.2.2.1
--- bin/sh/exec.c
+++ bin/sh/exec.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/exec.c,v 1.25.2.1 2005/11/06 20:39:47 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/exec.c,v 1.25.2.3 2007/02/04 10:42:30 stefanf Exp $");
#include <sys/types.h>
#include <sys/stat.h>
@@ -85,6 +85,7 @@
struct tblentry {
struct tblentry *next; /* next entry in hash chain */
union param param; /* definition of builtin function */
+ int special; /* flag for special builtin commands */
short cmdtype; /* index identifying command */
char rehash; /* if set, cd done since entry created */
char cmdname[ARB]; /* name of command */
@@ -318,6 +319,7 @@
struct stat statb;
int e;
int i;
+ int spec;
/* If name contains a slash, don't use the hash table */
if (strchr(name, '/') != NULL) {
@@ -331,11 +333,12 @@
goto success;
/* If %builtin not in path, check for builtin next */
- if (builtinloc < 0 && (i = find_builtin(name)) >= 0) {
+ if (builtinloc < 0 && (i = find_builtin(name, &spec)) >= 0) {
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
+ cmdp->special = spec;
INTON;
goto success;
}
@@ -357,12 +360,13 @@
index++;
if (pathopt) {
if (prefix("builtin", pathopt)) {
- if ((i = find_builtin(name)) < 0)
+ if ((i = find_builtin(name, &spec)) < 0)
goto loop;
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
+ cmdp->special = spec;
INTON;
goto success;
} else if (prefix("func", pathopt)) {
@@ -431,6 +435,7 @@
cmdp->rehash = 0;
entry->cmdtype = cmdp->cmdtype;
entry->u = cmdp->param;
+ entry->special = cmdp->special;
}
@@ -440,13 +445,15 @@
*/
int
-find_builtin(char *name)
+find_builtin(char *name, int *special)
{
const struct builtincmd *bp;
for (bp = builtincmd ; bp->name ; bp++) {
- if (*bp->name == *name && equal(bp->name, name))
+ if (*bp->name == *name && equal(bp->name, name)) {
+ *special = bp->special;
return bp->code;
+ }
}
return -1;
}
@@ -774,14 +781,17 @@
" a tracked alias for" : "",
name);
} else {
- if (access(argv[i], X_OK) == 0) {
+ if (eaccess(argv[i], X_OK) == 0) {
if (cmd == TYPECMD_SMALLV)
out1fmt("%s\n", argv[i]);
else
out1fmt(" is %s\n", argv[i]);
+ } else {
+ if (cmd != TYPECMD_SMALLV)
+ out1fmt(": %s\n",
+ strerror(errno));
+ error |= 127;
}
- else
- out1fmt(": %s\n", strerror(errno));
}
break;
}
Index: error.c
===================================================================
RCS file: /home/cvs/src/bin/sh/error.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/error.c -L bin/sh/error.c -u -r1.2 -r1.2.2.1
--- bin/sh/error.c
+++ bin/sh/error.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/error.c,v 1.25 2004/04/06 20:06:51 markm Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/error.c,v 1.26 2006/02/04 14:37:50 schweikh Exp $");
/*
* Errors and exceptions.
@@ -119,7 +119,7 @@
* This doesn't seem to be needed, since main() emits a newline.
*/
#if 0
- if (tcgetpgrp(0) == getpid())
+ if (tcgetpgrp(0) == getpid())
write(STDERR_FILENO, "\n", 1);
#endif
if (rootshell && iflag)
Index: exec.h
===================================================================
RCS file: /home/cvs/src/bin/sh/exec.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/exec.h -L bin/sh/exec.h -u -r1.2 -r1.2.2.1
--- bin/sh/exec.h
+++ bin/sh/exec.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)exec.h 8.3 (Berkeley) 6/8/95
- * $FreeBSD: src/bin/sh/exec.h,v 1.12.8.1 2005/11/06 20:39:47 stefanf Exp $
+ * $FreeBSD: src/bin/sh/exec.h,v 1.12.8.2 2006/06/03 15:38:07 stefanf Exp $
*/
/* values of cmdtype */
@@ -53,6 +53,7 @@
int index;
union node *func;
} u;
+ int special;
};
@@ -63,7 +64,7 @@
char *padvance(char **, char *);
int hashcmd(int, char **);
void find_command(char *, struct cmdentry *, int, char *);
-int find_builtin(char *);
+int find_builtin(char *, int *);
void hashcd(void);
void changepath(const char *);
void deletefuncs(void);
Index: arith.h
===================================================================
RCS file: /home/cvs/src/bin/sh/arith.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/arith.h -L bin/sh/arith.h -u -r1.2 -r1.2.2.1
--- bin/sh/arith.h
+++ bin/sh/arith.h
@@ -28,7 +28,7 @@
* SUCH DAMAGE.
*
* @(#)arith.h 1.1 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/arith.h,v 1.9.8.1 2005/11/06 20:39:47 stefanf Exp $
+ * $FreeBSD: src/bin/sh/arith.h,v 1.9.8.3 2008/04/27 20:43:26 stefanf Exp $
*/
extern char *arith_buf, *arith_startbuf;
Index: var.h
===================================================================
RCS file: /home/cvs/src/bin/sh/var.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/var.h -L bin/sh/var.h -u -r1.2 -r1.2.2.1
--- bin/sh/var.h
+++ bin/sh/var.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)var.h 8.2 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/var.h,v 1.12 2004/04/06 20:06:51 markm Exp $
+ * $FreeBSD: src/bin/sh/var.h,v 1.12.8.1 2006/11/22 00:11:11 stefanf Exp $
*/
/*
@@ -75,6 +75,7 @@
extern struct var vppid;
extern struct var vps1;
extern struct var vps2;
+extern struct var vps4;
#ifndef NO_HISTORY
extern struct var vhistsize;
#endif
@@ -92,6 +93,7 @@
#define pathval() (vpath.text + 5)
#define ps1val() (vps1.text + 4)
#define ps2val() (vps2.text + 4)
+#define ps4val() (vps4.text + 4)
#define optindval() (voptind.text + 7)
#ifndef NO_HISTORY
#define histsizeval() (vhistsize.text + 9)
Index: options.c
===================================================================
RCS file: /home/cvs/src/bin/sh/options.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/options.c -L bin/sh/options.c -u -r1.2 -r1.2.2.1
--- bin/sh/options.c
+++ bin/sh/options.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/options.c,v 1.23.2.1 2005/11/06 20:39:48 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/options.c,v 1.23.2.3 2008/04/20 18:08:46 stefanf Exp $");
#include <signal.h>
#include <unistd.h>
@@ -375,7 +375,7 @@
if (argc > 1)
n = number(argv[1]);
if (n > shellparam.nparam)
- error("can't shift that many");
+ return 1;
INTOFF;
shellparam.nparam -= n;
for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
@@ -384,7 +384,7 @@
}
ap2 = shellparam.p;
while ((*ap2++ = *ap1++) != NULL);
- shellparam.optnext = NULL;
+ shellparam.reset = 1;
INTON;
return 0;
}
@@ -406,6 +406,7 @@
if (*argptr != NULL) {
setparam(argptr);
}
+ shellparam.reset = 1;
INTON;
return 0;
}
@@ -415,7 +416,6 @@
getoptsreset(const char *value)
{
if (number(value) == 1) {
- shellparam.optnext = NULL;
shellparam.reset = 1;
}
}
Index: main.c
===================================================================
RCS file: /home/cvs/src/bin/sh/main.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/main.c -L bin/sh/main.c -u -r1.2 -r1.2.2.1
--- bin/sh/main.c
+++ bin/sh/main.c
@@ -43,7 +43,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/main.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/main.c,v 1.26.8.2 2006/11/22 00:23:09 stefanf Exp $");
#include <stdio.h>
#include <signal.h>
@@ -210,7 +210,7 @@
inter = 0;
if (iflag && top) {
inter++;
- showjobs(1, 0, 0);
+ showjobs(1, SHOWJOBS_DEFAULT);
chkmail(0);
flushout(&output);
}
@@ -315,19 +315,21 @@
dotcmd(int argc, char **argv)
{
struct strlist *sp;
+ char *fullname;
+
+ if (argc < 2)
+ error("missing filename");
+
exitstatus = 0;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
- if (argc >= 2) { /* That's what SVR2 does */
- char *fullname = find_dot_file(argv[1]);
-
- setinputfile(fullname, 1);
- commandname = fullname;
- cmdloop(0);
- popfile();
- }
+ fullname = find_dot_file(argv[1]);
+ setinputfile(fullname, 1);
+ commandname = fullname;
+ cmdloop(0);
+ popfile();
return exitstatus;
}
Index: jobs.h
===================================================================
RCS file: /home/cvs/src/bin/sh/jobs.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/jobs.h -L bin/sh/jobs.h -u -r1.2 -r1.2.2.1
--- bin/sh/jobs.h
+++ bin/sh/jobs.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)jobs.h 8.2 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/jobs.h,v 1.18 2004/04/06 20:06:51 markm Exp $
+ * $FreeBSD: src/bin/sh/jobs.h,v 1.18.8.1 2006/11/22 00:23:09 stefanf Exp $
*/
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
@@ -75,6 +75,13 @@
#endif
};
+enum {
+ SHOWJOBS_DEFAULT, /* job number, status, command */
+ SHOWJOBS_VERBOSE, /* job number, PID, status, command */
+ SHOWJOBS_PIDS, /* PID only */
+ SHOWJOBS_PGIDS /* PID of the group leader only */
+};
+
extern pid_t backgndpid; /* pid of last background process */
extern int job_warning; /* user was warned about stopped jobs */
extern int in_waitcmd; /* are we in waitcmd()? */
@@ -85,7 +92,7 @@
int fgcmd(int, char **);
int bgcmd(int, char **);
int jobscmd(int, char **);
-void showjobs(int, int, int);
+void showjobs(int, int);
int waitcmd(int, char **);
int jobidcmd(int, char **);
struct job *makejob(union node *, int);
Index: TOUR
===================================================================
RCS file: /home/cvs/src/bin/sh/TOUR,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/TOUR -L bin/sh/TOUR -u -r1.2 -r1.2.2.1
--- bin/sh/TOUR
+++ bin/sh/TOUR
@@ -23,8 +23,8 @@
programs that generate source code. A complete list of these
programs is:
- program intput files generates
- ------- ------------ ---------
+ program input files generates
+ ------- ----------- ---------
mkbuiltins builtins builtins.h builtins.c
mkinit *.c init.c
mknodes nodetypes nodes.h nodes.c
@@ -92,7 +92,7 @@
EXINT exception to return to the main command loop. (Exception:
EXINT is not raised if the user traps interrupts using the trap
command.) The INTOFF and INTON macros (defined in exception.h)
-provide uninterruptable critical sections. Between the execution
+provide uninterruptible critical sections. Between the execution
of INTOFF and the execution of INTON, interrupt signals will be
held for later delivery. INTOFF and INTON can be nested.
@@ -111,7 +111,7 @@
p = stackptr;
*p++ = c; /* repeated as many times as needed */
stackptr = p;
-The folloing three macros (defined in memalloc.h) perform these
+The following three macros (defined in memalloc.h) perform these
operations, but grow the stack if you run off the end:
STARTSTACKSTR(p);
STPUTC(c, p); /* repeated as many times as needed */
@@ -120,7 +120,7 @@
We now start a top-down look at the code:
MAIN.C: The main routine performs some initialization, executes
-the user's profile if necessary, and calls cmdloop. Cmdloop is
+the user's profile if necessary, and calls cmdloop. Cmdloop
repeatedly parses and executes commands.
OPTIONS.C: This file contains the option processing code. It is
@@ -179,7 +179,7 @@
VSQUESTION ${var?text}
VSQUESTION|VSNUL ${var:?text}
VSASSIGN ${var=text}
- VSASSIGN|VSNUL ${var=text}
+ VSASSIGN|VSNUL ${var:=text}
In addition, the type field will have the VSQUOTE flag set if the
variable is enclosed in double quotes. The name of the variable
@@ -205,7 +205,7 @@
field can be written without any processing). Other here docu-
ments, and words which are not subject to splitting and file name
generation, have the CTLESC characters removed during the vari-
-able and command substitution phase. Words which are subject
+able and command substitution phase. Words which are subject to
splitting and file name generation have the CTLESC characters re-
moved as part of the file name phase.
@@ -213,7 +213,7 @@
eval.c The top level routines.
redir.c Code to handle redirection of input and output.
jobs.c Code to handle forking, waiting, and job control.
- exec.c Code to to path searches and the actual exec sys call.
+ exec.c Code to do path searches and the actual exec sys call.
expand.c Code to evaluate arguments.
var.c Maintains the variable symbol table. Called from expand.c.
@@ -233,7 +233,7 @@
REDIR.C: Ash allows file descriptors to be redirected and then
restored without forking off a child process. This is accom-
plished by duplicating the original file descriptors. The redir-
-tab structure records where the file descriptors have be dupli-
+tab structure records where the file descriptors have been dupli-
cated to.
EXEC.C: The routine find_command locates a command, and enters
@@ -284,8 +284,8 @@
tered throughout the code, depending on which location appears
most appropriate. They can be recognized because their names al-
ways end in "cmd". The mapping from names to procedures is
-specified in the file builtins, which is processed by the mkbuil-
-tins command.
+specified in the file builtins, which is processed by the mkbuilt-
+ins command.
A builtin command is invoked with argc and argv set up like a
normal program. A builtin command is allowed to overwrite its
Index: eval.c
===================================================================
RCS file: /home/cvs/src/bin/sh/eval.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/eval.c -L bin/sh/eval.c -u -r1.2 -r1.2.2.1
--- bin/sh/eval.c
+++ bin/sh/eval.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/eval.c,v 1.42.8.2 2005/12/26 15:43:54 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/eval.c,v 1.42.8.6 2007/10/26 10:23:27 stefanf Exp $");
#include <paths.h>
#include <signal.h>
@@ -368,6 +368,7 @@
setstackmark(&smark);
arglist.lastp = &arglist.list;
oexitstatus = exitstatus;
+ exitstatus = 0;
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
@@ -644,14 +645,19 @@
/* Print the command if xflag is set. */
if (xflag) {
- outc('+', &errout);
+ char sep = 0;
+ out2str(ps4val());
for (sp = varlist.list ; sp ; sp = sp->next) {
- outc(' ', &errout);
+ if (sep != 0)
+ outc(' ', &errout);
out2str(sp->text);
+ sep = ' ';
}
for (sp = arglist.list ; sp ; sp = sp->next) {
- outc(' ', &errout);
+ if (sep != 0)
+ outc(' ', &errout);
out2str(sp->text);
+ sep = ' ';
}
outc('\n', &errout);
flushout(&errout);
@@ -659,8 +665,10 @@
/* Now locate the command. */
if (argc == 0) {
+ /* Variable assignment(s) without command */
cmdentry.cmdtype = CMDBUILTIN;
cmdentry.u.index = BLTINCMD;
+ cmdentry.special = 1;
} else {
static const char PATH[] = "PATH=";
char *path = pathval();
@@ -706,7 +714,8 @@
argv++;
if (--argc == 0)
break;
- if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
+ if ((cmdentry.u.index = find_builtin(*argv,
+ &cmdentry.special)) < 0) {
outfmt(&errout, "%s: not found\n", *argv);
exitstatus = 127;
flushout(&errout);
@@ -813,7 +822,6 @@
memout.bufsize = 64;
mode |= REDIR_BACKQ;
}
- redirect(cmd->ncmd.redirect, mode);
savecmdname = commandname;
cmdenviron = varlist.list;
e = -1;
@@ -824,6 +832,9 @@
}
savehandler = handler;
handler = &jmploc;
+ redirect(cmd->ncmd.redirect, mode);
+ if (cmdentry.special)
+ listsetvar(cmdenviron);
commandname = argv[0];
argptr = argv + 1;
optptr = NULL; /* initialize nextopt */
@@ -843,14 +854,7 @@
handler = savehandler;
if (e != -1) {
if ((e != EXERROR && e != EXEXEC)
- || cmdentry.u.index == BLTINCMD
- || cmdentry.u.index == DOTCMD
- || cmdentry.u.index == EVALCMD
-#ifndef NO_HISTORY
- || cmdentry.u.index == HISTCMD
-#endif
- || cmdentry.u.index == EXECCMD
- || cmdentry.u.index == COMMANDCMD)
+ || cmdentry.special)
exraise(e);
FORCEINTON;
}
@@ -912,7 +916,7 @@
{
struct cmdentry entry;
- if (n->type == NCMD && n->ncmd.args)
+ if (n && n->type == NCMD && n->ncmd.args)
if (goodname(n->ncmd.args->narg.text))
find_command(n->ncmd.args->narg.text, &entry, 0,
pathval());
@@ -926,14 +930,12 @@
*/
/*
- * No command given, or a bltin command with no arguments. Set the
- * specified variables.
+ * No command given, or a bltin command with no arguments.
*/
int
bltincmd(int argc __unused, char **argv __unused)
{
- listsetvar(cmdenviron);
/*
* Preserve exitstatus of a previous possible redirection
* as POSIX mandates
Index: parser.h
===================================================================
RCS file: /home/cvs/src/bin/sh/parser.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/parser.h -L bin/sh/parser.h -u -r1.2 -r1.2.2.1
--- bin/sh/parser.h
+++ bin/sh/parser.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)parser.h 8.3 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/parser.h,v 1.10 2004/04/06 20:06:51 markm Exp $
+ * $FreeBSD: src/bin/sh/parser.h,v 1.10.8.1 2006/11/22 00:26:06 stefanf Exp $
*/
/* control characters in argument strings */
@@ -61,6 +61,7 @@
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
#define VSLENGTH 0xa /* ${#var} */
+#define VSERROR 0xb /* Syntax error, issue when expanded */
/*
Index: builtins.def
===================================================================
RCS file: /home/cvs/src/bin/sh/builtins.def,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/builtins.def -L bin/sh/builtins.def -u -r1.2 -r1.2.2.1
--- bin/sh/builtins.def
+++ bin/sh/builtins.def
@@ -37,13 +37,15 @@
#
# This file lists all the builtin commands. The first column is the name
-# of a C routine. The -j flag, if present, specifies that this command
-# is to be excluded from systems without job control, and the -h flag,
-# if present specifies that this command is to be excluded from systems
-# based on the NO_HISTORY compile-time symbol. The rest of the line
-# specifies the command name or names used to run the command. The entry
-# for bltincmd, which is run when the user does not specify a command, must
-# come first.
+# of a C routine.
+# The -j flag specifies that this command is to be excluded from systems
+# without job control.
+# The -h flag specifies that this command is to be excluded from systems
+# based on the NO_HISTORY compile-time symbol.
+# The -s flag specifies that this is a POSIX 'special built-in' command.
+# The rest of the line specifies the command name or names used to run the
+# command. The entry for bltincmd, which is run when the user does not specify
+# a command, must come first.
#
# NOTE: bltincmd must come first!
@@ -51,16 +53,16 @@
aliascmd alias
bgcmd -j bg
bindcmd bind
-breakcmd break continue
+breakcmd -s break -s continue
cdcmd cd chdir
commandcmd command
-dotcmd .
+dotcmd -s .
echocmd echo
-evalcmd eval
-execcmd exec
-exitcmd exit
+evalcmd -s eval
+execcmd -s exec
+exitcmd -s exit
expcmd exp let
-exportcmd export readonly
+exportcmd -s export -s readonly
#exprcmd expr
falsecmd false
fgcmd -j fg
@@ -73,18 +75,18 @@
#printfcmd printf
pwdcmd pwd
readcmd read
-returncmd return
-setcmd set
+returncmd -s return
+setcmd -s set
setvarcmd setvar
-shiftcmd shift
+shiftcmd -s shift
testcmd test [
-timescmd times
-trapcmd trap
-truecmd : true
+timescmd -s times
+trapcmd -s trap
+truecmd -s : true
typecmd type
ulimitcmd ulimit
umaskcmd umask
unaliascmd unalias
-unsetcmd unset
+unsetcmd -s unset
waitcmd wait
wordexpcmd wordexp
Index: parser.c
===================================================================
RCS file: /home/cvs/src/bin/sh/parser.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/parser.c -L bin/sh/parser.c -u -r1.2 -r1.2.2.1
--- bin/sh/parser.c
+++ bin/sh/parser.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/parser.c,v 1.52.2.1 2005/11/06 20:39:48 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/parser.c,v 1.52.2.3 2006/11/22 00:26:06 stefanf Exp $");
#include <stdlib.h>
#include <unistd.h>
@@ -953,6 +953,7 @@
USTPUTC('\\', out);
pungetc();
} else if (c == '\n') {
+ plinno++;
if (doprompt)
setprompt(2);
else
@@ -1228,12 +1229,17 @@
c = pgetc();
}
} else {
- if (! is_special(c))
-badsub: synerror("Bad substitution");
- USTPUTC(c, out);
- c = pgetc();
+ if (! is_special(c)) {
+ subtype = VSERROR;
+ if (c == '}')
+ pungetc();
+ else
+ USTPUTC(c, out);
+ } else {
+ USTPUTC(c, out);
+ c = pgetc();
+ }
}
- STPUTC('=', out);
flags = 0;
if (subtype == 0) {
switch (c) {
@@ -1243,9 +1249,13 @@
/*FALLTHROUGH*/
default:
p = strchr(types, c);
- if (p == NULL)
- goto badsub;
- subtype = p - types + VSNORMAL;
+ if (p == NULL) {
+ if (flags == VSNUL)
+ STPUTC(':', out);
+ STPUTC(c, out);
+ subtype = VSERROR;
+ } else
+ subtype = p - types + VSNORMAL;
break;
case '%':
case '#':
@@ -1261,9 +1271,10 @@
break;
}
}
- } else {
+ } else if (subtype != VSERROR) {
pungetc();
}
+ STPUTC('=', out);
if (subtype != VSLENGTH && (dblquote || arinest))
flags |= VSQUOTE;
*(stackblock() + typeloc) = subtype | flags;
Index: jobs.c
===================================================================
RCS file: /home/cvs/src/bin/sh/jobs.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/jobs.c -L bin/sh/jobs.c -u -r1.2 -r1.2.2.1
--- bin/sh/jobs.c
+++ bin/sh/jobs.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/jobs.c,v 1.68.2.2 2006/01/12 05:24:46 maxim Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/jobs.c,v 1.68.2.3 2006/11/22 00:23:09 stefanf Exp $");
#include <fcntl.h>
#include <signal.h>
@@ -99,7 +99,7 @@
STATIC void deljob(struct job *);
STATIC struct job *getcurjob(struct job *);
#endif
-STATIC void showjob(struct job *, pid_t, int, int);
+STATIC void showjob(struct job *, pid_t, int);
/*
@@ -266,18 +266,21 @@
jobscmd(int argc, char *argv[])
{
char *id;
- int ch, sformat, lformat;
+ int ch, mode;
optind = optreset = 1;
opterr = 0;
- sformat = lformat = 0;
- while ((ch = getopt(argc, argv, "ls")) != -1) {
+ mode = SHOWJOBS_DEFAULT;
+ while ((ch = getopt(argc, argv, "lps")) != -1) {
switch (ch) {
case 'l':
- lformat = 1;
+ mode = SHOWJOBS_VERBOSE;
+ break;
+ case 'p':
+ mode = SHOWJOBS_PGIDS;
break;
case 's':
- sformat = 1;
+ mode = SHOWJOBS_PIDS;
break;
case '?':
default:
@@ -288,24 +291,25 @@
argv += optind;
if (argc == 0)
- showjobs(0, sformat, lformat);
+ showjobs(0, mode);
else
while ((id = *argv++) != NULL)
- showjob(getjob(id), 0, sformat, lformat);
+ showjob(getjob(id), 0, mode);
return (0);
}
STATIC void
-showjob(struct job *jp, pid_t pid, int sformat, int lformat)
+showjob(struct job *jp, pid_t pid, int mode)
{
char s[64];
struct procstat *ps;
struct job *j;
int col, curr, i, jobno, prev, procno;
+ pid_t ppid;
char c;
- procno = jp->nprocs;
+ procno = (mode == SHOWJOBS_PGIDS) ? 1 : jp->nprocs;
jobno = jp - jobtab + 1;
curr = prev = 0;
#if JOBS
@@ -316,11 +320,13 @@
}
#endif
for (ps = jp->ps ; ; ps++) { /* for each process */
- if (sformat) {
- out1fmt("%d\n", (int)ps->pid);
+ if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) {
+ ppid = (mode == SHOWJOBS_PIDS) ? ps->pid :
+ getpgid(ps->pid);
+ out1fmt("%d\n", (int)ppid);
goto skip;
}
- if (!lformat && ps != jp->ps && pid == 0)
+ if (mode != SHOWJOBS_VERBOSE && ps != jp->ps && pid == 0)
goto skip;
if (pid != 0 && pid != ps->pid)
goto skip;
@@ -336,7 +342,7 @@
fmtstr(s, 64, " %c ", c);
out1str(s);
col = strlen(s);
- if (lformat) {
+ if (mode == SHOWJOBS_VERBOSE) {
fmtstr(s, 64, "%d ", (int)ps->pid);
out1str(s);
col += strlen(s);
@@ -389,7 +395,7 @@
*/
void
-showjobs(int change, int sformat, int lformat)
+showjobs(int change, int mode)
{
int jobno;
struct job *jp;
@@ -405,7 +411,7 @@
}
if (change && ! jp->changed)
continue;
- showjob(jp, 0, sformat, lformat);
+ showjob(jp, 0, mode);
jp->changed = 0;
if (jp->state == JOBDONE) {
freejob(jp);
@@ -993,7 +999,7 @@
out1str(" (core dumped)");
out1c('\n');
} else
- showjob(thisjob, pid, 0, 0);
+ showjob(thisjob, pid, SHOWJOBS_DEFAULT);
}
} else {
TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job));
Index: shell.h
===================================================================
RCS file: /home/cvs/src/bin/sh/shell.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/shell.h -L bin/sh/shell.h -u -r1.2 -r1.2.2.1
--- bin/sh/shell.h
+++ bin/sh/shell.h
@@ -31,9 +31,14 @@
* SUCH DAMAGE.
*
* @(#)shell.h 8.2 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/shell.h,v 1.17 2004/04/06 20:06:51 markm Exp $
+ * $FreeBSD: src/bin/sh/shell.h,v 1.18 2008/04/27 20:46:45 stefanf Exp $
*/
+#ifndef SHELL_H_
+#define SHELL_H_
+
+#include <inttypes.h>
+
/*
* The follow should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
@@ -51,10 +56,10 @@
/*
* Type of used arithmetics. SUSv3 requires us to have at least signed long.
*/
-typedef long arith_t;
-#define ARITH_FORMAT_STR "%ld"
-#define atoarith_t(arg) strtol(arg, NULL, 0)
-#define strtoarith_t(nptr, endptr, base) strtol(nptr, endptr, base)
+typedef intmax_t arith_t;
+#define ARITH_FORMAT_STR "%" PRIdMAX
+#define atoarith_t(arg) strtoimax(arg, NULL, 0)
+#define strtoarith_t(nptr, endptr, base) strtoimax(nptr, endptr, base)
typedef void *pointer;
#define STATIC static
@@ -69,3 +74,5 @@
#else
#define TRACE(param)
#endif
+
+#endif /* !SHELL_H_ */
Index: sh.1
===================================================================
RCS file: /home/cvs/src/bin/sh/sh.1,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/sh.1 -L bin/sh/sh.1 -u -r1.2 -r1.2.2.1
--- bin/sh/sh.1
+++ bin/sh/sh.1
@@ -33,7 +33,7 @@
.\" $FreeBSD: src/bin/sh/sh.1,v 1.102.2.2 2005/12/26 15:43:54 stefanf Exp $
.\" $MidnightBSD$
.\"
-.Dd December 8, 2005
+.Dd June 29, 2008
.Dt SH 1
.Os
.Sh NAME
@@ -306,8 +306,9 @@
Useful for debugging.
.It Fl x Li xtrace
Write each command
-(preceded by
-.Dq Li "+ " )
+(preceded by the value of the
+.Ev PS4
+variable)
to standard error before it is executed.
Useful for debugging.
.El
@@ -363,6 +364,13 @@
.It Li <& Ta Li >& Ta Li <<- Ta Li >|
.El
.El
+.Pp
+The character
+.Ql #
+introduces a comment if used at the beginning of a word.
+The word starting with
+.Ql #
+and the rest of the line are ignored.
.Ss Quoting
Quoting is used to remove the special meaning of certain characters
or words to the shell, such as operators, whitespace, keywords,
@@ -854,6 +862,10 @@
separated by
.Dq Li \&|
characters.
+The exit code of the
+.Ic case
+command is the exit code of the last command executed in the list or
+zero if no patterns were matched.
.Ss Grouping Commands Together
Commands may be grouped by writing either
.Bd -literal -offset indent
@@ -1354,9 +1366,8 @@
are built-in because they need to perform some operation
that cannot be performed by a separate process.
In addition to
-these, a built-in version of the
-.Xr test 1
-command is provided for efficiency.
+these, built-in versions of essential utilities
+are provided for efficiency.
.Bl -tag -width indent
.It Ic \&:
A null command that returns a 0 (true) exit value.
@@ -1378,6 +1389,9 @@
If it is not found in the
.Ev PATH ,
it is sought in the current working directory.
+.It Ic \&[
+A built-in equivalent of
+.Xr test 1 .
.It Ic alias Oo Ar name Ns Oo = Ns Ar string Oc ... Oc
If
.Ar name Ns = Ns Ar string
@@ -1612,6 +1626,8 @@
option is specified, the exported variables are printed as
.Dq Ic export Ar name Ns = Ns Ar value
lines, suitable for re-input to the shell.
+.It Ic false
+A null command that returns a non-zero (false) exit value.
.It Ic fc Oo Fl e Ar editor Oc Op Ar first Op Ar last
.It Ic fc Fl l Oo Fl nr Oc Op Ar first Op Ar last
.It Ic fc Fl s Oo Ar old Ns = Ns Ar new Oc Op Ar first
@@ -1766,7 +1782,7 @@
If the
.Ar job
argument is omitted, use the current job.
-.It Ic jobs Oo Fl ls Oc Op Ar job ...
+.It Ic jobs Oo Fl lps Oc Op Ar job ...
Print information about the specified jobs, or all jobs if no
.Ar job
argument is given.
@@ -1776,8 +1792,13 @@
.Fl l
option is specified, the PID of each job is also printed.
If the
+.Fl p
+option is specified, only the process IDs for the process group leaders
+are printed, one per line.
+If the
.Fl s
-option is specified, only the PIDs of the jobs are printed, one per line.
+option is specified, only the PIDs of the job commands are printed, one per
+line.
.It Ic local Oo Ar variable ... Oc Op Fl
See the
.Sx Functions
@@ -1952,6 +1973,9 @@
the value of $2 to the value of $3, and so on,
decreasing the value of $# by one.
If there are zero positional parameters, shifting does not do anything.
+.It Ic test
+A built-in equivalent of
+.Xr test 1 .
.It Ic times
Print the amount of time spent executing the shell and its children.
The first output line shows the user and system times for the shell
@@ -1989,6 +2013,8 @@
causes the
.Ic trap
command to display a list of valid signal names.
+.It Ic true
+A null command that returns a 0 (true) exit value.
.It Ic type Op Ar name ...
Interpret each
.Ar name
@@ -2191,6 +2217,12 @@
.It Ev PS2
The secondary prompt string, which defaults to
.Dq Li "> " .
+.It Ev PS4
+The prefix for the trace output (if
+.Fl x
+is active).
+The default is
+.Dq Li "+ " .
.It Ev TERM
The default terminal setting for the shell.
This is inherited by children of the shell, and is used in the history
@@ -2222,8 +2254,23 @@
.Sh HISTORY
A
.Nm
-command appeared in
+command, the Thompson shell, appeared in
.At v1 .
+It was superseded in
+.At v7
+by the Bourne shell, which inherited the name
+.Nm .
+.Pp
+This version of
+.Nm
+was rewritten in 1989 under the
+.Bx
+license after the Bourne shell from
+.At V.4 .
+.Sh AUTHORS
+This version of
+.Nm
+was originally written by Kenneth Almquist.
.Sh BUGS
The
.Nm
Index: arith.y
===================================================================
RCS file: /home/cvs/src/bin/sh/arith.y,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/arith.y -L bin/sh/arith.y -u -r1.2 -r1.2.2.1
--- bin/sh/arith.y
+++ bin/sh/arith.y
@@ -40,7 +40,7 @@
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/arith.y,v 1.19.8.1 2005/11/06 20:39:47 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/arith.y,v 1.19.8.3 2008/04/27 20:43:26 stefanf Exp $");
#include <limits.h>
#include <stdio.h>
Index: input.c
===================================================================
RCS file: /home/cvs/src/bin/sh/input.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/input.c -L bin/sh/input.c -u -r1.2 -r1.2.2.1
--- bin/sh/input.c
+++ bin/sh/input.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/input.c,v 1.22 2004/04/06 20:06:51 markm Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/input.c,v 1.22.8.1 2006/06/03 15:38:07 stefanf Exp $");
#include <stdio.h> /* defines BUFSIZ */
#include <fcntl.h>
@@ -185,14 +185,23 @@
retry:
#ifndef NO_HISTORY
if (parsefile->fd == 0 && el) {
- const char *rl_cp;
+ static const char *rl_cp;
+ static int el_len;
- rl_cp = el_gets(el, &nr);
+ if (rl_cp == NULL)
+ rl_cp = el_gets(el, &el_len);
if (rl_cp == NULL)
nr = 0;
else {
- /* XXX - BUFSIZE should redesign so not necessary */
- (void) strcpy(parsenextc, rl_cp);
+ nr = el_len;
+ if (nr > BUFSIZ - 1)
+ nr = BUFSIZ - 1;
+ memcpy(parsenextc, rl_cp, nr);
+ if (nr != el_len) {
+ el_len -= nr;
+ rl_cp += nr;
+ } else
+ rl_cp = NULL;
}
} else
#endif
Index: cd.c
===================================================================
RCS file: /home/cvs/src/bin/sh/cd.c,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -L bin/sh/cd.c -L bin/sh/cd.c -u -r1.3 -r1.3.2.1
--- bin/sh/cd.c
+++ bin/sh/cd.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/cd.c,v 1.34 2004/04/06 20:06:51 markm Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/cd.c,v 1.34.8.2 2008/04/20 18:08:12 stefanf Exp $");
#include <sys/types.h>
#include <sys/stat.h>
@@ -69,7 +69,9 @@
STATIC int cdphysical(char *);
STATIC int docd(char *, int, int);
STATIC char *getcomponent(void);
-STATIC int updatepwd(char *);
+STATIC char *findcwd(char *);
+STATIC void updatepwd(char *);
+STATIC char *getpwd2(char *, size_t);
STATIC char *curdir = NULL; /* current working directory */
STATIC char *prevdir; /* previous working directory */
@@ -202,10 +204,11 @@
}
INTOFF;
- if (updatepwd(badstat ? NULL : dest) < 0 || chdir(curdir) < 0) {
+ if ((p = findcwd(badstat ? NULL : dest)) == NULL || chdir(p) < 0) {
INTON;
return (-1);
}
+ updatepwd(p);
INTON;
return (0);
}
@@ -213,12 +216,14 @@
STATIC int
cdphysical(char *dest)
{
+ char *p;
INTOFF;
- if (chdir(dest) < 0 || updatepwd(NULL) < 0) {
+ if (chdir(dest) < 0 || (p = findcwd(NULL)) == NULL) {
INTON;
return (-1);
}
+ updatepwd(p);
INTON;
return (0);
}
@@ -248,38 +253,20 @@
}
-/*
- * Update curdir (the name of the current directory) in response to a
- * cd command. We also call hashcd to let the routines in exec.c know
- * that the current directory has changed.
- */
-STATIC int
-updatepwd(char *dir)
+STATIC char *
+findcwd(char *dir)
{
char *new;
char *p;
- hashcd(); /* update command hash table */
-
/*
* If our argument is NULL, we don't know the current directory
* any more because we traversed a symbolic link or something
* we couldn't stat().
*/
if (dir == NULL || curdir == NULL) {
- if (prevdir)
- ckfree(prevdir);
- INTOFF;
- prevdir = curdir;
- curdir = NULL;
- if (getpwd() == NULL) {
- INTON;
- return (-1);
- }
- setvar("PWD", curdir, VEXPORT);
- setvar("OLDPWD", prevdir, VEXPORT);
- INTON;
- return (0);
+ p = stalloc(PATH_MAX);
+ return getpwd2(p, PATH_MAX);
}
cdcomppath = stalloc(strlen(dir) + 1);
scopy(dir, cdcomppath);
@@ -303,16 +290,25 @@
if (new == stackblock())
STPUTC('/', new);
STACKSTRNUL(new);
- INTOFF;
+ return stackblock();
+}
+
+/*
+ * Update curdir (the name of the current directory) in response to a
+ * cd command. We also call hashcd to let the routines in exec.c know
+ * that the current directory has changed.
+ */
+STATIC void
+updatepwd(char *dir)
+{
+ hashcd(); /* update command hash table */
+
if (prevdir)
ckfree(prevdir);
prevdir = curdir;
- curdir = savestr(stackblock());
+ curdir = savestr(dir);
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
- INTON;
-
- return (0);
}
int
@@ -356,17 +352,31 @@
}
/*
- * Find out what the current directory is. If we already know the current
- * directory, this routine returns immediately.
+ * Get the current directory and cache the result in curdir.
*/
char *
getpwd(void)
{
char buf[PATH_MAX];
+ char *p;
if (curdir)
return curdir;
- if (getcwd(buf, sizeof(buf)) == NULL) {
+
+ p = getpwd2(buf, sizeof(buf));
+ if (p != NULL)
+ curdir = savestr(p);
+
+ return curdir;
+}
+
+/*
+ * Return the current directory.
+ */
+STATIC char *
+getpwd2(char *buf, size_t size)
+{
+ if (getcwd(buf, size) == NULL) {
char *pwd = getenv("PWD");
struct stat stdot, stpwd;
@@ -374,12 +384,9 @@
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
- curdir = savestr(pwd);
- return curdir;
+ return pwd;
}
return NULL;
}
- curdir = savestr(buf);
-
- return curdir;
+ return buf;
}
Index: var.c
===================================================================
RCS file: /home/cvs/src/bin/sh/var.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L bin/sh/var.c -L bin/sh/var.c -u -r1.2 -r1.2.2.1
--- bin/sh/var.c
+++ bin/sh/var.c
@@ -37,7 +37,7 @@
#endif
#endif /* not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/sh/var.c,v 1.27.2.1 2005/11/06 20:39:48 stefanf Exp $");
+__FBSDID("$FreeBSD: src/bin/sh/var.c,v 1.27.2.3 2006/11/22 00:11:11 stefanf Exp $");
#include <unistd.h>
#include <stdlib.h>
@@ -89,6 +89,7 @@
struct var vppid;
struct var vps1;
struct var vps2;
+struct var vps4;
struct var vvers;
STATIC struct var voptind;
@@ -112,6 +113,8 @@
*/
{ &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
NULL },
+ { &vps4, VSTRFIXED|VTEXTFIXED, "PS4=+ ",
+ NULL },
{ &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
getoptsreset },
{ NULL, 0, NULL,
@@ -480,6 +483,21 @@
}
+static int
+var_compare(const void *a, const void *b)
+{
+ const char *const *sa, *const *sb;
+
+ sa = a;
+ sb = b;
+ /*
+ * This compares two var=value strings which creates a different
+ * order from what you would probably expect. POSIX is somewhat
+ * ambiguous on what should be sorted exactly.
+ */
+ return strcoll(*sa, *sb);
+}
+
/*
* Command to list all variables which are set. Currently this command
@@ -493,18 +511,41 @@
struct var **vpp;
struct var *vp;
const char *s;
+ const char **vars;
+ int i, n;
- for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
- for (vp = *vpp ; vp ; vp = vp->next) {
- if (vp->flags & VUNSET)
- continue;
- for (s = vp->text; *s != '='; s++)
- out1c(*s);
- out1c('=');
- out1qstr(s + 1);
- out1c('\n');
+ /*
+ * POSIX requires us to sort the variables.
+ */
+ n = 0;
+ for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) {
+ for (vp = *vpp; vp; vp = vp->next) {
+ if (!(vp->flags & VUNSET))
+ n++;
+ }
+ }
+
+ INTON;
+ vars = ckmalloc(n * sizeof(*vars));
+ i = 0;
+ for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) {
+ for (vp = *vpp; vp; vp = vp->next) {
+ if (!(vp->flags & VUNSET))
+ vars[i++] = vp->text;
}
}
+
+ qsort(vars, n, sizeof(*vars), var_compare);
+ for (i = 0; i < n; i++) {
+ for (s = vars[i]; *s != '='; s++)
+ out1c(*s);
+ out1c('=');
+ out1qstr(s + 1);
+ out1c('\n');
+ }
+ ckfree(vars);
+ INTOFF;
+
return 0;
}
More information about the Midnightbsd-cvs
mailing list