2015-12-05 00:01:56 +00:00
/*
2016-01-05 22:37:42 +00:00
* Copyright ( c ) 2015 - 2016 Dmitry V . Levin < ldv @ altlinux . org >
2015-12-05 00:01:56 +00:00
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` 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 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 .
*/
2016-01-05 22:37:42 +00:00
# if defined HAVE_FTRUNCATE && defined HAVE_FUTIMENS
2015-12-05 00:01:56 +00:00
tests: fix TEST_SYSCALL_{NR,STR} and STRUCT_STAT_STR macros for musl
The contents of TEST_SYSCALL_NAME and STRUCT_STAT macros was subject
to macro expansion when used in definitions of TEST_SYSCALL_NR,
TEST_SYSCALL_STR, and STRUCT_STAT_STR macros.
As some libcs, e.g. musl libc, define lfs64 names as macros
(stat64 as stat, lstat64 as lstat, etc.), this might result to incorrect
expansion of TEST_SYSCALL_NR, TEST_SYSCALL_STR, and STRUCT_STAT_STR
macros. To avoid this problem, define these macros directly and remove
TEST_SYSCALL_NAME macro.
* tests/_newselect.c (TEST_SYSCALL_NAME): Remove.
(TEST_SYSCALL_NR, TEST_SYSCALL_STR): New macros.
* tests/fcntl.c: Likewise.
* tests/fcntl64.c: Likewise.
* tests/fstat.c: Likewise.
* tests/fstatat64.c: Likewise.
* tests/lstat.c: Likewise.
* tests/newfstatat.c: Likewise.
* tests/select.c: Likewise.
* tests/stat.c: Likewise.
* tests/fstat64.c (TEST_SYSCALL_NAME): Remove.
(TEST_SYSCALL_NR, TEST_SYSCALL_STR, STRUCT_STAT_STR): New macros.
* tests/lstat64.c: Likewise.
* tests/stat64.c: Likewise.
* tests/fstatx.c (TEST_SYSCALL_NR, nrify, nrify_): Remove.
* tests/lstatx.c: Likewise.
* tests/struct_flock.c (TEST_SYSCALL_NR, TEST_SYSCALL_STR, nrify,
nrify_, stringify, stringify_): Remove.
* tests/xselect.c: Likewise.
* tests/xstatx.c: Check TEST_SYSCALL_STR instead of TEST_SYSCALL_NAME.
(STRUCT_STAT_STR, TEST_SYSCALL_STR, stringify, stringify_): Remove.
[!STRUCT_STAT] (STRUCT_STAT_STR): New macro.
2016-01-12 00:03:41 +00:00
# ifndef TEST_SYSCALL_STR
# error TEST_SYSCALL_STR must be defined
2016-01-05 22:37:42 +00:00
# endif
2015-12-05 00:01:56 +00:00
# ifndef TEST_SYSCALL_INVOKE
# error TEST_SYSCALL_INVOKE must be defined
# endif
# ifndef PRINT_SYSCALL_HEADER
# error PRINT_SYSCALL_HEADER must be defined
# endif
# ifndef PRINT_SYSCALL_FOOTER
# error PRINT_SYSCALL_FOOTER must be defined
# endif
2016-10-19 11:11:41 +03:00
# include <errno.h>
2015-12-05 00:01:56 +00:00
# include <stdio.h>
# include <stddef.h>
# include <time.h>
# include <unistd.h>
2016-08-26 21:32:53 +00:00
# include <sys / sysmacros.h>
2015-12-05 00:01:56 +00:00
static void
print_time ( const time_t t )
{
if ( ! t ) {
printf ( " 0 " ) ;
return ;
}
struct tm * p = localtime ( & t ) ;
2016-08-13 20:27:38 +03:00
if ( p ) {
char buf [ 256 ] ;
strftime ( buf , sizeof ( buf ) , " %FT%T%z " , p ) ;
printf ( " %s " , buf ) ;
} else {
2016-08-31 16:31:53 +00:00
printf ( " %llu " , zero_extend_signed_to_ull ( t ) ) ;
2016-08-13 20:27:38 +03:00
}
2015-12-05 00:01:56 +00:00
}
2016-08-11 22:31:08 +00:00
# ifndef STRUCT_STAT
# define STRUCT_STAT struct stat
# define STRUCT_STAT_STR "struct stat"
# define STRUCT_STAT_IS_STAT64 0
# endif
# ifndef SAMPLE_SIZE
2017-01-13 19:31:30 +00:00
# define SAMPLE_SIZE ((libc_off_t) 43147718418ULL)
2016-08-11 22:31:08 +00:00
# endif
2015-12-05 00:01:56 +00:00
typedef off_t libc_off_t ;
# ifdef USE_ASM_STAT
# define stat libc_stat
# define stat64 libc_stat64
# endif
# include <fcntl.h>
# include <sys / stat.h>
# ifdef USE_ASM_STAT
# undef stat
# undef stat64
# endif
# ifdef USE_ASM_STAT
# undef st_atime
# undef st_mtime
# undef st_ctime
# include "asm_stat.h"
2016-08-30 12:43:09 +00:00
2016-08-11 22:31:08 +00:00
# if STRUCT_STAT_IS_STAT64
# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
2016-08-30 12:43:09 +00:00
# if defined MPERS_IS_m32
# ifdef HAVE_M32_STRUCT_STAT64_ST_MTIME_NSEC
# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
# endif
# elif defined MPERS_IS_mx32
# ifdef HAVE_MX32_STRUCT_STAT64_ST_MTIME_NSEC
# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
# endif
# elif defined HAVE_STRUCT_STAT64_ST_MTIME_NSEC
# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
# endif /* MPERS_IS_m32 || MPERS_IS_mx32 || HAVE_STRUCT_STAT64_ST_MTIME_NSEC */
# else /* !STRUCT_STAT_IS_STAT64 */
# if defined MPERS_IS_m32
# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
# ifdef HAVE_M32_STRUCT_STAT_ST_MTIME_NSEC
# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
# endif
# elif defined MPERS_IS_mx32
# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
# ifdef HAVE_MX32_STRUCT_STAT_ST_MTIME_NSEC
# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
# endif
# endif /* MPERS_IS_m32 || MPERS_IS_mx32 */
2016-08-11 22:31:08 +00:00
# endif /* STRUCT_STAT_IS_STAT64 */
2016-08-30 12:43:09 +00:00
2016-08-23 14:27:45 +00:00
# else /* !USE_ASM_STAT */
2015-12-05 00:01:56 +00:00
# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
# ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
2016-08-23 14:27:45 +00:00
# undef st_atime_nsec
# define st_atime_nsec st_atim.tv_nsec
2015-12-05 00:01:56 +00:00
# undef st_ctime_nsec
# define st_ctime_nsec st_ctim.tv_nsec
2016-08-23 14:27:45 +00:00
# undef st_mtime_nsec
# define st_mtime_nsec st_mtim.tv_nsec
# endif /* HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC */
2015-12-05 00:01:56 +00:00
# endif
2016-10-19 11:11:41 +03:00
# ifndef TEST_BOGUS_STRUCT_STAT
# define TEST_BOGUS_STRUCT_STAT 1
# endif
# ifndef IS_FSTAT
2017-01-12 22:52:17 +00:00
# define IS_FSTAT 0
2016-10-19 11:11:41 +03:00
# endif
2016-10-24 04:50:36 +03:00
# ifndef OLD_STAT
# define OLD_STAT 0
# endif
2015-12-05 00:01:56 +00:00
static void
print_ftype ( const unsigned int mode )
{
if ( S_ISREG ( mode ) )
printf ( " S_IFREG " ) ;
else if ( S_ISDIR ( mode ) )
printf ( " S_IFDIR " ) ;
else if ( S_ISCHR ( mode ) )
printf ( " S_IFCHR " ) ;
else if ( S_ISBLK ( mode ) )
printf ( " S_IFBLK " ) ;
else
printf ( " %#o " , mode & S_IFMT ) ;
}
static void
print_perms ( const unsigned int mode )
{
printf ( " %#o " , mode & ~ S_IFMT ) ;
}
static void
print_stat ( const STRUCT_STAT * st )
{
printf ( " {st_dev=makedev(%u, %u) " ,
2016-08-31 16:31:53 +00:00
( unsigned int ) major ( zero_extend_signed_to_ull ( st - > st_dev ) ) ,
( unsigned int ) minor ( zero_extend_signed_to_ull ( st - > st_dev ) ) ) ;
printf ( " , st_ino=%llu " , zero_extend_signed_to_ull ( st - > st_ino ) ) ;
2015-12-05 00:01:56 +00:00
printf ( " , st_mode= " ) ;
print_ftype ( st - > st_mode ) ;
printf ( " | " ) ;
print_perms ( st - > st_mode ) ;
2016-08-31 16:31:53 +00:00
printf ( " , st_nlink=%llu " , zero_extend_signed_to_ull ( st - > st_nlink ) ) ;
printf ( " , st_uid=%llu " , zero_extend_signed_to_ull ( st - > st_uid ) ) ;
printf ( " , st_gid=%llu " , zero_extend_signed_to_ull ( st - > st_gid ) ) ;
2016-10-24 04:50:36 +03:00
# if OLD_STAT
printf ( " , st_blksize=0, st_blocks=0 " ) ;
# else /* !OLD_STAT */
2016-08-31 16:31:53 +00:00
printf ( " , st_blksize=%llu " , zero_extend_signed_to_ull ( st - > st_blksize ) ) ;
printf ( " , st_blocks=%llu " , zero_extend_signed_to_ull ( st - > st_blocks ) ) ;
2016-10-24 04:50:36 +03:00
# endif /* OLD_STAT */
2015-12-05 00:01:56 +00:00
switch ( st - > st_mode & S_IFMT ) {
case S_IFCHR : case S_IFBLK :
printf ( " , st_rdev=makedev(%u, %u) " ,
2016-08-31 16:31:53 +00:00
( unsigned int ) major ( zero_extend_signed_to_ull ( st - > st_rdev ) ) ,
( unsigned int ) minor ( zero_extend_signed_to_ull ( st - > st_rdev ) ) ) ;
2015-12-05 00:01:56 +00:00
break ;
default :
2016-08-31 16:31:53 +00:00
printf ( " , st_size=%llu " , zero_extend_signed_to_ull ( st - > st_size ) ) ;
2015-12-05 00:01:56 +00:00
}
printf ( " , st_atime= " ) ;
2016-08-31 16:31:53 +00:00
print_time ( sign_extend_unsigned_to_ll ( st - > st_atime ) ) ;
2016-10-24 04:50:36 +03:00
# if defined(HAVE_STRUCT_STAT_ST_MTIME_NSEC) && !OLD_STAT
2015-12-05 00:01:56 +00:00
if ( st - > st_atime_nsec )
2016-08-31 16:31:53 +00:00
printf ( " .%09llu " , zero_extend_signed_to_ull ( st - > st_atime_nsec ) ) ;
2015-12-05 00:01:56 +00:00
# endif
printf ( " , st_mtime= " ) ;
2016-08-31 16:31:53 +00:00
print_time ( sign_extend_unsigned_to_ll ( st - > st_mtime ) ) ;
2016-10-24 04:50:36 +03:00
# if defined(HAVE_STRUCT_STAT_ST_MTIME_NSEC) && !OLD_STAT
2015-12-05 00:01:56 +00:00
if ( st - > st_mtime_nsec )
2016-08-31 16:31:53 +00:00
printf ( " .%09llu " , zero_extend_signed_to_ull ( st - > st_mtime_nsec ) ) ;
2015-12-05 00:01:56 +00:00
# endif
printf ( " , st_ctime= " ) ;
2016-08-31 16:31:53 +00:00
print_time ( sign_extend_unsigned_to_ll ( st - > st_ctime ) ) ;
2016-10-24 04:50:36 +03:00
# if defined(HAVE_STRUCT_STAT_ST_MTIME_NSEC) && !OLD_STAT
2015-12-05 00:01:56 +00:00
if ( st - > st_ctime_nsec )
2016-08-31 16:31:53 +00:00
printf ( " .%09llu " , zero_extend_signed_to_ull ( st - > st_ctime_nsec ) ) ;
2015-12-05 00:01:56 +00:00
# endif
printf ( " } " ) ;
}
static int
create_sample ( const char * fname , const libc_off_t size )
{
static const struct timespec ts [ ] = {
{ - 10843 , 135 } , { - 10841 , 246 }
} ;
( void ) close ( 0 ) ;
if ( open ( fname , O_RDWR | O_CREAT | O_TRUNC , 0640 ) ) {
perror ( fname ) ;
return 77 ;
}
if ( ftruncate ( 0 , size ) ) {
perror ( " ftruncate " ) ;
return 77 ;
}
if ( futimens ( 0 , ts ) ) {
perror ( " futimens " ) ;
return 77 ;
}
return 0 ;
}
int
main ( void )
{
2016-10-19 11:11:41 +03:00
# if !IS_FSTAT
static const char full [ ] = " /dev/full " ;
# endif
2015-12-05 00:01:56 +00:00
static const char sample [ ] = TEST_SYSCALL_STR " .sample " ;
STRUCT_STAT st [ 2 ] ;
2016-10-19 11:11:41 +03:00
int rc ;
rc = create_sample ( sample , SAMPLE_SIZE ) ;
2015-12-05 00:01:56 +00:00
if ( rc ) {
( void ) unlink ( sample ) ;
return rc ;
}
2016-10-19 11:11:41 +03:00
# if TEST_BOGUS_STRUCT_STAT
STRUCT_STAT * st_cut = tail_alloc ( sizeof ( long ) * 4 ) ;
rc = TEST_SYSCALL_INVOKE ( sample , st_cut ) ;
PRINT_SYSCALL_HEADER ( sample ) ;
printf ( " %p " , st_cut ) ;
PRINT_SYSCALL_FOOTER ( rc ) ;
# endif
# if !IS_FSTAT
rc = TEST_SYSCALL_INVOKE ( full , st ) ;
PRINT_SYSCALL_HEADER ( full ) ;
if ( rc )
printf ( " %p " , st ) ;
else
print_stat ( st ) ;
PRINT_SYSCALL_FOOTER ( rc ) ;
# endif
2016-10-19 11:11:41 +03:00
if ( ( rc = TEST_SYSCALL_INVOKE ( sample , st ) ) ) {
2016-10-24 04:50:36 +03:00
# if OLD_STAT
if ( errno ! = EOVERFLOW )
# endif
{
perror ( TEST_SYSCALL_STR ) ;
( void ) unlink ( sample ) ;
return 77 ;
}
2015-12-05 00:01:56 +00:00
}
( void ) unlink ( sample ) ;
2016-10-24 04:50:36 +03:00
if ( ! rc & & zero_extend_signed_to_ull ( SAMPLE_SIZE ) ! =
2016-08-31 16:31:53 +00:00
zero_extend_signed_to_ull ( st [ 0 ] . st_size ) ) {
2015-12-05 00:01:56 +00:00
fprintf ( stderr , " Size mismatch: "
2015-12-16 00:07:16 +00:00
" requested size(%llu) != st_size(%llu) \n " ,
2016-08-31 16:31:53 +00:00
zero_extend_signed_to_ull ( SAMPLE_SIZE ) ,
zero_extend_signed_to_ull ( st [ 0 ] . st_size ) ) ;
2015-12-05 00:01:56 +00:00
fprintf ( stderr , " The most likely reason for this is incorrect "
" definition of %s. \n "
" Here is some diagnostics that might help: \n " ,
STRUCT_STAT_STR ) ;
2017-01-12 23:01:32 +00:00
# define LOG_STAT_OFFSETOF_SIZEOF(object, member) \
fprintf ( stderr , " offsetof(%s, %s) = %zu " \
" , sizeof(%s) = %zu \n " , \
STRUCT_STAT_STR , # member , \
offsetof ( STRUCT_STAT , member ) , \
# member, sizeof((object).member))
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_dev ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_ino ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_mode ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_nlink ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_uid ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_gid ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_rdev ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_size ) ;
2016-10-24 04:50:36 +03:00
# if !OLD_STAT
2017-01-12 23:01:32 +00:00
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_blksize ) ;
LOG_STAT_OFFSETOF_SIZEOF ( st [ 0 ] , st_blocks ) ;
2016-10-24 04:50:36 +03:00
# endif /* !OLD_STAT */
2017-01-12 23:01:32 +00:00
2017-01-13 01:14:51 +00:00
return 1 ;
2015-12-05 00:01:56 +00:00
}
PRINT_SYSCALL_HEADER ( sample ) ;
2016-10-24 04:50:36 +03:00
if ( rc )
printf ( " %p " , st ) ;
else
print_stat ( st ) ;
2016-10-19 11:11:41 +03:00
PRINT_SYSCALL_FOOTER ( rc ) ;
2015-12-05 00:01:56 +00:00
puts ( " +++ exited with 0 +++ " ) ;
return 0 ;
}
# else
2016-01-05 22:37:42 +00:00
SKIP_MAIN_UNDEFINED ( " HAVE_FTRUNCATE && HAVE_FUTIMENS " )
2015-12-05 00:01:56 +00:00
# endif