summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
committersjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
commit97d8b9495668afa398ab17c8c5f7e223b5fd2e89 (patch)
tree54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /bin
parent5ee3bfdb338e7c80af29a67f4425c4be24c7b866 (diff)
parent086d73aef6d0ab7d21daa2076fdc8d25961f9b05 (diff)
downloadFreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.zip
FreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.tar.gz
sync from head
Diffstat (limited to 'bin')
-rw-r--r--bin/chflags/chflags.c6
-rw-r--r--bin/cp/cp.123
-rw-r--r--bin/dd/dd.c7
-rw-r--r--bin/ed/cbc.c4
-rw-r--r--bin/ls/ls.120
-rw-r--r--bin/mkdir/mkdir.119
-rw-r--r--bin/mv/mv.112
-rw-r--r--bin/mv/mv.c2
-rw-r--r--bin/ps/ps.16
-rw-r--r--bin/rm/rm.115
-rw-r--r--bin/rmdir/rmdir.114
-rw-r--r--bin/setfacl/setfacl.124
-rw-r--r--bin/sh/eval.c6
-rw-r--r--bin/sh/exec.c4
-rw-r--r--bin/sh/expand.c13
-rw-r--r--bin/sh/input.c14
-rw-r--r--bin/sh/input.h4
-rw-r--r--bin/sh/jobs.c14
-rw-r--r--bin/sh/main.c6
-rw-r--r--bin/sh/memalloc.c5
-rw-r--r--bin/sh/memalloc.h4
-rw-r--r--bin/sh/nodes.c.pat6
-rw-r--r--bin/sh/parser.c11
-rw-r--r--bin/sh/parser.h2
-rw-r--r--bin/sh/redir.c18
-rw-r--r--bin/sh/sh.115
-rw-r--r--bin/sh/trap.c42
-rw-r--r--bin/sh/trap.h2
-rw-r--r--bin/test/test.158
-rw-r--r--bin/test/test.c184
30 files changed, 444 insertions, 116 deletions
diff --git a/bin/chflags/chflags.c b/bin/chflags/chflags.c
index 2c07db9..e94c34d 100644
--- a/bin/chflags/chflags.c
+++ b/bin/chflags/chflags.c
@@ -117,11 +117,7 @@ main(int argc, char *argv[])
} else
fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
- /* XXX: Why don't chflags and lchflags have compatible prototypes? */
- if (hflag)
- change_flags = (int (*)(const char *, unsigned long))lchflags;
- else
- change_flags = chflags;
+ change_flags = hflag ? lchflags : chflags;
flags = *argv;
if (*flags >= '0' && *flags <= '7') {
diff --git a/bin/cp/cp.1 b/bin/cp/cp.1
index 8c014b4..169f350 100644
--- a/bin/cp/cp.1
+++ b/bin/cp/cp.1
@@ -32,7 +32,7 @@
.\" @(#)cp.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd September 4, 2012
+.Dd March 15, 2013
.Dt CP 1
.Os
.Sh NAME
@@ -251,6 +251,27 @@ signal, the current input and output file and the percentage complete
will be written to the standard output.
.Sh EXIT STATUS
.Ex -std
+.Sh EXAMPLES
+Make a copy of file
+.Pa foo
+named
+.Pa bar :
+.Pp
+.Dl $ cp foo bar
+.Pp
+Copy a group of files to the
+.Pa /tmp
+directory:
+.Pp
+.Dl $ cp *.txt /tmp
+.Pp
+Copy the directory
+.Pa junk
+and all of its contents (including any subdirectories) to the
+.Pa /tmp
+directory:
+.Pp
+.Dl $ cp -R junk /tmp
.Sh COMPATIBILITY
Historic versions of the
.Nm
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
index 637e0cc..01b66fc 100644
--- a/bin/dd/dd.c
+++ b/bin/dd/dd.c
@@ -98,6 +98,13 @@ main(int argc __unused, char *argv[])
dd_in();
dd_close();
+ /*
+ * Some devices such as cfi(4) may perform significant amounts
+ * of work when a write descriptor is closed. Close the out
+ * descriptor explicitly so that the summary handler (called
+ * from an atexit() hook) includes this work.
+ */
+ close(out.fd);
exit(0);
}
diff --git a/bin/ed/cbc.c b/bin/ed/cbc.c
index 08e48cd..31838f5 100644
--- a/bin/ed/cbc.c
+++ b/bin/ed/cbc.c
@@ -71,7 +71,6 @@ __FBSDID("$FreeBSD$");
#ifdef DES
static DES_cblock ivec; /* initialization vector */
static DES_cblock pvec; /* padding vector */
-#endif
static char bits[] = { /* used to extract bits from a char */
'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
@@ -79,13 +78,12 @@ static char bits[] = { /* used to extract bits from a char */
static int pflag; /* 1 to preserve parity bits */
-#ifdef DES
static DES_key_schedule schedule; /* expanded DES key */
-#endif
static unsigned char des_buf[8];/* shared buffer for get_des_char/put_des_char */
static int des_ct = 0; /* count for get_des_char/put_des_char */
static int des_n = 0; /* index for put_des_char/get_des_char */
+#endif
/* init_des_cipher: initialize DES */
void
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
index aa4fc18..7c72652 100644
--- a/bin/ls/ls.1
+++ b/bin/ls/ls.1
@@ -32,7 +32,7 @@
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
.\" $FreeBSD$
.\"
-.Dd November 8, 2012
+.Dd March 15, 2013
.Dt LS 1
.Os
.Sh NAME
@@ -718,6 +718,24 @@ for more information.
.El
.Sh EXIT STATUS
.Ex -std
+.Sh EXAMPLES
+List the contents of the current working directory in long format:
+.Pp
+.Dl $ ls -l
+.Pp
+In addition to listing the contents of the current working directory in
+long format, show inode numbers, file flags (see
+.Xr chflags 1 ) ,
+and suffix each filename with a symbol representing its file type:
+.Pp
+.Dl $ ls -lioF
+.Pp
+List the files in
+.Pa /var/log ,
+sorting the output such that the mostly recently modified entries are
+printed first:
+.Pp
+.Dl $ ls -lt /var/log
.Sh COMPATIBILITY
The group field is now automatically included in the long listing for
files in order to be compatible with the
diff --git a/bin/mkdir/mkdir.1 b/bin/mkdir/mkdir.1
index 0f8d812..d702348 100644
--- a/bin/mkdir/mkdir.1
+++ b/bin/mkdir/mkdir.1
@@ -32,7 +32,7 @@
.\" @(#)mkdir.1 8.2 (Berkeley) 1/25/94
.\" $FreeBSD$
.\"
-.Dd January 25, 1994
+.Dd March 15, 2013
.Dt MKDIR 1
.Os
.Sh NAME
@@ -87,6 +87,23 @@ Be verbose when creating directories, listing them as they are created.
The user must have write permission in the parent directory.
.Sh EXIT STATUS
.Ex -std
+.Sh EXAMPLES
+Create a directory named
+.Pa foobar :
+.Pp
+.Dl $ mkdir foobar
+.Pp
+Create a directory named
+.Pa foobar
+and set its file mode to 700:
+.Pp
+.Dl $ mkdir -m 700 foobar
+.Pp
+Create a directory named
+.Pa cow/horse/monkey ,
+creating any non-existent intermediate directories as necessary:
+.Pp
+.Dl $ mkdir -p cow/horse/monkey
.Sh COMPATIBILITY
The
.Fl v
diff --git a/bin/mv/mv.1 b/bin/mv/mv.1
index 5199f27..298dbf9 100644
--- a/bin/mv/mv.1
+++ b/bin/mv/mv.1
@@ -32,7 +32,7 @@
.\" @(#)mv.1 8.1 (Berkeley) 5/31/93
.\" $FreeBSD$
.\"
-.Dd August 28, 2012
+.Dd March 15, 2013
.Dt MV 1
.Os
.Sh NAME
@@ -155,6 +155,16 @@ rm -rf source_file
.Ed
.Sh EXIT STATUS
.Ex -std
+.Sh EXAMPLES
+Rename file
+.Pa foo
+to
+.Pa bar ,
+overwriting
+.Pa bar
+if it already exists:
+.Pp
+.Dl $ mv -f foo bar
.Sh COMPATIBILITY
The
.Fl h ,
diff --git a/bin/mv/mv.c b/bin/mv/mv.c
index 5147a2db..2710f89 100644
--- a/bin/mv/mv.c
+++ b/bin/mv/mv.c
@@ -337,7 +337,7 @@ err: if (unlink(to))
* on a file that we copied, i.e., that we didn't create.)
*/
errno = 0;
- if (fchflags(to_fd, (u_long)sbp->st_flags))
+ if (fchflags(to_fd, sbp->st_flags))
if (errno != EOPNOTSUPP || sbp->st_flags != 0)
warn("%s: set flags (was: 0%07o)", to, sbp->st_flags);
diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
index 7f69137..1a364f5 100644
--- a/bin/ps/ps.1
+++ b/bin/ps/ps.1
@@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd February 7, 2013
+.Dd March 15, 2013
.Dt PS 1
.Os
.Sh NAME
@@ -689,6 +689,10 @@ attempts to automatically determine the terminal width.
.It Pa /boot/kernel/kernel
default system namelist
.El
+.Sh EXAMPLES
+Display information on all system processes:
+.Pp
+.Dl $ ps -auxw
.Sh SEE ALSO
.Xr kill 1 ,
.Xr pgrep 1 ,
diff --git a/bin/rm/rm.1 b/bin/rm/rm.1
index ad81066..3588f38 100644
--- a/bin/rm/rm.1
+++ b/bin/rm/rm.1
@@ -32,7 +32,7 @@
.\" @(#)rm.1 8.5 (Berkeley) 12/5/94
.\" $FreeBSD$
.\"
-.Dd October 31, 2010
+.Dd March 15, 2013
.Dt RM 1
.Os
.Sh NAME
@@ -193,6 +193,19 @@ When
is specified with
.Fl f
the file will be overwritten and removed even if it has hard links.
+.Sh EXAMPLES
+Recursively remove all files contained within the
+.Pa foobar
+directory hierarchy:
+.Pp
+.Dl $ rm -rf foobar
+.Pp
+Either of these commands will remove the file
+.Pa -f :
+.Bd -literal -offset indent
+$ rm -- -f
+$ rm ./-f
+.Ed
.Sh COMPATIBILITY
The
.Nm
diff --git a/bin/rmdir/rmdir.1 b/bin/rmdir/rmdir.1
index 688d144..ededd43 100644
--- a/bin/rmdir/rmdir.1
+++ b/bin/rmdir/rmdir.1
@@ -32,7 +32,7 @@
.\" @(#)rmdir.1 8.1 (Berkeley) 5/31/93
.\" $FreeBSD$
.\"
-.Dd March 21, 2004
+.Dd March 15, 2013
.Dt RMDIR 1
.Os
.Sh NAME
@@ -86,6 +86,18 @@ successfully.
.It Li >0
An error occurred.
.El
+.Sh EXAMPLES
+Remove the directory
+.Pa foobar ,
+if it is empty:
+.Pp
+.Dl $ rmdir foobar
+.Pp
+Remove all directories up to and including
+.Pa cow ,
+stopping at the first non-empty directory (if any):
+.Pp
+.Dl $ rmdir -p cow/horse/monkey
.Sh SEE ALSO
.Xr rm 1
.Sh STANDARDS
diff --git a/bin/setfacl/setfacl.1 b/bin/setfacl/setfacl.1
index 3d7b517..4104315 100644
--- a/bin/setfacl/setfacl.1
+++ b/bin/setfacl/setfacl.1
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 2, 2012
+.Dd April 1, 2013
.Dt SETFACL 1
.Os
.Sh NAME
@@ -91,10 +91,16 @@ An error will be reported if any of
the specified files cannot have a default entry (i.e.\&
non-directories). This option is not applicable to NFSv4 ACLs.
.It Fl m Ar entries
-Modify the ACL entries on the specified files by adding new
-entries and modifying existing ACL entries with the ACL entries
-specified in
-.Ar entries .
+Modify the ACL on the specified file.
+New entries will be added, and existing entries will be modified
+according to the
+.Ar entries
+argument.
+For NFSv4 ACLs, it is recommended to use the
+.Fl a
+and
+.Fl x
+options instead.
.It Fl M Ar file
Modify the ACL entries on the specified files by adding new
ACL entries and modifying existing ACL entries with the ACL
@@ -319,9 +325,9 @@ write_data
execute
.It p
append_data
-.It d
-delete_child
.It D
+delete_child
+.It d
delete
.It a
read_attributes
@@ -395,6 +401,10 @@ NFSv4 ACL entries are evaluated in their visible order.
.Pp
Multiple ACL entries specified on the command line are
separated by commas.
+.Pp
+Note that the file owner is always granted the read_acl, write_acl,
+read_attributes, and write_attributes permissions, even if the ACL
+would deny it.
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 66ae40e..d3708b3 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -174,6 +174,7 @@ evalstring(char *s, int flags)
any = 1;
}
popstackmark(&smark);
+ setstackmark(&smark);
}
popfile();
popstackmark(&smark);
@@ -278,6 +279,8 @@ evaltree(union node *n, int flags)
break;
case NNOT:
evaltree(n->nnot.com, EV_TESTED);
+ if (evalskip)
+ goto out;
exitstatus = !exitstatus;
break;
@@ -296,10 +299,11 @@ evaltree(union node *n, int flags)
}
n = next;
popstackmark(&smark);
+ setstackmark(&smark);
} while (n != NULL);
out:
popstackmark(&smark);
- if (pendingsigs)
+ if (pendingsig)
dotrap();
if (eflag && exitstatus != 0 && do_etest)
exitshell(exitstatus);
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index 7a6dbae..6c3a6dd 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -165,7 +165,7 @@ tryexec(char *cmd, char **argv, char **envp)
}
}
*argv = cmd;
- *--argv = _PATH_BSHELL;
+ *--argv = __DECONST(char *, _PATH_BSHELL);
execve(_PATH_BSHELL, argv, envp);
}
errno = e;
@@ -188,7 +188,7 @@ padvance(const char **path, const char *name)
{
const char *p, *start;
char *q;
- int len;
+ size_t len;
if (*path == NULL)
return NULL;
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 107f798..414bfa7 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -460,7 +460,7 @@ expbackq(union node *cmd, int quoted, int flag)
int startloc = dest - stackblock();
char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
- int nnl;
+ size_t nnl;
INTOFF;
saveifs = ifsfirst;
@@ -1163,9 +1163,9 @@ nometa:
static void
expmeta(char *enddir, char *name)
{
- char *p;
- char *q;
- char *start;
+ const char *p;
+ const char *q;
+ const char *start;
char *endname;
int metaflag;
struct stat statb;
@@ -1229,7 +1229,7 @@ expmeta(char *enddir, char *name)
addfname(expdir);
return;
}
- endname = p;
+ endname = name + (p - name);
if (start != name) {
p = name;
while (p < start) {
@@ -1412,7 +1412,8 @@ match_charclass(const char *p, wchar_t chr, const char **end)
*end = NULL;
p++;
nameend = strstr(p, ":]");
- if (nameend == NULL || nameend - p >= sizeof(name) || nameend == p)
+ if (nameend == NULL || (size_t)(nameend - p) >= sizeof(name) ||
+ nameend == p)
return 0;
memcpy(name, p, nameend - p);
name[nameend - p] = '\0';
diff --git a/bin/sh/input.c b/bin/sh/input.c
index 84580ad..62e82a0 100644
--- a/bin/sh/input.c
+++ b/bin/sh/input.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
struct strpush {
struct strpush *prev; /* preceding string on stack */
- char *prevstring;
+ const char *prevstring;
int prevnleft;
int prevlleft;
struct alias *ap; /* if push was associated with an alias */
@@ -83,7 +83,7 @@ struct parsefile {
int fd; /* file descriptor (or -1 if string) */
int nleft; /* number of chars left in this line */
int lleft; /* number of lines left in this buffer */
- char *nextc; /* next char in buffer */
+ const char *nextc; /* next char in buffer */
char *buf; /* input buffer */
struct strpush *strpush; /* for pushing strings at this level */
struct strpush basestrpush; /* so pushing one is fast */
@@ -93,7 +93,7 @@ struct parsefile {
int plinno = 1; /* input line number */
int parsenleft; /* copy of parsefile->nleft */
MKINIT int parselleft; /* copy of parsefile->lleft */
-char *parsenextc; /* copy of parsefile->nextc */
+const char *parsenextc; /* copy of parsefile->nextc */
static char basebuf[BUFSIZ + 1];/* buffer for top level input file */
static struct parsefile basepf = { /* top level input file */
.nextc = basebuf,
@@ -185,7 +185,7 @@ retry:
nr = el_len;
if (nr > BUFSIZ)
nr = BUFSIZ;
- memcpy(parsenextc, rl_cp, nr);
+ memcpy(parsefile->buf, rl_cp, nr);
if (nr != el_len) {
el_len -= nr;
rl_cp += nr;
@@ -194,7 +194,7 @@ retry:
}
} else
#endif
- nr = read(parsefile->fd, parsenextc, BUFSIZ);
+ nr = read(parsefile->fd, parsefile->buf, BUFSIZ);
if (nr <= 0) {
if (nr < 0) {
@@ -252,7 +252,7 @@ again:
}
}
- q = p = parsenextc;
+ q = p = parsefile->buf + (parsenextc - parsefile->buf);
/* delete nul characters */
something = 0;
@@ -439,7 +439,7 @@ setinputfd(int fd, int push)
*/
void
-setinputstring(char *string, int push)
+setinputstring(const char *string, int push)
{
INTOFF;
if (push)
diff --git a/bin/sh/input.h b/bin/sh/input.h
index c8802f9..70f675e 100644
--- a/bin/sh/input.h
+++ b/bin/sh/input.h
@@ -42,7 +42,7 @@
*/
extern int plinno;
extern int parsenleft; /* number of characters left in input buffer */
-extern char *parsenextc; /* next character in input buffer */
+extern const char *parsenextc; /* next character in input buffer */
struct alias;
struct parsefile;
@@ -55,7 +55,7 @@ void pungetc(void);
void pushstring(char *, int, struct alias *);
void setinputfile(const char *, int);
void setinputfd(int, int);
-void setinputstring(char *, int);
+void setinputstring(const char *, int);
void popfile(void);
struct parsefile *getcurrentfile(void);
void popfilesupto(struct parsefile *);
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index c86394f..c978e3d 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -458,14 +458,15 @@ freejob(struct job *jp)
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;
}
@@ -521,7 +522,7 @@ waitcmd(int argc, char **argv)
} while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1);
in_waitcmd--;
- return 0;
+ return pendingsig + 128;
}
@@ -667,7 +668,8 @@ makejob(union node *node __unused, int nprocs)
jobtab = jp;
}
jp = jobtab + njobs;
- for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
+ for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0)
+ ;
INTON;
break;
}
@@ -1004,7 +1006,7 @@ waitforjob(struct job *jp, int *origstatus)
static void
-dummy_handler(int sig)
+dummy_handler(int sig __unused)
{
}
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 66e1335..84a1ef2 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -80,7 +80,7 @@ struct jmploc main_handler;
int localeisutf8, initial_localeisutf8;
static void cmdloop(int);
-static void read_profile(char *);
+static void read_profile(const char *);
static char *find_dot_file(char *);
/*
@@ -196,7 +196,7 @@ cmdloop(int top)
TRACE(("cmdloop(%d) called\n", top));
setstackmark(&smark);
for (;;) {
- if (pendingsigs)
+ if (pendingsig)
dotrap();
inter = 0;
if (iflag && top) {
@@ -239,7 +239,7 @@ cmdloop(int top)
*/
static void
-read_profile(char *name)
+read_profile(const char *name)
{
int fd;
const char *expandedname;
diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c
index bc567d0..f33a15c 100644
--- a/bin/sh/memalloc.c
+++ b/bin/sh/memalloc.c
@@ -233,7 +233,8 @@ growstackblock(int min)
if (min < stacknleft)
min = stacknleft;
- if (min >= INT_MAX / 2 - ALIGN(sizeof(struct stack_block)))
+ if ((unsigned int)min >=
+ INT_MAX / 2 - ALIGN(sizeof(struct stack_block)))
error("Out of space");
min += stacknleft;
min += ALIGN(sizeof(struct stack_block));
@@ -327,7 +328,7 @@ makestrspace(int min, char *p)
char *
-stputbin(const char *data, int len, char *p)
+stputbin(const char *data, size_t len, char *p)
{
CHECKSTRSPACE(len, p);
memcpy(p, data, len);
diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h
index 425004e..95a6594 100644
--- a/bin/sh/memalloc.h
+++ b/bin/sh/memalloc.h
@@ -57,7 +57,7 @@ void setstackmark(struct stackmark *);
void popstackmark(struct stackmark *);
char *growstackstr(void);
char *makestrspace(int, char *);
-char *stputbin(const char *data, int len, char *p);
+char *stputbin(const char *data, size_t len, char *p);
char *stputs(const char *data, char *p);
@@ -67,7 +67,7 @@ char *stputs(const char *data, char *p);
#define grabstackblock(n) stalloc(n)
#define STARTSTACKSTR(p) p = stackblock()
#define STPUTC(c, p) do { if (p == sstrend) p = growstackstr(); *p++ = (c); } while(0)
-#define CHECKSTRSPACE(n, p) { if (sstrend - p < n) p = makestrspace(n, p); }
+#define CHECKSTRSPACE(n, p) { if ((size_t)(sstrend - p) < n) p = makestrspace(n, p); }
#define USTPUTC(c, p) (*p++ = (c))
/*
* STACKSTRNUL's use is where we want to be able to turn a stack
diff --git a/bin/sh/nodes.c.pat b/bin/sh/nodes.c.pat
index b325d76..e99e3ab 100644
--- a/bin/sh/nodes.c.pat
+++ b/bin/sh/nodes.c.pat
@@ -58,7 +58,7 @@ static void calcsize(union node *);
static void sizenodelist(struct nodelist *);
static union node *copynode(union node *);
static struct nodelist *copynodelist(struct nodelist *);
-static char *nodesavestr(char *);
+static char *nodesavestr(const char *);
struct funcdef {
@@ -147,9 +147,9 @@ copynodelist(struct nodelist *lp)
static char *
-nodesavestr(char *s)
+nodesavestr(const char *s)
{
- char *p = s;
+ const char *p = s;
char *q = funcstring;
char *rtn = funcstring;
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index 665b53f..073c2b6 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -119,7 +119,7 @@ static void parseheredoc(void);
static int peektoken(void);
static int readtoken(void);
static int xxreadtoken(void);
-static int readtoken1(int, char const *, char *, int);
+static int readtoken1(int, const char *, const char *, int);
static int noexpand(char *);
static void synexpect(int) __dead2;
static void synerror(const char *) __dead2;
@@ -983,7 +983,7 @@ parsebackq(char *out, struct nodelist **pbqlist,
char *volatile str;
struct jmploc jmploc;
struct jmploc *const savehandler = handler;
- int savelen;
+ size_t savelen;
int saveprompt;
const int bq_startlinno = plinno;
char *volatile ostr = NULL;
@@ -1300,7 +1300,8 @@ readcstyleesc(char *out)
#define PARSEARITH() {goto parsearith; parsearith_return:;}
static int
-readtoken1(int firstc, char const *initialsyntax, char *eofmark, int striptabs)
+readtoken1(int firstc, char const *initialsyntax, const char *eofmark,
+ int striptabs)
{
int c = firstc;
char *out;
@@ -1521,7 +1522,7 @@ checkend: {
}
if (c == *eofmark) {
if (pfgets(line, sizeof line) != NULL) {
- char *p, *q;
+ const char *p, *q;
p = line;
for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
@@ -2038,7 +2039,7 @@ getprompt(void *unused __unused)
const char *
-expandstr(char *ps)
+expandstr(const char *ps)
{
union node n;
struct jmploc jmploc;
diff --git a/bin/sh/parser.h b/bin/sh/parser.h
index f80d917..b803f76 100644
--- a/bin/sh/parser.h
+++ b/bin/sh/parser.h
@@ -82,4 +82,4 @@ void fixredir(union node *, const char *, int);
int goodname(const char *);
int isassignment(const char *);
char *getprompt(void *);
-const char *expandstr(char *);
+const char *expandstr(const char *);
diff --git a/bin/sh/redir.c b/bin/sh/redir.c
index c11cb71..fda094d2 100644
--- a/bin/sh/redir.c
+++ b/bin/sh/redir.c
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
#define EMPTY -2 /* marks an unused slot in redirtab */
#define CLOSED -1 /* fd was not open before redir */
-#define PIPESIZE 4096 /* amount of buffering in a pipe */
MKINIT
@@ -253,7 +252,9 @@ openhere(union node *redir)
{
char *p;
int pip[2];
- int len = 0;
+ size_t len = 0;
+ int flags;
+ ssize_t written = 0;
if (pipe(pip) < 0)
error("Pipe call failed: %s", strerror(errno));
@@ -263,9 +264,16 @@ openhere(union node *redir)
else
p = redir->nhere.doc->narg.text;
len = strlen(p);
- if (len <= PIPESIZE) {
- xwrite(pip[1], p, len);
+ if (len == 0)
goto out;
+ flags = fcntl(pip[1], F_GETFL, 0);
+ if (flags != -1 && fcntl(pip[1], F_SETFL, flags | O_NONBLOCK) != -1) {
+ written = write(pip[1], p, len);
+ if (written < 0)
+ written = 0;
+ if ((size_t)written == len)
+ goto out;
+ fcntl(pip[1], F_SETFL, flags);
}
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
@@ -275,7 +283,7 @@ openhere(union node *redir)
signal(SIGHUP, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGPIPE, SIG_DFL);
- xwrite(pip[1], p, len);
+ xwrite(pip[1], p + written, len - written);
_exit(0);
}
out:
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 09d94f3..01cb775 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd January 22, 2013
+.Dd March 24, 2013
.Dt SH 1
.Os
.Sh NAME
@@ -1061,6 +1061,9 @@ A subshell environment may be implemented as a child process or differently.
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
@@ -1618,6 +1621,16 @@ and
.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.
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index 521c511..3138029 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -73,7 +73,7 @@ __FBSDID("$FreeBSD$");
MKINIT char sigmode[NSIG]; /* current value of signal */
-int pendingsigs; /* indicates some signal received */
+volatile sig_atomic_t pendingsig; /* indicates some signal received */
int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[NSIG];
@@ -150,7 +150,7 @@ printsignals(void)
* The trap builtin.
*/
int
-trapcmd(int argc, char **argv)
+trapcmd(int argc __unused, char **argv)
{
char *action;
int signo;
@@ -388,22 +388,25 @@ onsig(int signo)
return;
}
- if (signo != SIGCHLD || !ignore_sigchld)
- gotsig[signo] = 1;
- pendingsigs++;
-
/* If we are currently in a wait builtin, prepare to break it */
- if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
- breakwaitcmd = 1;
- /*
- * If a trap is set, not ignored and not the null command, we need
- * to make sure traps are executed even when a child blocks signals.
- */
- if (Tflag &&
- trap[signo] != NULL &&
- ! (trap[signo][0] == '\0') &&
- ! (trap[signo][0] == ':' && trap[signo][1] == '\0'))
+ if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0) {
breakwaitcmd = 1;
+ pendingsig = signo;
+ }
+
+ if (trap[signo] != NULL && trap[signo][0] != '\0' &&
+ (signo != SIGCHLD || !ignore_sigchld)) {
+ gotsig[signo] = 1;
+ pendingsig = signo;
+
+ /*
+ * If a trap is set, not ignored and not the null command, we
+ * need to make sure traps are executed even when a child
+ * blocks signals.
+ */
+ if (Tflag && !(trap[signo][0] == ':' && trap[signo][1] == '\0'))
+ breakwaitcmd = 1;
+ }
#ifndef NO_HISTORY
if (signo == SIGWINCH)
@@ -424,7 +427,7 @@ dotrap(void)
in_dotrap++;
for (;;) {
- pendingsigs = 0;
+ pendingsig = 0;
for (i = 1; i < NSIG; i++) {
if (gotsig[i]) {
gotsig[i] = 0;
@@ -452,7 +455,6 @@ dotrap(void)
last_trapsig = i;
savestatus = exitstatus;
evalstring(trap[i], 0);
- exitstatus = savestatus;
/*
* If such a command was not
@@ -461,9 +463,11 @@ dotrap(void)
* trap action to have an effect
* outside of it.
*/
- if (prev_evalskip != 0) {
+ if (evalskip == 0 ||
+ prev_evalskip != 0) {
evalskip = prev_evalskip;
skipcount = prev_skipcount;
+ exitstatus = savestatus;
}
if (i == SIGCHLD)
diff --git a/bin/sh/trap.h b/bin/sh/trap.h
index 61a17ec..0a05d8d 100644
--- a/bin/sh/trap.h
+++ b/bin/sh/trap.h
@@ -33,7 +33,7 @@
* $FreeBSD$
*/
-extern int pendingsigs;
+extern volatile sig_atomic_t pendingsig;
extern int in_dotrap;
extern volatile sig_atomic_t gotwinch;
diff --git a/bin/test/test.1 b/bin/test/test.1
index 885374e..76a4a9c 100644
--- a/bin/test/test.1
+++ b/bin/test/test.1
@@ -169,15 +169,65 @@ True if
.Ar file
exists and is a socket.
.It Ar file1 Fl nt Ar file2
-True if
+True if both
+.Ar file1
+and
+.Ar file2
+exist and
+.Ar file1
+is newer than
+.Ar file2 .
+.It Ar file1 Fl nt Ns Ar X Ns Ar Y Ar file2
+True if both
+.Ar file1
+and
+.Ar file2
+exist and
.Ar file1
-exists and is newer than
+has a more recent last access time
+.Pq Ar X Ns = Ns Cm a ,
+inode creation time
+.Pq Ar X Ns = Ns Cm b ,
+change time
+.Pq Ar X Ns = Ns Cm c ,
+or modification time
+.Pq Ar X Ns = Ns Cm m
+than the last access time
+.Pq Ar Y Ns = Ns Cm a ,
+inode creation time
+.Pq Ar Y Ns = Ns Cm b ,
+change time
+.Pq Ar Y Ns = Ns Cm c ,
+or modification time
+.Pq Ar Y Ns = Ns Cm m
+of
.Ar file2 .
+Note that
+.Ic -ntmm
+is equivalent to
+.Ic -nt .
.It Ar file1 Fl ot Ar file2
-True if
+True if both
+.Ar file1
+and
+.Ar file2
+exist and
.Ar file1
-exists and is older than
+is older than
.Ar file2 .
+Note that
+.Ar file1
+.Ic -ot
+.Ar file2
+is equivalent to
+.Ar file2
+.Ic -nt
+.Ar file1
+.It Ar file1 Fl ot Ns Ar X Ns Ar Y Ar file2
+Equivalent to
+.Ar file2
+.Ic -nt Ns Ar Y Ns Ar X
+.Ar file1 .
.It Ar file1 Fl ef Ar file2
True if
.Ar file1
diff --git a/bin/test/test.c b/bin/test/test.c
index 96aa9f5..eaa2f40 100644
--- a/bin/test/test.c
+++ b/bin/test/test.c
@@ -63,7 +63,7 @@ error(const char *msg, ...)
"-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
- "-nt"|"-ot"|"-ef";
+ "-nt"|"-nt[abcm][abcm]"|"-ot"|"-ot[abcm][abcm])"|"-ef";
operand ::= <any legal UNIX file name>
*/
@@ -85,8 +85,38 @@ enum token {
FILSUID,
FILSGID,
FILSTCK,
- FILNT,
- FILOT,
+ FILNTAA,
+ FILNTAB,
+ FILNTAC,
+ FILNTAM,
+ FILNTBA,
+ FILNTBB,
+ FILNTBC,
+ FILNTBM,
+ FILNTCA,
+ FILNTCB,
+ FILNTCC,
+ FILNTCM,
+ FILNTMA,
+ FILNTMB,
+ FILNTMC,
+ FILNTMM,
+ FILOTAA,
+ FILOTAB,
+ FILOTAC,
+ FILOTAM,
+ FILOTBA,
+ FILOTBB,
+ FILOTBC,
+ FILOTBM,
+ FILOTCA,
+ FILOTCB,
+ FILOTCC,
+ FILOTCM,
+ FILOTMA,
+ FILOTMB,
+ FILOTMC,
+ FILOTMM,
FILEQ,
FILUID,
FILGID,
@@ -118,9 +148,16 @@ enum token_types {
PAREN
};
+enum time_types {
+ ATIME,
+ BTIME,
+ CTIME,
+ MTIME
+};
+
static struct t_op {
- char op_text[4];
- short op_num, op_type;
+ char op_text[6];
+ char op_num, op_type;
} const ops [] = {
{"-r", FILRD, UNOP},
{"-w", FILWR, UNOP},
@@ -154,8 +191,40 @@ static struct t_op {
{"-gt", INTGT, BINOP},
{"-le", INTLE, BINOP},
{"-lt", INTLT, BINOP},
- {"-nt", FILNT, BINOP},
- {"-ot", FILOT, BINOP},
+ {"-nt", FILNTMM, BINOP},
+ {"-ntaa", FILNTAA, BINOP},
+ {"-ntab", FILNTAB, BINOP},
+ {"-ntac", FILNTAC, BINOP},
+ {"-ntam", FILNTAM, BINOP},
+ {"-ntba", FILNTBA, BINOP},
+ {"-ntbb", FILNTBB, BINOP},
+ {"-ntbc", FILNTBC, BINOP},
+ {"-ntbm", FILNTBM, BINOP},
+ {"-ntca", FILNTCA, BINOP},
+ {"-ntcb", FILNTCB, BINOP},
+ {"-ntcc", FILNTCC, BINOP},
+ {"-ntcm", FILNTCM, BINOP},
+ {"-ntma", FILNTMA, BINOP},
+ {"-ntmb", FILNTMB, BINOP},
+ {"-ntmc", FILNTMC, BINOP},
+ {"-ntmm", FILNTMM, BINOP},
+ {"-ot", FILOTMM, BINOP},
+ {"-otaa", FILOTAA, BINOP},
+ {"-otab", FILOTBB, BINOP},
+ {"-otac", FILOTAC, BINOP},
+ {"-otam", FILOTAM, BINOP},
+ {"-otba", FILOTBA, BINOP},
+ {"-otbb", FILOTBB, BINOP},
+ {"-otbc", FILOTBC, BINOP},
+ {"-otbm", FILOTBM, BINOP},
+ {"-otca", FILOTCA, BINOP},
+ {"-otcb", FILOTCB, BINOP},
+ {"-otcc", FILOTCC, BINOP},
+ {"-otcm", FILOTCM, BINOP},
+ {"-otma", FILOTMA, BINOP},
+ {"-otmb", FILOTMB, BINOP},
+ {"-otmc", FILOTMC, BINOP},
+ {"-otmm", FILOTMM, BINOP},
{"-ef", FILEQ, BINOP},
{"!", UNOT, BUNOP},
{"-a", BAND, BBINOP},
@@ -180,10 +249,10 @@ static int intcmp(const char *, const char *);
static int isunopoperand(void);
static int islparenoperand(void);
static int isrparenoperand(void);
-static int newerf(const char *, const char *);
+static int newerf(const char *, const char *, enum time_types,
+ enum time_types);
static int nexpr(enum token);
static int oexpr(enum token);
-static int olderf(const char *, const char *);
static int primary(enum token);
static void syntax(const char *, const char *);
static enum token t_lex(char *);
@@ -353,10 +422,70 @@ binop(void)
return intcmp(opnd1, opnd2) <= 0;
case INTLT:
return intcmp(opnd1, opnd2) < 0;
- case FILNT:
- return newerf (opnd1, opnd2);
- case FILOT:
- return olderf (opnd1, opnd2);
+ case FILNTAA:
+ return newerf(opnd1, opnd2, ATIME, ATIME);
+ case FILNTAB:
+ return newerf(opnd1, opnd2, ATIME, BTIME);
+ case FILNTAC:
+ return newerf(opnd1, opnd2, ATIME, CTIME);
+ case FILNTAM:
+ return newerf(opnd1, opnd2, ATIME, MTIME);
+ case FILNTBA:
+ return newerf(opnd1, opnd2, BTIME, ATIME);
+ case FILNTBB:
+ return newerf(opnd1, opnd2, BTIME, BTIME);
+ case FILNTBC:
+ return newerf(opnd1, opnd2, BTIME, CTIME);
+ case FILNTBM:
+ return newerf(opnd1, opnd2, BTIME, MTIME);
+ case FILNTCA:
+ return newerf(opnd1, opnd2, CTIME, ATIME);
+ case FILNTCB:
+ return newerf(opnd1, opnd2, CTIME, BTIME);
+ case FILNTCC:
+ return newerf(opnd1, opnd2, CTIME, CTIME);
+ case FILNTCM:
+ return newerf(opnd1, opnd2, CTIME, MTIME);
+ case FILNTMA:
+ return newerf(opnd1, opnd2, MTIME, ATIME);
+ case FILNTMB:
+ return newerf(opnd1, opnd2, MTIME, BTIME);
+ case FILNTMC:
+ return newerf(opnd1, opnd2, MTIME, CTIME);
+ case FILNTMM:
+ return newerf(opnd1, opnd2, MTIME, MTIME);
+ case FILOTAA:
+ return newerf(opnd2, opnd1, ATIME, ATIME);
+ case FILOTAB:
+ return newerf(opnd2, opnd1, BTIME, ATIME);
+ case FILOTAC:
+ return newerf(opnd2, opnd1, CTIME, ATIME);
+ case FILOTAM:
+ return newerf(opnd2, opnd1, MTIME, ATIME);
+ case FILOTBA:
+ return newerf(opnd2, opnd1, ATIME, BTIME);
+ case FILOTBB:
+ return newerf(opnd2, opnd1, BTIME, BTIME);
+ case FILOTBC:
+ return newerf(opnd2, opnd1, CTIME, BTIME);
+ case FILOTBM:
+ return newerf(opnd2, opnd1, MTIME, BTIME);
+ case FILOTCA:
+ return newerf(opnd2, opnd1, ATIME, CTIME);
+ case FILOTCB:
+ return newerf(opnd2, opnd1, BTIME, CTIME);
+ case FILOTCC:
+ return newerf(opnd2, opnd1, CTIME, CTIME);
+ case FILOTCM:
+ return newerf(opnd2, opnd1, MTIME, CTIME);
+ case FILOTMA:
+ return newerf(opnd2, opnd1, ATIME, MTIME);
+ case FILOTMB:
+ return newerf(opnd2, opnd1, BTIME, MTIME);
+ case FILOTMC:
+ return newerf(opnd2, opnd1, CTIME, MTIME);
+ case FILOTMM:
+ return newerf(opnd2, opnd1, MTIME, MTIME);
case FILEQ:
return equalf (opnd1, opnd2);
default:
@@ -570,25 +699,34 @@ intcmp (const char *s1, const char *s2)
}
static int
-newerf (const char *f1, const char *f2)
+newerf (const char *f1, const char *f2, enum time_types t1, enum time_types t2)
{
struct stat b1, b2;
+ struct timespec *ts1, *ts2;
if (stat(f1, &b1) != 0 || stat(f2, &b2) != 0)
return 0;
- if (b1.st_mtim.tv_sec > b2.st_mtim.tv_sec)
+ switch (t1) {
+ case ATIME: ts1 = &b1.st_atim; break;
+ case BTIME: ts1 = &b1.st_birthtim; break;
+ case CTIME: ts1 = &b1.st_ctim; break;
+ default: ts1 = &b1.st_mtim; break;
+ }
+
+ switch (t2) {
+ case ATIME: ts2 = &b2.st_atim; break;
+ case BTIME: ts2 = &b2.st_birthtim; break;
+ case CTIME: ts2 = &b2.st_ctim; break;
+ default: ts2 = &b2.st_mtim; break;
+ }
+
+ if (ts1->tv_sec > ts2->tv_sec)
return 1;
- if (b1.st_mtim.tv_sec < b2.st_mtim.tv_sec)
+ if (ts1->tv_sec < ts2->tv_sec)
return 0;
- return (b1.st_mtim.tv_nsec > b2.st_mtim.tv_nsec);
-}
-
-static int
-olderf (const char *f1, const char *f2)
-{
- return (newerf(f2, f1));
+ return (ts1->tv_nsec > ts2->tv_nsec);
}
static int
OpenPOWER on IntegriCloud