aclocal.m4: New file with new test libiberty_AC_FUNC_STRNCMP.
* aclocal.m4: New file with new test libiberty_AC_FUNC_STRNCMP. * configure.in (AC_CHECK_HEADERS): Add sys/mman.h fcntl.h. (libiberty_AC_FUNC_STRNCMP): Invoke. * strncmp.c: New file. From-SVN: r33498
This commit is contained in:
parent
b9550bfbc6
commit
a9266bfa4a
@ -1,3 +1,12 @@
|
||||
2000-04-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* aclocal.m4: New file with new test libiberty_AC_FUNC_STRNCMP.
|
||||
|
||||
* configure.in (AC_CHECK_HEADERS): Add sys/mman.h fcntl.h.
|
||||
(libiberty_AC_FUNC_STRNCMP): Invoke.
|
||||
|
||||
* strncmp.c: New file.
|
||||
|
||||
Thu Apr 27 16:58:43 MET DST 2000 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* hashtab.c (htab_expand): Add prototype.
|
||||
|
71
libiberty/aclocal.m4
vendored
Normal file
71
libiberty/aclocal.m4
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
dnl See whether strncmp reads past the end of its string parameters.
|
||||
dnl On some versions of SunOS4 at least, strncmp reads a word at a time
|
||||
dnl but erroneously reads past the end of strings. This can cause
|
||||
dnl a SEGV in some cases.
|
||||
AC_DEFUN(libiberty_AC_FUNC_STRNCMP,
|
||||
[AC_REQUIRE([AC_FUNC_MMAP])
|
||||
AC_CACHE_CHECK([for working strncmp], ac_cv_func_strncmp_works,
|
||||
[AC_TRY_RUN([
|
||||
/* Test by Jim Wilson and Kaveh Ghazi.
|
||||
Check whether strncmp reads past the end of its string parameters. */
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAP_ANON
|
||||
#ifdef MAP_ANONYMOUS
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#else
|
||||
#define MAP_ANON MAP_FILE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
#ifndef O_RDONLY
|
||||
#define O_RDONLY 0
|
||||
#endif
|
||||
|
||||
#define MAP_LEN 0x10000
|
||||
|
||||
main ()
|
||||
{
|
||||
#if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE)
|
||||
char *p;
|
||||
int dev_zero;
|
||||
|
||||
dev_zero = open ("/dev/zero", O_RDONLY);
|
||||
if (dev_zero < 0)
|
||||
exit (1);
|
||||
|
||||
p = (char *) mmap (0, MAP_LEN, PROT_READ|PROT_WRITE,
|
||||
MAP_ANON|MAP_PRIVATE, dev_zero, 0);
|
||||
if (p == (char *)-1)
|
||||
exit (2);
|
||||
else
|
||||
{
|
||||
char *string = "__si_type_info";
|
||||
char *q = (char *) p + MAP_LEN - strlen (string) - 2;
|
||||
char *r = (char *) p + 0xe;
|
||||
|
||||
strcpy (q, string);
|
||||
strcpy (r, string);
|
||||
strncmp (r, q, 14);
|
||||
}
|
||||
#endif /* HAVE_MMAP || HAVE_MMAP_ANYWHERE */
|
||||
exit (0);
|
||||
}
|
||||
], ac_cv_func_strncmp_works=yes, ac_cv_func_strncmp_works=no,
|
||||
ac_cv_func_strncmp_works=no)
|
||||
rm -f core core.* *.core])
|
||||
if test $ac_cv_func_strncmp_works = no ; then
|
||||
LIBOBJS="$LIBOBJS strncmp.o"
|
||||
fi
|
||||
])
|
@ -13,6 +13,9 @@
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
@ -196,6 +199,9 @@
|
||||
/* Define if you have the waitpid function. */
|
||||
#undef HAVE_WAITPID
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
@ -208,6 +214,9 @@
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
|
360
libiberty/configure
vendored
360
libiberty/configure
vendored
@ -1058,7 +1058,7 @@ else
|
||||
fi
|
||||
echo "$ac_t""$CPP" 1>&6
|
||||
|
||||
for ac_hdr in sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h
|
||||
for ac_hdr in sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
@ -2550,6 +2550,364 @@ done
|
||||
|
||||
fi
|
||||
|
||||
for ac_hdr in unistd.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
echo "configure:2558: checking for $ac_hdr" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2563 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <$ac_hdr>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:2568: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_header_$ac_safe=yes"
|
||||
else
|
||||
echo "$ac_err" >&5
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_header_$ac_safe=no"
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
|
||||
echo "$ac_t""yes" 1>&6
|
||||
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
cat >> confdefs.h <<EOF
|
||||
#define $ac_tr_hdr 1
|
||||
EOF
|
||||
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in getpagesize
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:2597: checking for $ac_func" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2602 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func(); below. */
|
||||
#include <assert.h>
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char $ac_func();
|
||||
|
||||
int main() {
|
||||
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
|
||||
choke me
|
||||
#else
|
||||
$ac_func();
|
||||
#endif
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2625: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=yes"
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=no"
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
|
||||
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
|
||||
echo "$ac_t""yes" 1>&6
|
||||
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
|
||||
cat >> confdefs.h <<EOF
|
||||
#define $ac_tr_func 1
|
||||
EOF
|
||||
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
done
|
||||
|
||||
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
|
||||
echo "configure:2650: checking for working mmap" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_func_mmap_fixed_mapped=no
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2658 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
/* Thanks to Mike Haertel and Jim Avera for this test.
|
||||
Here is a matrix of mmap possibilities:
|
||||
mmap private not fixed
|
||||
mmap private fixed at somewhere currently unmapped
|
||||
mmap private fixed at somewhere already mapped
|
||||
mmap shared not fixed
|
||||
mmap shared fixed at somewhere currently unmapped
|
||||
mmap shared fixed at somewhere already mapped
|
||||
For private mappings, we should verify that changes cannot be read()
|
||||
back from the file, nor mmap's back from the file at a different
|
||||
address. (There have been systems where private was not correctly
|
||||
implemented like the infamous i386 svr4.0, and systems where the
|
||||
VM page cache was not coherent with the filesystem buffer cache
|
||||
like early versions of FreeBSD and possibly contemporary NetBSD.)
|
||||
For shared mappings, we should conversely verify that changes get
|
||||
propogated back to all the places they're supposed to be.
|
||||
|
||||
Grep wants private fixed already mapped.
|
||||
The main things grep needs to know about mmap are:
|
||||
* does it exist and is it safe to write into the mmap'd area
|
||||
* how to use it (BSD variants) */
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* This mess was copied from the GNU getpagesize.h. */
|
||||
#ifndef HAVE_GETPAGESIZE
|
||||
# ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
|
||||
/* Assume that all systems that can run configure have sys/param.h. */
|
||||
# ifndef HAVE_SYS_PARAM_H
|
||||
# define HAVE_SYS_PARAM_H 1
|
||||
# endif
|
||||
|
||||
# ifdef _SC_PAGESIZE
|
||||
# define getpagesize() sysconf(_SC_PAGESIZE)
|
||||
# else /* no _SC_PAGESIZE */
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# ifdef EXEC_PAGESIZE
|
||||
# define getpagesize() EXEC_PAGESIZE
|
||||
# else /* no EXEC_PAGESIZE */
|
||||
# ifdef NBPG
|
||||
# define getpagesize() NBPG * CLSIZE
|
||||
# ifndef CLSIZE
|
||||
# define CLSIZE 1
|
||||
# endif /* no CLSIZE */
|
||||
# else /* no NBPG */
|
||||
# ifdef NBPC
|
||||
# define getpagesize() NBPC
|
||||
# else /* no NBPC */
|
||||
# ifdef PAGESIZE
|
||||
# define getpagesize() PAGESIZE
|
||||
# endif /* PAGESIZE */
|
||||
# endif /* no NBPC */
|
||||
# endif /* no NBPG */
|
||||
# endif /* no EXEC_PAGESIZE */
|
||||
# else /* no HAVE_SYS_PARAM_H */
|
||||
# define getpagesize() 8192 /* punt totally */
|
||||
# endif /* no HAVE_SYS_PARAM_H */
|
||||
# endif /* no _SC_PAGESIZE */
|
||||
|
||||
#endif /* no HAVE_GETPAGESIZE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { void *malloc(unsigned); }
|
||||
#else
|
||||
char *malloc();
|
||||
#endif
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
char *data, *data2, *data3;
|
||||
int i, pagesize;
|
||||
int fd;
|
||||
|
||||
pagesize = getpagesize();
|
||||
|
||||
/*
|
||||
* First, make a file with some known garbage in it.
|
||||
*/
|
||||
data = malloc(pagesize);
|
||||
if (!data)
|
||||
exit(1);
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
*(data + i) = rand();
|
||||
umask(0);
|
||||
fd = creat("conftestmmap", 0600);
|
||||
if (fd < 0)
|
||||
exit(1);
|
||||
if (write(fd, data, pagesize) != pagesize)
|
||||
exit(1);
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* Next, try to mmap the file at a fixed address which
|
||||
* already has something else allocated at it. If we can,
|
||||
* also make sure that we see the same garbage.
|
||||
*/
|
||||
fd = open("conftestmmap", O_RDWR);
|
||||
if (fd < 0)
|
||||
exit(1);
|
||||
data2 = malloc(2 * pagesize);
|
||||
if (!data2)
|
||||
exit(1);
|
||||
data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
|
||||
if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_FIXED, fd, 0L))
|
||||
exit(1);
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data + i) != *(data2 + i))
|
||||
exit(1);
|
||||
|
||||
/*
|
||||
* Finally, make sure that changes to the mapped area
|
||||
* do not percolate back to the file as seen by read().
|
||||
* (This is a bug on some variants of i386 svr4.0.)
|
||||
*/
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
*(data2 + i) = *(data2 + i) + 1;
|
||||
data3 = malloc(pagesize);
|
||||
if (!data3)
|
||||
exit(1);
|
||||
if (read(fd, data3, pagesize) != pagesize)
|
||||
exit(1);
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data + i) != *(data3 + i))
|
||||
exit(1);
|
||||
close(fd);
|
||||
unlink("conftestmmap");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
EOF
|
||||
if { (eval echo configure:2798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
ac_cv_func_mmap_fixed_mapped=yes
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -fr conftest*
|
||||
ac_cv_func_mmap_fixed_mapped=no
|
||||
fi
|
||||
rm -fr conftest*
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
|
||||
if test $ac_cv_func_mmap_fixed_mapped = yes; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define HAVE_MMAP 1
|
||||
EOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
echo $ac_n "checking for working strncmp""... $ac_c" 1>&6
|
||||
echo "configure:2822: checking for working strncmp" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_strncmp_works'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_func_strncmp_works=no
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2830 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
/* Test by Jim Wilson and Kaveh Ghazi.
|
||||
Check whether strncmp reads past the end of its string parameters. */
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAP_ANON
|
||||
#ifdef MAP_ANONYMOUS
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#else
|
||||
#define MAP_ANON MAP_FILE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
#ifndef O_RDONLY
|
||||
#define O_RDONLY 0
|
||||
#endif
|
||||
|
||||
#define MAP_LEN 0x10000
|
||||
|
||||
main ()
|
||||
{
|
||||
#if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE)
|
||||
char *p;
|
||||
int dev_zero;
|
||||
|
||||
dev_zero = open ("/dev/zero", O_RDONLY);
|
||||
if (dev_zero < 0)
|
||||
exit (1);
|
||||
|
||||
p = (char *) mmap (0, MAP_LEN, PROT_READ|PROT_WRITE,
|
||||
MAP_ANON|MAP_PRIVATE, dev_zero, 0);
|
||||
if (p == (char *)-1)
|
||||
exit (2);
|
||||
else
|
||||
{
|
||||
char *string = "__si_type_info";
|
||||
char *q = (char *) p + MAP_LEN - strlen (string) - 2;
|
||||
char *r = (char *) p + 0xe;
|
||||
|
||||
strcpy (q, string);
|
||||
strcpy (r, string);
|
||||
strncmp (r, q, 14);
|
||||
}
|
||||
#endif /* HAVE_MMAP || HAVE_MMAP_ANYWHERE */
|
||||
exit (0);
|
||||
}
|
||||
|
||||
EOF
|
||||
if { (eval echo configure:2891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
ac_cv_func_strncmp_works=yes
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -fr conftest*
|
||||
ac_cv_func_strncmp_works=no
|
||||
fi
|
||||
rm -fr conftest*
|
||||
fi
|
||||
|
||||
rm -f core core.* *.core
|
||||
fi
|
||||
|
||||
echo "$ac_t""$ac_cv_func_strncmp_works" 1>&6
|
||||
if test $ac_cv_func_strncmp_works = no ; then
|
||||
LIBOBJS="$LIBOBJS strncmp.o"
|
||||
fi
|
||||
|
||||
|
||||
# Install a library built with a cross compiler in $(tooldir) rather
|
||||
# than $(libdir).
|
||||
if test -z "${with_cross_host}"; then
|
||||
|
@ -109,7 +109,7 @@ AC_SUBST_FILE(host_makefile_frag)
|
||||
# It's OK to check for header files. Although the compiler may not be
|
||||
# able to link anything, it had better be able to at least compile
|
||||
# something.
|
||||
AC_CHECK_HEADERS(sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h)
|
||||
AC_CHECK_HEADERS(sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h)
|
||||
AC_HEADER_SYS_WAIT
|
||||
|
||||
# This is the list of functions which libiberty will provide if they
|
||||
@ -352,6 +352,8 @@ EOF
|
||||
AC_CHECK_FUNCS($checkfuncs)
|
||||
fi
|
||||
|
||||
libiberty_AC_FUNC_STRNCMP
|
||||
|
||||
# Install a library built with a cross compiler in $(tooldir) rather
|
||||
# than $(libdir).
|
||||
if test -z "${with_cross_host}"; then
|
||||
|
28
libiberty/strncmp.c
Normal file
28
libiberty/strncmp.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* strncmp -- compare two strings, stop after n bytes.
|
||||
This function is in the public domain. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#ifdef __STDC__
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#define size_t unsigned long
|
||||
#endif
|
||||
|
||||
int
|
||||
strncmp(s1, s2, n)
|
||||
const char *s1, *s2;
|
||||
register size_t n;
|
||||
{
|
||||
register unsigned char u1, u2;
|
||||
|
||||
while (n-- > 0)
|
||||
{
|
||||
u1 = (unsigned char) *s1++;
|
||||
u2 = (unsigned char) *s2++;
|
||||
if (u1 != u2)
|
||||
return u1 - u2;
|
||||
if (u1 == '\0')
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user