mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Fixed some portability issues for Windows.
This commit is contained in:
parent
bb350beb63
commit
8fb43ddefa
9 changed files with 688 additions and 37 deletions
53
Makefile.am
53
Makefile.am
|
|
@ -12,7 +12,8 @@ snapraid_SOURCES = \
|
|||
sync.c \
|
||||
check.c \
|
||||
parity.c \
|
||||
handle.c
|
||||
handle.c \
|
||||
fnmatch.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
portable.h \
|
||||
|
|
@ -31,7 +32,8 @@ noinst_HEADERS = \
|
|||
tommyarray.c \
|
||||
tommyhash.c \
|
||||
tommyhashdyn.c \
|
||||
tommylist.c
|
||||
tommylist.c \
|
||||
fnmatch.h
|
||||
|
||||
mktest_SOURCES = \
|
||||
mktest.c
|
||||
|
|
@ -65,36 +67,36 @@ check-local:
|
|||
mkdir test/disk2
|
||||
mkdir test/disk3
|
||||
echo --- As empty, sync and check
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf sync
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Create some files, sync and check
|
||||
./mktest generate 1 3 1000 4000
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf sync
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 1 3 1000 4000
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Create some more files, sync and check
|
||||
./mktest generate 2 3 1000 4000
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf sync
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 2 3 1000 4000
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Delete some files, fix and check
|
||||
rm test/disk1/a*
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Delete the parity, fix and check
|
||||
rm test/parity
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Corrupt the parity, fix and check
|
||||
./mktest damage 1 10 10000 test/parity
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 1 10 10000 test/parity
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Corrupt some files, fix and check
|
||||
./mktest damage 1 1 500 test/disk2/b*
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(VALGRIND) ./snapraid -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 1 1 500 test/disk2/b*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf fix 2>/dev/null
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo Success!
|
||||
|
||||
# Valgrind testing
|
||||
|
|
@ -141,7 +143,8 @@ cachegrind:
|
|||
DISTWIN = \
|
||||
snapraid.txt \
|
||||
snapraid.html \
|
||||
snapraid.exe
|
||||
snapraid.exe \
|
||||
snapraid.conf.example
|
||||
|
||||
distwindows: $(DISTWIN)
|
||||
rm -f $(PACKAGE)-$(VERSION)-windows-x86.zip
|
||||
|
|
|
|||
12
configure.ac
12
configure.ac
|
|
@ -10,6 +10,7 @@ dnl Checks for programs.
|
|||
AC_PROG_CC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind --leak-check=full --track-fds=yes --error-exitcode=1],[])
|
||||
AC_CHECK_PROG([WINE],[wine],[wine],[])
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_SYS_LARGEFILE
|
||||
|
|
@ -19,7 +20,7 @@ AC_HEADER_ASSERT
|
|||
AC_HEADER_STDC
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h getopt.h fnmatch.h])
|
||||
AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h getopt.h fnmatch.h io.h])
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
|
@ -38,7 +39,7 @@ dnl Checks for library functions.
|
|||
AC_SYS_LARGEFILE
|
||||
AC_CHECK_FUNCS([memset strchr strerror strrchr])
|
||||
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf])
|
||||
AC_CHECK_FUNCS([ftruncate fsync posix_fallocate posix_fadvise pread pwrite fgetc_unlocked ferror_unlocked])
|
||||
AC_CHECK_FUNCS([ftruncate fsync posix_fallocate posix_fadvise pread pwrite fgetc_unlocked ferror_unlocked fnmatch])
|
||||
|
||||
dnl Checks for architecture
|
||||
AC_C_BIGENDIAN
|
||||
|
|
@ -46,6 +47,13 @@ AC_C_BIGENDIAN
|
|||
dnl Checks for compiler
|
||||
AC_CHECK_CC_OPT([-Wall], CFLAGS="$CFLAGS -Wall", [])
|
||||
|
||||
dnl Checks for test environment
|
||||
AS_CASE([$host],
|
||||
[*-*-mingw*], [TESTENV="$WINE"],
|
||||
[TESTENV="$VALGRIND"]
|
||||
)
|
||||
AC_SUBST([TESTENV])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
|
|
|
|||
496
fnmatch.c
Normal file
496
fnmatch.c
Normal file
|
|
@ -0,0 +1,496 @@
|
|||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if !HAVE_FNMATCH
|
||||
|
||||
/* Enable GNU extensions in fnmatch.h. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#if HAVE_FNMATCH_H
|
||||
#include <fnmatch.h>
|
||||
#else
|
||||
#include "fnmatch.h"
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* For platforms which support the ISO C amendment 1 functionality we
|
||||
support user defined character classes. */
|
||||
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
#endif
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined _LIBC || !defined __GNU_LIBRARY__
|
||||
|
||||
|
||||
# if defined STDC_HEADERS || !defined isascii
|
||||
# define ISASCII(c) 1
|
||||
# else
|
||||
# define ISASCII(c) isascii(c)
|
||||
# endif
|
||||
|
||||
# ifdef isblank
|
||||
# define ISBLANK(c) (ISASCII (c) && isblank (c))
|
||||
# else
|
||||
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
# endif
|
||||
# ifdef isgraph
|
||||
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
|
||||
# else
|
||||
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
|
||||
# endif
|
||||
|
||||
# define ISPRINT(c) (ISASCII (c) && isprint (c))
|
||||
# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
|
||||
# define ISALNUM(c) (ISASCII (c) && isalnum (c))
|
||||
# define ISALPHA(c) (ISASCII (c) && isalpha (c))
|
||||
# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
|
||||
# define ISLOWER(c) (ISASCII (c) && islower (c))
|
||||
# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
|
||||
# define ISSPACE(c) (ISASCII (c) && isspace (c))
|
||||
# define ISUPPER(c) (ISASCII (c) && isupper (c))
|
||||
# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
|
||||
|
||||
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* The GNU C library provides support for user-defined character classes
|
||||
and the functions from ISO C amendment 1. */
|
||||
# ifdef CHARCLASS_NAME_MAX
|
||||
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
|
||||
# else
|
||||
/* This shouldn't happen but some implementation might still have this
|
||||
problem. Use a reasonable default value. */
|
||||
# define CHAR_CLASS_MAX_LENGTH 256
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# define IS_CHAR_CLASS(string) __wctype (string)
|
||||
# else
|
||||
# define IS_CHAR_CLASS(string) wctype (string)
|
||||
# endif
|
||||
# else
|
||||
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
||||
|
||||
# define IS_CHAR_CLASS(string) \
|
||||
(STREQ (string, "alpha") || STREQ (string, "upper") \
|
||||
|| STREQ (string, "lower") || STREQ (string, "digit") \
|
||||
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|
||||
|| STREQ (string, "space") || STREQ (string, "print") \
|
||||
|| STREQ (string, "punct") || STREQ (string, "graph") \
|
||||
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
|
||||
# endif
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
# if !defined _LIBC && !defined getenv
|
||||
extern char *getenv ();
|
||||
# endif
|
||||
|
||||
# ifndef errno
|
||||
extern int errno;
|
||||
# endif
|
||||
|
||||
/* This function doesn't exist on most systems. */
|
||||
|
||||
# if !defined HAVE___STRCHRNUL && !defined _LIBC
|
||||
static char *
|
||||
__strchrnul (s, c)
|
||||
const char *s;
|
||||
int c;
|
||||
{
|
||||
char *result = strchr (s, c);
|
||||
if (result == NULL)
|
||||
result = strchr (s, '\0');
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef internal_function
|
||||
/* Inside GNU libc we mark some function in a special way. In other
|
||||
environments simply ignore the marking. */
|
||||
# define internal_function
|
||||
# endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
static int internal_fnmatch __P ((const char *pattern, const char *string,
|
||||
int no_leading_period, int flags))
|
||||
internal_function;
|
||||
static int
|
||||
internal_function
|
||||
internal_fnmatch (pattern, string, no_leading_period, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int no_leading_period;
|
||||
int flags;
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register unsigned char c;
|
||||
|
||||
/* Note that this evaluates C many times. */
|
||||
# ifdef _LIBC
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# else
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# endif
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
if (c == '\0')
|
||||
/* Trailing \ loses. */
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD ((unsigned char) *n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++)
|
||||
{
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* A slash does not match a wildcard under FNM_FILE_NAME. */
|
||||
return FNM_NOMATCH;
|
||||
else if (c == '?')
|
||||
{
|
||||
/* A ? needs to match one character. */
|
||||
if (*n == '\0')
|
||||
/* There isn't another character; no match. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
/* One character of the string is consumed in matching
|
||||
this ? wildcard, so *??? won't match if there are
|
||||
less than three characters. */
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\0')
|
||||
/* The wildcard(s) is/are the last element of the pattern.
|
||||
If the name is a file name and contains another slash
|
||||
this does mean it cannot match. */
|
||||
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
|
||||
? FNM_NOMATCH : 0);
|
||||
else
|
||||
{
|
||||
const char *endp;
|
||||
|
||||
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
|
||||
if (c == '[')
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
for (--p; n < endp; ++n)
|
||||
if (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
else if (c == '/' && (flags & FNM_FILE_NAME))
|
||||
{
|
||||
while (*n != '\0' && *n != '/')
|
||||
++n;
|
||||
if (*n == '/'
|
||||
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
|
||||
flags) == 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *p;
|
||||
c = FOLD (c);
|
||||
for (--p; n < endp; ++n)
|
||||
if (FOLD ((unsigned char) *n) == c
|
||||
&& (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2) == 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we come here no match is possible with the wildcard. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
static int posixly_correct;
|
||||
register int not;
|
||||
char cold;
|
||||
|
||||
if (posixly_correct == 0)
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '.' && no_leading_period && (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* `/' cannot be matched. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
unsigned char fn = FOLD ((unsigned char) *n);
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD ((unsigned char) *p);
|
||||
++p;
|
||||
|
||||
if (c == fn)
|
||||
goto matched;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
/* Leave room for the null. */
|
||||
char str[CHAR_CLASS_MAX_LENGTH + 1];
|
||||
size_t c1 = 0;
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wctype_t wt;
|
||||
# endif
|
||||
const char *startp = p;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (c1 == CHAR_CLASS_MAX_LENGTH)
|
||||
/* The name is too long and therefore the pattern
|
||||
is ill-formed. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *++p;
|
||||
if (c == ':' && p[1] == ']')
|
||||
{
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
if (c < 'a' || c >= 'z')
|
||||
{
|
||||
/* This cannot possibly be a character class name.
|
||||
Match it as a normal range. */
|
||||
p = startp;
|
||||
c = '[';
|
||||
goto normal_bracket;
|
||||
}
|
||||
str[c1++] = c;
|
||||
}
|
||||
str[c1] = '\0';
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wt = IS_CHAR_CLASS (str);
|
||||
if (wt == 0)
|
||||
/* Invalid character class name. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (__iswctype (__btowc ((unsigned char) *n), wt))
|
||||
goto matched;
|
||||
# else
|
||||
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|
||||
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|
||||
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|
||||
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|
||||
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|
||||
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|
||||
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|
||||
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|
||||
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|
||||
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|
||||
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|
||||
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
|
||||
goto matched;
|
||||
# endif
|
||||
}
|
||||
else if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
{
|
||||
normal_bracket:
|
||||
if (FOLD (c) == fn)
|
||||
goto matched;
|
||||
|
||||
cold = c;
|
||||
c = *p++;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
/* It is a range. */
|
||||
unsigned char cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (cold <= fn && fn <= FOLD (cend))
|
||||
goto matched;
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
do
|
||||
if (*++p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
while (*p != ':' || p[1] == ']');
|
||||
p += 2;
|
||||
c = *p;
|
||||
}
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD ((unsigned char) *n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
|
||||
# undef FOLD
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#endif
|
||||
84
fnmatch.h
Normal file
84
fnmatch.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__ || !defined __P
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
# endif
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef const
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# define __const const
|
||||
# else
|
||||
# define __const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
|
||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* This value is returned if the implementation does not support
|
||||
`fnmatch'. Since this is not the case here it will never be
|
||||
returned but the conformance test suites still require the symbol
|
||||
to be defined. */
|
||||
#ifdef _XOPEN_SOURCE
|
||||
# define FNM_NOSYS (-1)
|
||||
#endif
|
||||
|
||||
/* Match NAME against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((__const char *__pattern, __const char *__name,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
||||
12
mktest.c
12
mktest.c
|
|
@ -47,7 +47,7 @@ void generate(int disk, int size)
|
|||
|
||||
snprintf(path, sizeof(path), "test/disk%d/%s", disk, name);
|
||||
|
||||
f = fopen(path, "w");
|
||||
f = fopen(path, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Error writing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -59,7 +59,6 @@ void generate(int disk, int size)
|
|||
--count;
|
||||
}
|
||||
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +69,7 @@ void damage(const char* path, int size)
|
|||
off_t start;
|
||||
int count;
|
||||
|
||||
f = fopen(path, "r+");
|
||||
f = fopen(path, "r+b");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Error writing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -130,7 +129,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
for(i=0;i<disk;++i) {
|
||||
for(j=0;j<file;++j) {
|
||||
generate(i+1, rnd(size));
|
||||
if (j == 0)
|
||||
generate(i+1, size);
|
||||
else if (j == 1)
|
||||
generate(i+1, 0);
|
||||
else
|
||||
generate(i+1, rnd(size));
|
||||
}
|
||||
}
|
||||
} else if (strcmp(argv[1], "damage") == 0) {
|
||||
|
|
|
|||
2
parity.c
2
parity.c
|
|
@ -131,9 +131,11 @@ int parity_open(const char* path)
|
|||
|
||||
return f;
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
bail:
|
||||
close(f);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int parity_sync(const char* path, int f)
|
||||
|
|
|
|||
56
portable.h
56
portable.h
|
|
@ -92,6 +92,12 @@
|
|||
|
||||
#if HAVE_FNMATCH_H
|
||||
#include <fnmatch.h>
|
||||
#else
|
||||
#include "fnmatch.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
|
|
@ -112,10 +118,58 @@
|
|||
#define lseek lseek64
|
||||
#define fstat _fstati64
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#define ftruncate _chsize_s
|
||||
#define ftruncate windows_ftruncate
|
||||
#define HAVE_FSYNC 1
|
||||
#define fsync _commit
|
||||
|
||||
static inline int windows_ftruncate(int fd, off64_t off)
|
||||
{
|
||||
HANDLE h;
|
||||
LARGE_INTEGER pos;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos.QuadPart = off;
|
||||
if (!SetFilePointerEx(h, pos, 0, FILE_BEGIN)) {
|
||||
DWORD error = GetLastError();
|
||||
switch (error) {
|
||||
case ERROR_INVALID_HANDLE :
|
||||
errno = EBADF;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SetEndOfFile(h)) {
|
||||
DWORD error = GetLastError();
|
||||
switch (error) {
|
||||
case ERROR_INVALID_HANDLE :
|
||||
errno = EBADF;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED :
|
||||
errno = EACCES;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define rename windows_atomic_rename
|
||||
static inline int windows_atomic_rename(const char* a, const char* b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ exclude *.bak
|
|||
exclude tmp/
|
||||
exclude /lost+found/
|
||||
|
||||
# Define the block size in kilo bytes (1024 bytes).
|
||||
# Format: "block_size SIZE_IN_KB"
|
||||
# Default value is 256 -> 256 kilo bytes
|
||||
# Define the block size in kibi bytes (1024 bytes).
|
||||
# Format: "block_size SIZE_IN_KiB"
|
||||
# Default value is 256 -> 256 kibi bytes -> 262144 bytes
|
||||
block_size 256
|
||||
|
||||
|
|
|
|||
4
state.c
4
state.c
|
|
@ -179,7 +179,7 @@ void state_read(struct snapraid_state* state)
|
|||
count_block = 0;
|
||||
|
||||
pathcpy(path, sizeof(path), state->content);
|
||||
f = fopen(state->content, "r");
|
||||
f = fopen(state->content, "rt");
|
||||
if (!f) {
|
||||
/* if not found, assume empty */
|
||||
if (errno == ENOENT)
|
||||
|
|
@ -397,7 +397,7 @@ void state_write(struct snapraid_state* state)
|
|||
printf("Saving state...\n");
|
||||
|
||||
pathprint(path, sizeof(path), "%s.tmp", state->content);
|
||||
f = fopen(path, "w");
|
||||
f = fopen(path, "wt");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Error opening for writing the content file '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue