Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Aug 2002 22:43:20 -0400
From:      Mike Barcroft <mike@FreeBSD.org>
To:        standards@FreeBSD.org
Subject:   fmtmsg(3) for review
Message-ID:  <20020802224320.A70372@espresso.q9media.com>

next in thread | raw e-mail | index | archive | help

--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


I'd appreciate comments on my implementation of fmtmsg(3).  Patch
attached.

Best regards,
Mike Barcroft

--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fmtmsg.diff"

Implement POSIX.1-2001 (XSI)'s fmtmsg(3).

Index: include/Makefile
===================================================================
RCS file: /work/repo/src/include/Makefile,v
retrieving revision 1.173
diff -u -r1.173 Makefile
--- include/Makefile	2 Aug 2002 06:56:26 -0000	1.173
+++ include/Makefile	3 Aug 2002 00:05:07 -0000
@@ -10,7 +10,7 @@
 SUBDIR= arpa protocols rpcsvc rpc
 INCS=	a.out.h ar.h assert.h bitstring.h complex.h cpio.h ctype.h db.h \
 	dirent.h \
-	dlfcn.h elf.h elf-hints.h err.h fnmatch.h fstab.h \
+	dlfcn.h elf.h elf-hints.h err.h fnmatch.h fmtmsg.h fstab.h \
 	fts.h glob.h grp.h \
 	hesiod.h histedit.h ieeefp.h ifaddrs.h inttypes.h iso646.h kenv.h \
 	langinfo.h \
Index: include/fmtmsg.h
===================================================================
RCS file: include/fmtmsg.h
diff -N include/fmtmsg.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ include/fmtmsg.h	3 Aug 2002 00:28:16 -0000
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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$
+ */
+
+#ifndef _FMTMSG_H_
+#define	_FMTMSG_H_
+
+/* Source of condition is... */
+#define	MM_HARD		0x0001	/* hardware. */
+#define	MM_SOFT		0x0002	/* software. */
+#define	MM_FIRM		0x0004	/* fireware. */
+
+/* Condition detected by... */
+#define	MM_APPL		0x0010	/* application. */
+#define	MM_UTIL		0x0020	/* utility. */
+#define	MM_OPSYS	0x0040	/* operating system. */
+
+/* Display on... */
+#define	MM_PRINT	0x0100	/* standard error. */
+#define	MM_CONSOLE	0x0200	/* system console. */
+
+#define	MM_RECOVER	0x1000	/* Recoverable error. */
+#define	MM_NRECOV	0x2000	/* Non-recoverable error. */
+
+/* Severity levels. */
+#define	MM_NOSEV	0	/* No severity level provided. */
+#define	MM_HALT		1	/* Error causing application to halt. */
+#define	MM_ERROR	2	/* Non-fault fault. */
+#define	MM_WARNING	3	/* Unusual non-error condition. */
+#define	MM_INFO		4	/* Informative message. */
+
+/* Null options. */
+#define	MM_NULLLBL	(char *)0
+#define	MM_NULLSEV	0
+#define	MM_NULLMC	0L
+#define	MM_NULLTXT	(char *)0
+#define	MM_NULLACT	(char *)0
+#define	MM_NULLTAG	(char *)0
+
+/* Return values. */
+#define	MM_OK		0	/* Success. */
+#define	MM_NOMSG	1	/* Failed to output to stderr. */
+#define	MM_NOCON	2	/* Failed to output to console. */
+#define	MM_NOTOK	3	/* Failed to output anything. */
+
+int fmtmsg(long, const char *, int, const char *, const char *, const char *);
+
+#endif /* _FMTMSG_H_ */
Index: lib/libc/gen/Makefile.inc
===================================================================
RCS file: /work/repo/src/lib/libc/gen/Makefile.inc,v
retrieving revision 1.92
diff -u -r1.92 Makefile.inc
--- lib/libc/gen/Makefile.inc	13 Jul 2002 19:33:20 -0000	1.92
+++ lib/libc/gen/Makefile.inc	2 Aug 2002 18:07:07 -0000
@@ -9,7 +9,7 @@
 	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 \
-	exec.c fmtcheck.c fnmatch.c fstab.c ftok.c fts.c \
+	exec.c fmtcheck.c fmtmsg.c fnmatch.c fstab.c ftok.c fts.c \
 	getbootfile.c getbsize.c \
 	getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
 	gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \
@@ -41,7 +41,7 @@
 	basename.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 fnmatch.3 frexp.3 ftok.3 fts.3 \
+	err.3 exec.3 fmtcheck.3 fmtmsg.3 fnmatch.3 frexp.3 ftok.3 fts.3 \
 	getbootfile.3 getbsize.3 getcap.3 getcwd.3 \
 	getdiskbyname.3 getdomainname.3 getfsent.3 \
 	getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
Index: lib/libc/gen/err.3
===================================================================
RCS file: /work/repo/src/lib/libc/gen/err.3,v
retrieving revision 1.18
diff -u -r1.18 err.3
--- lib/libc/gen/err.3	1 Oct 2001 16:08:50 -0000	1.18
+++ lib/libc/gen/err.3	2 Aug 2002 18:34:43 -0000
@@ -207,6 +207,7 @@
 .Ed
 .Sh SEE ALSO
 .Xr exit 3 ,
+.Xr fmtmsg 3 ,
 .Xr printf 3 ,
 .Xr strerror 3
 .Sh HISTORY
Index: lib/libc/gen/fmtmsg.3
===================================================================
RCS file: lib/libc/gen/fmtmsg.3
diff -N lib/libc/gen/fmtmsg.3
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libc/gen/fmtmsg.3	3 Aug 2002 01:10:49 -0000
@@ -0,0 +1,256 @@
+.\"
+.\" Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 August 2, 2002
+.Dt FMTMSG 3
+.Os
+.Sh NAME
+.Nm fmtmsg
+.Nd display a detailed diagnostic message
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In fmtmsg.h
+.Ft int
+.Fn fmtmsg "long classification" "const char *label" "int severity" "const char *text" "const char *action" "const char *tag"
+.Sh DESCRIPTION
+The
+.Fn fmtmsg
+function displays a detailed diagnostic message, based on
+the supplied augments, to
+.Em stderr
+and/or the system console.
+.Pp
+The
+.Fa classification
+argument is the bitwise inclusive
+.Tn OR
+of zero or one of the manifest constants from
+each of the classification groups below.
+The Output classification group is an exception since both
+.Dv MM_PRINT
+and
+.Dv MM_CONSOLE
+may be specified.
+.Pp
+Output
+.Bl -tag -offset indent -width MM_CONSOLE
+.It Dv MM_PRINT
+Output should take place on
+.Em stderr .
+.It Dv MM_CONSOLE
+Output should take place on the system console.
+.El
+.Pp
+Source of Condition (Major)
+.Bl -tag -offset indent -width MM_CONSOLE
+.It Dv MM_HARD
+The source of the condition is hardware related.
+.It Dv MM_SOFT
+The source of the condition is software related.
+.It Dv MM_FIRM
+The source of the condition is firmware related.
+.El
+.Pp
+Source of Condition (Minor)
+.Bl -tag -offset indent -width MM_CONSOLE
+.It Dv MM_APPL
+The condition was detected at the application level.
+.It Dv MM_UTIL
+The condition was detected at the utility level.
+.It Dv MM_OPSYS
+The condition was detected at the operating system level.
+.El
+.Pp
+Status
+.Bl -tag -offset indent -width MM_CONSOLE
+.It Dv MM_RECOVER
+The application can recover from the condition.
+.It Dv MM_NRECOV
+The application is unable to recover from the condition.
+.El
+.Pp
+Alternatively, the
+.Dv MM_NULLMC
+manifest constant may be used to specify no classification.
+.Pp
+The
+.Fa label
+argument indicates the source of the message.
+It is made up of two fields seperated by a colon
+.Pq \&: .
+The first field can be up to 10 bytes,
+and the second field can be up to 14 bytes.
+The
+.Dv MM_NULLLBL
+manifest constant may be used to specify no label.
+.Pp
+The
+.Fa severity
+argument identifies the importance of the condition.
+One of the following manifest constants should be used for this argument.
+.Bl -tag -offset indent -width MM_WARNING
+.It Dv MM_HALT
+The application has confronted a serious fault and is halting.
+.It Dv MM_ERROR
+The application has detected a fault.
+.It Dv MM_WARNING
+The application has detected an unusual condition,
+that could be indicative of a problem.
+.It Dv MM_INFO
+The application is providing information about a non-error condition.
+.It Dv MM_NOSEV
+No severity level supplied.
+.El
+.Pp
+The
+.Fa text
+argument details the error condition that caused the message.
+There is no limit on the size of this character string.
+The
+.Dv MM_NULLTXT
+manifest constant may be used to specify no text.
+.Pp
+The
+.Fa action
+argument details how the error-recovery process should begin.
+Upon output,
+.Fn fmtmsg
+will prefix
+.Qq TO FIX:
+to the begin of the
+.Fa action
+argument.
+The
+.Dv MM_NULLACT
+manifest constant may be used to specify no action.
+.Pp
+The
+.Fa tag
+argument should reference online documentation for the message.
+This usually includes the
+.Fa label
+and a unique identifying number.
+An example tag is
+.Qq BSD:ls:168 .
+The
+.Dv MM_NULLTAG
+manifest constant may be used to specify no tag.
+.Sh RETURN VALUES
+The
+.Fn fmtmsg
+function returns
+.Dv MM_OK
+upon success,
+.Dv MM_NOMSG
+to indicate output to
+.Em stderr
+failed,
+.Dv MM_NOCON
+to indicate output to the system console failed, or
+.Dv MM_NOTOK
+to indicate output to
+.Em stderr
+and the system console failed.
+.Sh ENVIRONMENT
+The
+.Va MSGVERB
+.Pq message verbosity
+environment variable specifies which arguments to
+.Fn fmtmsg
+will be outputted to
+.Em stderr ,
+and in which order.
+.Va MSGVERB
+should be a colon
+.Pq \&:
+seperated list of identifiers.
+Valid identifiers include: label, severity, text, action, and tag.
+If invalid identifiers are specified or incorrectly seperated,
+the default message verbosity and ordering will be used.
+The default ordering is equivalent to a
+.Va MSGVERB
+with a value of
+.Qq label:severity:text:action:tag .
+.Sh EXAMPLES
+The code:
+.Bd -literal -offset indent
+fmtmsg(MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR,
+    "illegal option -- z", "refer to manual", "BSD:ls:001");
+.Ed
+.Pp
+will output:
+.Bd -literal -offset indent
+BSD:ls: ERROR: illegal option -- z
+TO FIX: refer to manual BSD:ls:001
+.Ed
+.Pp
+to
+.Em stderr .
+.Pp
+The same code, with
+.Va MSGVERB
+set to
+.Qq "text:severity:action:tag" ,
+produces:
+.Bd -literal -offset indent
+illegal option -- z: ERROR
+TO FIX: refer to manual BSD:ls:001
+.Ed
+.Sh SEE ALSO
+.Xr err 3 ,
+.Xr exit 3 ,
+.Xr strerror 3
+.Sh STANDARDS
+The
+.Fn fmtmsg
+function conforms to
+.St -p1003.1-2001 .
+.Sh HISTORY
+The
+.Fn fmtmsg
+function first appeared in
+.Fx 5.0 .
+.Sh BUGS
+Specifying
+.Dv MM_NULLMC
+for the
+.Fa classification
+argument makes little sense, since without an output specified,
+.Fn fmtmsg
+is unable to do anything useful.
+.Pp
+In order for
+.Fn fmtmsg
+to output to the system console, the effective
+user must have appropriate permission to write to
+.Pa /dev/console .
+This means that on most systems
+.Fn fmtmsg
+will return
+.Dv MM_NOCON
+unless the effective user is root.
Index: lib/libc/gen/fmtmsg.c
===================================================================
RCS file: lib/libc/gen/fmtmsg.c
diff -N lib/libc/gen/fmtmsg.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libc/gen/fmtmsg.c	3 Aug 2002 00:56:46 -0000
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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$");
+
+#include <fmtmsg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Default value for MSGVERB. */
+#define	DFLT_MSGVERB	"label:severity:text:action:tag"
+
+/* Maximum valid size for a MSGVERB. */
+#define	MAX_MSGVERB	sizeof(DFLT_MSGVERB)
+
+static char	*printfmt(char *, long, const char *, int, const char *,
+		    const char *, const char *);
+static char	*nextcomp(const char *);
+static const char
+		*sevinfo(int);
+static int	 validmsgverb(const char *);
+
+static const char *validlist[] = {
+	"label", "severity", "text", "action", "tag", NULL
+};
+
+int
+fmtmsg(long class, const char *label, int sev, const char *text,
+    const char *action, const char *tag)
+{
+	FILE *fp;
+	char *env, *msgverb, *output;
+
+	if (class & MM_PRINT) {
+		if ((env = getenv("MSGVERB")) != NULL && *env != '\0' &&
+		    strlen(env) <= strlen(DFLT_MSGVERB)) {
+			if ((msgverb = strdup(env)) == NULL)
+				return (MM_NOTOK);
+			else if (validmsgverb(msgverb) == 0)
+				goto def;
+		} else {
+def:
+			if ((msgverb = strdup(DFLT_MSGVERB)) == NULL)
+				return (MM_NOTOK);
+		}
+		output = printfmt(msgverb, class, label, sev, text, action,
+		    tag);
+		if (output == NULL)
+			return (MM_NOTOK);
+		if (*output != '\0')
+			fprintf(stderr, "%s", output);
+		free(msgverb);
+		free(output);
+	}
+	if (class & MM_CONSOLE) {
+		output = printfmt(DFLT_MSGVERB, class, label, sev, text,
+		    action, tag);
+		if (output == NULL)
+			return (MM_NOCON);
+		if (*output != '\0') {
+			if ((fp = fopen("/dev/console", "a")) == NULL) {
+				free(output);
+				return (MM_NOCON);
+			}
+			fprintf(fp, "%s", output);
+			fclose(fp);
+		}
+		free(output);
+	}
+	return (MM_OK);
+}
+
+#define INSERT_COLON							\
+	if (*output != '\0')						\
+		strlcat(output, ": ", size)
+#define INSERT_NEWLINE							\
+	if (*output != '\0')						\
+		strlcat(output, "\n", size)
+#define INSERT_SPACE							\
+	if (*output != '\0')						\
+		strlcat(output, " ", size)
+
+/*
+ * Returns NULL on memory allocation failure, otherwise returns a pointer to
+ * a newly malloc()'d output buffer.
+ */
+static char *
+printfmt(char *msgverb, long class, const char *label, int sev,
+    const char *text, const char *act, const char *tag)
+{
+	size_t size;
+	char *comp, *output;
+	const char *sevname;
+
+	size = 32;
+	if (label != MM_NULLLBL)
+		size += strlen(label);
+	if ((sevname = sevinfo(sev)) != NULL)
+		size += strlen(sevname);
+	if (text != MM_NULLTXT)
+		size += strlen(text);
+	if (text != MM_NULLACT)
+		size += strlen(act);
+	if (tag != MM_NULLTAG)
+		size += strlen(tag);
+
+	if ((output = malloc(size)) == NULL)
+		return (NULL);
+	*output = '\0';
+	while ((comp = nextcomp(msgverb)) != NULL) {
+		if (strcmp(comp, "label") == 0 && label != MM_NULLLBL) {
+			INSERT_COLON;
+			strlcat(output, label, size);
+		} else if (strcmp(comp, "severity") == 0 && sevname != NULL) {
+			INSERT_COLON;
+			strlcat(output, sevinfo(sev), size);
+		} else if (strcmp(comp, "text") == 0 && text != MM_NULLTXT) {
+			INSERT_COLON;
+			strlcat(output, text, size);
+		} else if (strcmp(comp, "action") == 0 && act != MM_NULLACT) {
+			INSERT_NEWLINE;
+			strlcat(output, "TO FIX: ", size);
+			strlcat(output, act, size);
+		} else if (strcmp(comp, "tag") == 0 && tag != MM_NULLTAG) {
+			INSERT_SPACE;
+			strlcat(output, tag, size);
+		}
+	}
+	INSERT_NEWLINE;
+	return (output);
+}
+
+static char *
+nextcomp(const char *msgverb)
+{
+	static char lmsgverb[MAX_MSGVERB], *state;
+	char *retval;
+	
+	if (*lmsgverb == '\0') {
+		strlcpy(lmsgverb, msgverb, sizeof(lmsgverb));
+		retval = strtok_r(lmsgverb, ":", &state);
+	} else {
+		retval = strtok_r(NULL, ":", &state);
+	}
+	if (retval == NULL)
+		*lmsgverb = '\0';
+	return (retval);
+}
+
+static const char *
+sevinfo(int sev)
+{
+	switch (sev) {
+	case MM_HALT:
+		return ("HALT");
+	case MM_ERROR:
+		return ("ERROR");
+	case MM_WARNING:
+		return ("WARNING");
+	case MM_INFO:
+		return ("INFO");
+	default:
+		return (NULL);
+	}
+}
+
+/*
+ * Returns 1 if the msgverb list is valid, otherwise 0.
+ */
+static int
+validmsgverb(const char *msgverb)
+{
+	char *msgcomp;
+	const char *validcomp;
+
+	while ((msgcomp = nextcomp(msgverb)) != NULL) {
+		if (*msgcomp == '\0')
+			return (0);
+		for (validcomp = *validlist;
+		    validcomp != NULL; validcomp++) {
+			if (strcmp(msgcomp, validcomp) == 0)
+				break;
+		}
+		if (validcomp == NULL)
+			return (0);
+	}
+	return (1);
+}

--VbJkn9YxBvnuCH5J--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-standards" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020802224320.A70372>