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:
wollman 2002-10-28 00:15:43 +00:00
parent 092b51aeec
commit d47f5a7e94
6 changed files with 201 additions and 34 deletions

View File

@ -121,9 +121,23 @@ otherwise 0.
.Pp
Parentheses are used for grouping in the usual manner.
.Pp
Unless the
.Ev EXPR_COMPAT
variable is defined in the process environment, this version of
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 .
.Ss Compatibility with previous implementations
Unless
.Fx 4.x
compatibility is enabled, this version of
.Nm
adheres to the
\*[Px]
@ -140,43 +154,31 @@ will not permit this syntax.
See the examples below for portable ways to guarantee the correct
interpretation.
The
.Ev EXPR_COMPAT
variable is intended for use as a transition and debugging aid, when
.Xr check_utility_compat 3
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
is used in complex scripts which cannot easily be recast to avoid the
non-portable usage.
Defining
.Ev EXPR_COMPAT
Enabling compatibility mode
also implicitly enables the
.Fl e
option, since this matches the historic behavior of
.Nm
in
.Fx .
For historical reasons, defining the environment variable
.Ev EXPR_COMPAT
also enables compatibility mode.
.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
.Bl -tag -width ".Ev EXPR_COMPAT"
.It Ev EXPR_COMPAT
If set,
.Nm
will emulate historic
.Nm
implementations which did not obey the Utility Syntax Guidelines.
Implies
.Fl e .
If set, enables compatibility mode.
.El
.Sh EXAMPLES
.Bl -bullet
@ -248,15 +250,14 @@ the expression is invalid.
.El
.Sh SEE ALSO
.Xr sh 1 ,
.Xr test 1
.Xr test 1 ,
.Xr check_utility_compat 3
.Sh STANDARDS
The
.Nm
utility conforms to
.St -p1003.1-2001 ,
provided that the
.Ev EXPR_COMPAT
environment variable is not defined.
provided that compatibility mode is not enabled.
The
.Fl e
flag is an extension.

View File

@ -278,7 +278,8 @@ main(int argc, char *argv[])
int c;
setlocale (LC_ALL, "");
if (getenv("EXPR_COMPAT") != NULL) {
if (getenv("EXPR_COMPAT") != NULL
|| check_utility_compat("expr")) {
av = argv + 1;
eflag = 1;
} else {

View File

@ -437,6 +437,7 @@ struct timeval; /* select(2) */
int acct(const char *);
int async_daemon(void);
int brk(const void *);
int check_utility_compat(const char *);
int chroot(const char *);
const char *
crypt_get_format(void);

View File

@ -5,7 +5,7 @@
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/gen ${.CURDIR}/../libc/gen
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 \
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 \
@ -38,7 +38,7 @@ SRCS+= __xuname.c _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \
.if ${LIB} == "c"
MAN+= alarm.3 arc4random.3 \
basename.3 clock.3 \
basename.3 check_utility_compat.3 clock.3 \
confstr.3 ctermid.3 daemon.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 \

View 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 .

View 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;
}