Create a small library function, check_utility_compat(3), to determine
whether a named utility should behave in FreeBSD 4.x-compatible mode or in a standard mode (default standard). The configuration is done malloc(3)-style, with either an environment variable or a symlink. Update expr(1) to use this new interface.
This commit is contained in:
parent
4e08ccb2ff
commit
c9885518de
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=106065
@ -121,9 +121,23 @@ otherwise 0.
|
|||||||
.Pp
|
.Pp
|
||||||
Parentheses are used for grouping in the usual manner.
|
Parentheses are used for grouping in the usual manner.
|
||||||
.Pp
|
.Pp
|
||||||
Unless the
|
The
|
||||||
.Ev EXPR_COMPAT
|
.Nm
|
||||||
variable is defined in the process environment, this version of
|
utility makes no lexical distinction between arguments which may be
|
||||||
|
operators and arguments which may be operands.
|
||||||
|
An operand which is lexically identical to an operator will be considered a
|
||||||
|
syntax error.
|
||||||
|
See the examples below for a work-around.
|
||||||
|
.Pp
|
||||||
|
The syntax of the
|
||||||
|
.Nm
|
||||||
|
command in general is historic and inconvenient.
|
||||||
|
New applications are advised to use shell arithmetic rather than
|
||||||
|
.Nm .
|
||||||
|
.Ss Compatibility with previous implementations
|
||||||
|
Unless
|
||||||
|
.Fx 4.x
|
||||||
|
compatibility is enabled, this version of
|
||||||
.Nm
|
.Nm
|
||||||
adheres to the
|
adheres to the
|
||||||
\*[Px]
|
\*[Px]
|
||||||
@ -140,43 +154,31 @@ will not permit this syntax.
|
|||||||
See the examples below for portable ways to guarantee the correct
|
See the examples below for portable ways to guarantee the correct
|
||||||
interpretation.
|
interpretation.
|
||||||
The
|
The
|
||||||
.Ev EXPR_COMPAT
|
.Xr check_utility_compat 3
|
||||||
variable is intended for use as a transition and debugging aid, when
|
function (with a
|
||||||
|
.Fa utility
|
||||||
|
argument of
|
||||||
|
.Dq Li expr )
|
||||||
|
is used to determine whether compatibility mode should be enabled.
|
||||||
|
This feature is intended for use as a transition and debugging aid, when
|
||||||
.Nm
|
.Nm
|
||||||
is used in complex scripts which cannot easily be recast to avoid the
|
is used in complex scripts which cannot easily be recast to avoid the
|
||||||
non-portable usage.
|
non-portable usage.
|
||||||
Defining
|
Enabling compatibility mode
|
||||||
.Ev EXPR_COMPAT
|
|
||||||
also implicitly enables the
|
also implicitly enables the
|
||||||
.Fl e
|
.Fl e
|
||||||
option, since this matches the historic behavior of
|
option, since this matches the historic behavior of
|
||||||
.Nm
|
.Nm
|
||||||
in
|
in
|
||||||
.Fx .
|
.Fx .
|
||||||
|
For historical reasons, defining the environment variable
|
||||||
|
.Ev EXPR_COMPAT
|
||||||
|
also enables compatibility mode.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility makes no lexical distinction between arguments which may be
|
|
||||||
operators and arguments which may be operands.
|
|
||||||
An operand which is lexically identical to an operator will be considered a
|
|
||||||
syntax error.
|
|
||||||
See the examples below for a work-around.
|
|
||||||
.Pp
|
|
||||||
The syntax of the
|
|
||||||
.Nm
|
|
||||||
command in general is historic and inconvenient.
|
|
||||||
New applications are advised to use shell arithmetic rather than
|
|
||||||
.Nm .
|
|
||||||
.Sh ENVIRONMENT
|
.Sh ENVIRONMENT
|
||||||
.Bl -tag -width ".Ev EXPR_COMPAT"
|
.Bl -tag -width ".Ev EXPR_COMPAT"
|
||||||
.It Ev EXPR_COMPAT
|
.It Ev EXPR_COMPAT
|
||||||
If set,
|
If set, enables compatibility mode.
|
||||||
.Nm
|
|
||||||
will emulate historic
|
|
||||||
.Nm
|
|
||||||
implementations which did not obey the Utility Syntax Guidelines.
|
|
||||||
Implies
|
|
||||||
.Fl e .
|
|
||||||
.El
|
.El
|
||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
.Bl -bullet
|
.Bl -bullet
|
||||||
@ -248,15 +250,14 @@ the expression is invalid.
|
|||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr sh 1 ,
|
.Xr sh 1 ,
|
||||||
.Xr test 1
|
.Xr test 1 ,
|
||||||
|
.Xr check_utility_compat 3
|
||||||
.Sh STANDARDS
|
.Sh STANDARDS
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
utility conforms to
|
utility conforms to
|
||||||
.St -p1003.1-2001 ,
|
.St -p1003.1-2001 ,
|
||||||
provided that the
|
provided that compatibility mode is not enabled.
|
||||||
.Ev EXPR_COMPAT
|
|
||||||
environment variable is not defined.
|
|
||||||
The
|
The
|
||||||
.Fl e
|
.Fl e
|
||||||
flag is an extension.
|
flag is an extension.
|
||||||
|
@ -278,7 +278,8 @@ main(int argc, char *argv[])
|
|||||||
int c;
|
int c;
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
if (getenv("EXPR_COMPAT") != NULL) {
|
if (getenv("EXPR_COMPAT") != NULL
|
||||||
|
|| check_utility_compat("expr")) {
|
||||||
av = argv + 1;
|
av = argv + 1;
|
||||||
eflag = 1;
|
eflag = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -437,6 +437,7 @@ struct timeval; /* select(2) */
|
|||||||
int acct(const char *);
|
int acct(const char *);
|
||||||
int async_daemon(void);
|
int async_daemon(void);
|
||||||
int brk(const void *);
|
int brk(const void *);
|
||||||
|
int check_utility_compat(const char *);
|
||||||
int chroot(const char *);
|
int chroot(const char *);
|
||||||
const char *
|
const char *
|
||||||
crypt_get_format(void);
|
crypt_get_format(void);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/gen ${.CURDIR}/../libc/gen
|
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/gen ${.CURDIR}/../libc/gen
|
||||||
|
|
||||||
SRCS+= __xuname.c _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \
|
SRCS+= __xuname.c _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \
|
||||||
alarm.c arc4random.c assert.c basename.c \
|
alarm.c arc4random.c assert.c basename.c check_utility_compat.c \
|
||||||
clock.c closedir.c confstr.c \
|
clock.c closedir.c confstr.c \
|
||||||
crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \
|
crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \
|
||||||
dlfcn.c dlfunc.c drand48.c erand48.c err.c errlst.c errno.c \
|
dlfcn.c dlfunc.c drand48.c erand48.c err.c errlst.c errno.c \
|
||||||
@ -38,7 +38,7 @@ SRCS+= __xuname.c _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \
|
|||||||
|
|
||||||
.if ${LIB} == "c"
|
.if ${LIB} == "c"
|
||||||
MAN+= alarm.3 arc4random.3 \
|
MAN+= alarm.3 arc4random.3 \
|
||||||
basename.3 clock.3 \
|
basename.3 check_utility_compat.3 clock.3 \
|
||||||
confstr.3 ctermid.3 daemon.3 \
|
confstr.3 ctermid.3 daemon.3 \
|
||||||
devname.3 directory.3 dirname.3 dladdr.3 dllockinit.3 dlopen.3 \
|
devname.3 directory.3 dirname.3 dladdr.3 dllockinit.3 dlopen.3 \
|
||||||
err.3 exec.3 fmtcheck.3 fmtmsg.3 fnmatch.3 frexp.3 ftok.3 fts.3 \
|
err.3 exec.3 fmtcheck.3 fmtmsg.3 fnmatch.3 frexp.3 ftok.3 fts.3 \
|
||||||
|
89
lib/libc/gen/check_utility_compat.3
Normal file
89
lib/libc/gen/check_utility_compat.3
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
.\"
|
||||||
|
.\" Copyright 2002 Massachusetts Institute of Technology
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this software and
|
||||||
|
.\" its documentation for any purpose and without fee is hereby
|
||||||
|
.\" granted, provided that both the above copyright notice and this
|
||||||
|
.\" permission notice appear in all copies, that both the above
|
||||||
|
.\" copyright notice and this permission notice appear in all
|
||||||
|
.\" supporting documentation, and that the name of M.I.T. not be used
|
||||||
|
.\" in advertising or publicity pertaining to distribution of the
|
||||||
|
.\" software without specific, written prior permission. M.I.T. makes
|
||||||
|
.\" no representations about the suitability of this software for any
|
||||||
|
.\" purpose. It is provided "as is" without express or implied
|
||||||
|
.\" warranty.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||||
|
.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||||
|
.\" SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.\"
|
||||||
|
.Dd October 27, 2002
|
||||||
|
.Dt CHECK_UTILITY_COMPAT 3
|
||||||
|
.Os
|
||||||
|
.Sh MAME
|
||||||
|
.Nm check_utility_compat
|
||||||
|
.Nd "determine whether a utility should be compatible"
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In unistd.h
|
||||||
|
.Ft int
|
||||||
|
.Fn check_utility_compat "const char *utility"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
function checks whether
|
||||||
|
.Fa utility
|
||||||
|
should behave in a traditional
|
||||||
|
.Pq Fx 4.7 -compatible
|
||||||
|
manner, or in accordance with
|
||||||
|
.St -p1003.1-2001 .
|
||||||
|
The configuration is given as a comma-separated list of utility names;
|
||||||
|
if the list is present but empty, all supported utilities assume their
|
||||||
|
most compatible mode.
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
function first checks for an environment variable named
|
||||||
|
.Ev _COMPAT_FreeBSD_4 .
|
||||||
|
If that environment variable does not exist, then
|
||||||
|
.Nm
|
||||||
|
will attempt to read the contents of a symbolic link named
|
||||||
|
.Pa /etc/compat-FreeBSD-4-util .
|
||||||
|
If no configuration is found, compatibility mode is disabled.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
function returns zero if
|
||||||
|
.Fa utility
|
||||||
|
should implement strict
|
||||||
|
.St -p1003.1-2001
|
||||||
|
behavior, and nonzero otherwise.
|
||||||
|
.Sh ERRORS
|
||||||
|
No errors are detected.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -offset indent -width Pa
|
||||||
|
.It Pa /etc/compat-FreeBSD-4-util
|
||||||
|
If present, a symbolic link whose expansion gives system-wide default settings
|
||||||
|
for the
|
||||||
|
.Nm
|
||||||
|
function.
|
||||||
|
.El
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
function first appeared in
|
||||||
|
.Fx 5.0 .
|
||||||
|
.Sh AUTHOR
|
||||||
|
This manual page was written by
|
||||||
|
.An Garrett Wollman Aq wollman@FreeBSD.org .
|
75
lib/libc/gen/check_utility_compat.c
Normal file
75
lib/libc/gen/check_utility_compat.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002 Massachusetts Institute of Technology
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software and
|
||||||
|
* its documentation for any purpose and without fee is hereby
|
||||||
|
* granted, provided that both the above copyright notice and this
|
||||||
|
* permission notice appear in all copies, that both the above
|
||||||
|
* copyright notice and this permission notice appear in all
|
||||||
|
* supporting documentation, and that the name of M.I.T. not be used
|
||||||
|
* in advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission. M.I.T. makes
|
||||||
|
* no representations about the suitability of this software for any
|
||||||
|
* purpose. It is provided "as is" without express or implied
|
||||||
|
* warranty.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||||
|
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||||
|
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I din't use "namespace.h" here because none of the relevant utilities
|
||||||
|
* are threaded, so I'm not concerned about cancellation points or other
|
||||||
|
* niceties.
|
||||||
|
*/
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef LINE_MAX
|
||||||
|
#define LINE_MAX _POSIX2_LINE_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _PATH_UTIL_COMPAT "/etc/compat-FreeBSD-4-util"
|
||||||
|
#define _ENV_UTIL_COMPAT "_COMPAT_FreeBSD_4"
|
||||||
|
|
||||||
|
int
|
||||||
|
check_utility_compat(const char *utility)
|
||||||
|
{
|
||||||
|
char buf[LINE_MAX];
|
||||||
|
char *p, *bp;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if ((p = getenv(_ENV_UTIL_COMPAT)) != NULL) {
|
||||||
|
strlcpy(buf, p, sizeof buf);
|
||||||
|
} else {
|
||||||
|
if ((len = readlink(_PATH_UTIL_COMPAT, buf, sizeof buf)) < 0)
|
||||||
|
return 0;
|
||||||
|
if (len > sizeof buf)
|
||||||
|
len = sizeof buf;
|
||||||
|
buf[len] = '\0';
|
||||||
|
}
|
||||||
|
if (buf[0] == '\0')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
bp = buf;
|
||||||
|
while ((p = strsep(&bp, ",")) != NULL) {
|
||||||
|
if (strcmp(p, utility) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user