]> Zhao Yanbai Git Server - minix.git/commitdiff
- new pread(), fnmatch() calls
authorBen Gras <ben@minix3.org>
Thu, 25 Feb 2010 17:08:08 +0000 (17:08 +0000)
committerBen Gras <ben@minix3.org>
Thu, 25 Feb 2010 17:08:08 +0000 (17:08 +0000)
 - split sprintf() and snprintf() to solve a linking problem when
   compiling an application

include/fnmatch.h [new file with mode: 0644]
include/unistd.h
lib/libc/posix/Makefile.inc
lib/libc/posix/charclass.h [new file with mode: 0644]
lib/libc/posix/fnmatch.c [new file with mode: 0644]
lib/libc/posix/pread.c [new file with mode: 0644]
lib/libc/stdio/Makefile.inc
lib/libc/stdio/snprintf.c [new file with mode: 0644]
lib/libc/stdio/sprintf.c
man/man2/read.2
man/man3/fnmatch.3 [new file with mode: 0644]

diff --git a/include/fnmatch.h b/include/fnmatch.h
new file mode 100644 (file)
index 0000000..fd21313
--- /dev/null
@@ -0,0 +1,53 @@
+/*     $OpenBSD: fnmatch.h,v 1.8 2005/12/13 00:35:22 millert Exp $     */
+/*     $NetBSD: fnmatch.h,v 1.5 1994/10/26 00:55:53 cgd Exp $  */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *     @(#)fnmatch.h   8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef        _FNMATCH_H_
+#define        _FNMATCH_H_
+
+#define        FNM_NOMATCH     1       /* Match failed. */
+#define        FNM_NOSYS       2       /* Function not supported (unused). */
+
+#define        FNM_NOESCAPE    0x01    /* Disable backslash escaping. */
+#define        FNM_PATHNAME    0x02    /* Slash must be matched by slash. */
+#define        FNM_PERIOD      0x04    /* Period must be matched by period. */
+
+#define        FNM_LEADING_DIR 0x08    /* Ignore /<tail> after Imatch. */
+#define        FNM_CASEFOLD    0x10    /* Case insensitive search. */
+#define        FNM_IGNORECASE  FNM_CASEFOLD
+#define        FNM_FILE_NAME   FNM_PATHNAME
+
+
+int     fnmatch(const char *, const char *, int);
+
+#endif /* !_FNMATCH_H_ */
index e7c8bd682332ce7ee0a9c8d42c065d2cb6e240c4..c353472c20b6860c8753668bf2f9ba84df8095e2 100644 (file)
@@ -133,6 +133,7 @@ _PROTOTYPE( long pathconf, (const char *_path, int _name)           );
 _PROTOTYPE( int pause, (void)                                          );
 _PROTOTYPE( int pipe, (int _fildes[2])                                 );
 _PROTOTYPE( ssize_t read, (int _fd, void *_buf, size_t _n)             );
+_PROTOTYPE( ssize_t pread, (int, void *, size_t, off_t)                        );
 _PROTOTYPE( int rmdir, (const char *_path)                             );
 _PROTOTYPE( int setgid, (_mnx_Gid_t _gid)                              );
 _PROTOTYPE( int setegid, (_mnx_Gid_t _gid)                             );
index 52d761d52a811e5b4cadf513a780ad883e9ed2e4..dd7912d60dc718de53934106a1bfa899988e413e 100644 (file)
@@ -98,10 +98,12 @@ SRCS+=       \
        _wait.c \
        _waitpid.c \
        _write.c \
+       fnmatch.c \
        getloadavg.c \
        getopt.c \
        gettimeofday.c \
        glob.c \
        nice.c \
        priority.c \
+       pread.c \
        usleep.c
diff --git a/lib/libc/posix/charclass.h b/lib/libc/posix/charclass.h
new file mode 100644 (file)
index 0000000..c780f16
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Public domain, 2008, Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $
+ */
+
+/*
+ * POSIX character class support for fnmatch() and glob().
+ */
+static struct cclass {
+       const char *name;
+       int (*isctype)(int);
+} cclasses[] = {
+       { "alnum",      isalnum },
+       { "alpha",      isalpha },
+#ifndef _MINIX
+       { "blank",      isblank },
+#endif
+       { "cntrl",      iscntrl },
+       { "digit",      isdigit },
+       { "graph",      isgraph },
+       { "lower",      islower },
+       { "print",      isprint },
+       { "punct",      ispunct },
+       { "space",      isspace },
+       { "upper",      isupper },
+       { "xdigit",     isxdigit },
+       { NULL,         NULL }
+};
+
+#define NCCLASSES      (sizeof(cclasses) / sizeof(cclasses[0]) - 1)
diff --git a/lib/libc/posix/fnmatch.c b/lib/libc/posix/fnmatch.c
new file mode 100644 (file)
index 0000000..2388f82
--- /dev/null
@@ -0,0 +1,251 @@
+/*     $OpenBSD: fnmatch.c,v 1.14 2008/10/01 23:04:13 millert Exp $    */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <fnmatch.h>
+
+#include "charclass.h"
+
+#define        EOS     '\0'
+
+#define        RANGE_MATCH     1
+#define        RANGE_NOMATCH   0
+#define        RANGE_ERROR     (-1)
+
+static int rangematch(const char *, char, int, char **);
+static int classmatch(const char *, char, int, const char **);
+
+int
+fnmatch(const char *pattern, const char *string, int flags)
+{
+       const char *stringstart;
+       char *newp;
+       char c, test;
+
+       for (stringstart = string;;)
+               switch (c = *pattern++) {
+               case EOS:
+                       if ((flags & FNM_LEADING_DIR) && *string == '/')
+                               return (0);
+                       return (*string == EOS ? 0 : FNM_NOMATCH);
+               case '?':
+                       if (*string == EOS)
+                               return (FNM_NOMATCH);
+                       if (*string == '/' && (flags & FNM_PATHNAME))
+                               return (FNM_NOMATCH);
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+                       ++string;
+                       break;
+               case '*':
+                       c = *pattern;
+                       /* Collapse multiple stars. */
+                       while (c == '*')
+                               c = *++pattern;
+
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+
+                       /* Optimize for pattern with * at end or before /. */
+                       if (c == EOS) {
+                               if (flags & FNM_PATHNAME)
+                                       return ((flags & FNM_LEADING_DIR) ||
+                                           strchr(string, '/') == NULL ?
+                                           0 : FNM_NOMATCH);
+                               else
+                                       return (0);
+                       } else if (c == '/' && (flags & FNM_PATHNAME)) {
+                               if ((string = strchr(string, '/')) == NULL)
+                                       return (FNM_NOMATCH);
+                               break;
+                       }
+
+                       /* General case, use recursion. */
+                       while ((test = *string) != EOS) {
+                               if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
+                                       return (0);
+                               if (test == '/' && (flags & FNM_PATHNAME))
+                                       break;
+                               ++string;
+                       }
+                       return (FNM_NOMATCH);
+               case '[':
+                       if (*string == EOS)
+                               return (FNM_NOMATCH);
+                       if (*string == '/' && (flags & FNM_PATHNAME))
+                               return (FNM_NOMATCH);
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+
+                       switch (rangematch(pattern, *string, flags, &newp)) {
+                       case RANGE_ERROR:
+                               /* not a good range, treat as normal text */
+                               goto normal;
+                       case RANGE_MATCH:
+                               pattern = newp;
+                               break;
+                       case RANGE_NOMATCH:
+                               return (FNM_NOMATCH);
+                       }
+                       ++string;
+                       break;
+               case '\\':
+                       if (!(flags & FNM_NOESCAPE)) {
+                               if ((c = *pattern++) == EOS) {
+                                       c = '\\';
+                                       --pattern;
+                               }
+                       }
+                       /* FALLTHROUGH */
+               default:
+               normal:
+                       if (c != *string && !((flags & FNM_CASEFOLD) &&
+                                (tolower((unsigned char)c) ==
+                                tolower((unsigned char)*string))))
+                               return (FNM_NOMATCH);
+                       ++string;
+                       break;
+               }
+       /* NOTREACHED */
+}
+
+static int
+rangematch(const char *pattern, char test, int flags, char **newp)
+{
+       int negate, ok, rv;
+       char c, c2;
+
+       /*
+        * A bracket expression starting with an unquoted circumflex
+        * character produces unspecified results (IEEE 1003.2-1992,
+        * 3.13.2).  This implementation treats it like '!', for
+        * consistency with the regular expression syntax.
+        * J.T. Conklin (conklin@ngai.kaleida.com)
+        */
+       if ((negate = (*pattern == '!' || *pattern == '^')))
+               ++pattern;
+
+       if (flags & FNM_CASEFOLD)
+               test = (char)tolower((unsigned char)test);
+
+       /*
+        * A right bracket shall lose its special meaning and represent
+        * itself in a bracket expression if it occurs first in the list.
+        * -- POSIX.2 2.8.3.2
+        */
+       ok = 0;
+       c = *pattern++;
+       do {
+               if (c == '[' && *pattern == ':') {
+                       do {
+                               rv = classmatch(pattern + 1, test,
+                                   (flags & FNM_CASEFOLD), &pattern);
+                               if (rv == RANGE_MATCH)
+                                       ok = 1;
+                               c = *pattern++;
+                       } while (rv != RANGE_ERROR && c == '[' && *pattern == ':');
+                       if (c == ']')
+                               break;
+               }
+               if (c == '\\' && !(flags & FNM_NOESCAPE))
+                       c = *pattern++;
+               if (c == EOS)
+                       return (RANGE_ERROR);
+               if (c == '/' && (flags & FNM_PATHNAME))
+                       return (RANGE_NOMATCH);
+               if ((flags & FNM_CASEFOLD))
+                       c = (char)tolower((unsigned char)c);
+               if (*pattern == '-'
+                   && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+                       pattern += 2;
+                       if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+                               c2 = *pattern++;
+                       if (c2 == EOS)
+                               return (RANGE_ERROR);
+                       if (flags & FNM_CASEFOLD)
+                               c2 = (char)tolower((unsigned char)c2);
+                       if (c <= test && test <= c2)
+                               ok = 1;
+               } else if (c == test)
+                       ok = 1;
+       } while ((c = *pattern++) != ']');
+
+       *newp = (char *)pattern;
+       return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
+}
+
+static int
+classmatch(const char *pattern, char test, int foldcase, const char **ep)
+{
+       struct cclass *cc;
+       const char *colon;
+       size_t len;
+       int rval = RANGE_NOMATCH;
+
+       if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') {
+               *ep = pattern - 2;
+               return(RANGE_ERROR);
+       }
+       *ep = colon + 2;
+       len = (size_t)(colon - pattern);
+
+       if (foldcase && strncmp(pattern, "upper:]", 7) == 0)
+               pattern = "lower:]";
+       for (cc = cclasses; cc->name != NULL; cc++) {
+               if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') {
+                       if (cc->isctype((unsigned char)test))
+                               rval = RANGE_MATCH;
+                       break;
+               }
+       }
+       if (cc->name == NULL) {
+               /* invalid character class, return EOS */
+               *ep = colon + strlen(colon);
+               rval = RANGE_ERROR;
+       }
+       return(rval);
+}
diff --git a/lib/libc/posix/pread.c b/lib/libc/posix/pread.c
new file mode 100644 (file)
index 0000000..a1af022
--- /dev/null
@@ -0,0 +1,27 @@
+#include <lib.h>
+#include <unistd.h>
+
+ssize_t pread(int fd, void *buffer, size_t nbytes, off_t where)
+{
+       off_t here;
+       ssize_t r;
+
+       if((here = lseek(fd, 0, SEEK_CUR)) < 0)
+               return -1;
+
+       if(lseek(fd, where, SEEK_SET) < 0)
+               return -1;
+
+       if((r=read(fd, buffer, nbytes)) < 0) {
+               int e = errno;
+               lseek(fd, here, SEEK_SET);
+               errno = e;
+               return -1;
+       }
+
+       if(lseek(fd, here, SEEK_SET) < 0)
+               return -1;
+
+       return r;
+}
+
index c4de4f8acd9323d46d535c02aa6abba97f6dda84..a4a0c5409d923083cc894756cc71e0cbbdf7616b 100644 (file)
@@ -44,6 +44,7 @@ SRCS+=  \
        setbuf.c \
        setvbuf.c \
        sprintf.c \
+       snprintf.c \
        sscanf.c \
        tmpfile.c \
        tmpnam.c \
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
new file mode 100644 (file)
index 0000000..efe4c44
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * snprintf - print limited formatted output on an array
+ */
+/* $Header$ */
+
+#include       <stdio.h>
+#include       <stdarg.h>
+#include       <limits.h>
+#include       "loc_incl.h"
+
+int
+snprintf(char *s, size_t n, const char *format, ...)
+{
+       va_list ap;
+       int retval;
+
+       va_start(ap, format);
+
+       retval = vsnprintf(s, n, format, ap);
+
+       va_end(ap);
+
+       return retval;
+}
index c40b080de0e875396d64a305a0ce961665b00b0f..5fe46af36ceb8869967a05c5a3bda1104cac3e63 100644 (file)
@@ -23,17 +23,3 @@ sprintf(char *s, const char *format, ...)
        return retval;
 }
 
-int
-snprintf(char *s, size_t n, const char *format, ...)
-{
-       va_list ap;
-       int retval;
-
-       va_start(ap, format);
-
-       retval = vsnprintf(s, n, format, ap);
-
-       va_end(ap);
-
-       return retval;
-}
index 4326ac06ada26aa7641bb622333e80c6b3399956..ca9571ec0413f9b5f6bd0dab59b498b8caf28abb 100644 (file)
@@ -7,7 +7,7 @@
 .TH READ 2 "May 23, 1986"
 .UC 4
 .SH NAME
-read \- read input
+read, pread \- read input
 .SH SYNOPSIS
 .nf
 .ft B
@@ -15,6 +15,7 @@ read \- read input
 #include <unistd.h>
 
 ssize_t read(int \fId\fP, void *\fIbuf\fP, size_t \fInbytes\fP)
+ssize_t pread(int \fId\fP, void *\fIbuf\fP, size_t \fInbytes\fP, off_t \fIoffset\fP)
 .fi
 .SH DESCRIPTION
 .B Read
@@ -49,6 +50,11 @@ before the end-of-file, but in no other case.
 .PP
 If the returned value is 0, then
 end-of-file has been reached.
+.PP
+The
+.B pread
+system call performs the same functions, but reads from the specified
+position in the file without modifying the file pointer.
 .SH "RETURN VALUE
 If successful, the
 number of bytes actually read is returned.
@@ -57,6 +63,8 @@ Otherwise, a \-1 is returned and the global variable
 is set to indicate the error.
 .SH "ERRORS
 .B Read
+and 
+.B pread
 will fail if one or more of the following are true:
 .TP 15
 [EBADF]
@@ -75,9 +83,19 @@ any data arrived by the delivery of a signal.
 [EAGAIN]
 The file was marked for non-blocking I/O,
 and no data were ready to be read.
+.PP
+The
+.B pread
+system call may also return any of the
+.B lseek
+errors.
 .SH "SEE ALSO"
 .BR dup (2),
 .BR fcntl (2),
 .BR open (2),
 .BR pipe (2),
+.BR lseek (2),
 .BR write (2).
+.SH NOTES
+.B pread
+is currently implemented as a library function instead of a system call.
diff --git a/man/man3/fnmatch.3 b/man/man3/fnmatch.3
new file mode 100644 (file)
index 0000000..80c54bd
--- /dev/null
@@ -0,0 +1,120 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Guido van Rossum.
+.\" 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.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+.\"
+.\"     @(#)fnmatch.3  8.3 (Berkeley) 4/28/95
+.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.19.6.1 2008/11/25 02:59:29 kensmith Exp $
+.\"
+.TH FNMATCH 3 "July 18, 2004"
+.AT 3
+.SH NAME
+fnmatch \- test whether a filename or pathname matches a shell-style pattern
+.SH SYNOPSIS
+.nf
+.ft B
+#include <fnmatch.h>
+
+int fnmatch(const char *\fIpattern\fP, const char *\fIstring\fP, int \fIflags\fP);
+.ft R
+.fi
+.SH DESCRIPTION
+The
+.B fnmatch
+function matches patterns according to the rules used by the shell.
+It checks the string specified by the
+.IR string
+argument to see if it matches the pattern specified by the
+.IR pattern
+argument.
+.PP
+The
+.IR flags
+argument modifies the interpretation of
+.IR pattern
+and
+.IR string .
+The value of
+.IR flags
+is the bitwise inclusive OR of any of the following
+constants, which are defined in the include file fnmatch.h.
+.TP 15
+FNM_NOESCAPE
+Normally, every occurrence of a backslash followed by a character in
+.IR pattern
+is replaced by that character.
+This is done to negate any special meaning for the character.
+If the FNM_NOESCAPE
+flag is set, a backslash character is treated as an ordinary character.
+.TP 15
+FNM_PATHNAME
+Slash characters in
+.IR string
+must be explicitly matched by slashes in
+.IR pattern .
+If this flag is not set, then slashes are treated as regular characters.
+.TP 15
+FNM_PERIOD
+Leading periods in
+.IR string
+must be explicitly matched by periods in
+.IR pattern .
+If this flag is not set, then leading periods are treated as regular
+characters.
+The definition of leading is related to the specification of FNM_PATHNAME.
+A period is always leading if it is the first character in
+.IR string .
+Additionally, if FNM_PATHNAME is set, a period is leading
+if it immediately follows a slash.
+.TP 15
+FNM_LEADING_DIR
+Ignore /* rest after successful
+.IR pattern
+matching.
+.TP 15
+FNM_CASEFOLD
+Ignore case distinctions in both the
+.IR pattern
+and the
+.IR string .
+.SH RETURN VALUES
+The
+.B fnmatch
+function returns zero if
+.IR string
+matches the pattern specified by
+.IR pattern ,
+otherwise, it returns the value FNM_NOMATCH.
+.SH SEE ALSO
+.BR sh (1),
+.BR regex (3),
+.SH HISTORY
+The
+.B fnmatch
+function first appeared in 4.4BSD.
+.SH BUGS
+The pattern * matches the empty string, even if FNM_PATHNAME is specified.