1998-07-29 07:08:05 +04:00
/* test whether fcntl locking works on this system */
1999-12-13 16:27:58 +03:00
# if defined(HAVE_UNISTD_H)
# include <unistd.h>
# endif
1998-07-29 07:08:05 +04:00
# include <stdio.h>
# include <stdlib.h>
1998-10-22 22:51:16 +04:00
# include <sys/types.h>
1998-07-29 07:08:05 +04:00
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# ifdef HAVE_SYS_FCNTL_H
# include <sys/fcntl.h>
# endif
2001-05-02 10:54:52 +04:00
# ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# endif
1998-07-29 07:08:05 +04:00
# include <errno.h>
static int sys_waitpid ( pid_t pid , int * status , int options )
{
# ifdef HAVE_WAITPID
return waitpid ( pid , status , options ) ;
# else /* USE_WAITPID */
return wait4 ( pid , status , options , NULL ) ;
# endif /* USE_WAITPID */
}
# define DATA "conftest.fcntl"
# ifndef SEEK_SET
# define SEEK_SET 0
# endif
/* lock a byte range in a open file */
int main ( int argc , char * argv [ ] )
{
struct flock lock ;
1999-12-13 16:27:58 +03:00
int fd , ret , status = 1 ;
pid_t pid ;
2001-05-06 18:09:10 +04:00
char * testdir = NULL ;
testdir = getenv ( " TESTDIR " ) ;
if ( testdir ) chdir ( testdir ) ;
1998-07-29 07:08:05 +04:00
2001-05-06 16:47:32 +04:00
alarm ( 10 ) ;
1998-07-29 07:08:05 +04:00
if ( ! ( pid = fork ( ) ) ) {
sleep ( 2 ) ;
fd = open ( DATA , O_RDONLY ) ;
2001-05-02 10:52:25 +04:00
if ( fd = = - 1 ) {
fprintf ( stderr , " ERROR: failed to open %s (errno=%d) \n " ,
DATA , ( int ) errno ) ;
2007-10-11 00:34:30 +04:00
exit ( 1 ) ;
2001-05-02 10:52:25 +04:00
}
1998-07-29 07:08:05 +04:00
lock . l_type = F_WRLCK ;
lock . l_whence = SEEK_SET ;
2012-04-05 03:59:41 +04:00
lock . l_start = 0x100000000LL ;
1998-07-29 07:08:05 +04:00
lock . l_len = 4 ;
lock . l_pid = getpid ( ) ;
lock . l_type = F_WRLCK ;
/* check if a lock applies */
ret = fcntl ( fd , F_GETLK , & lock ) ;
if ( ( ret = = - 1 ) | |
( lock . l_type = = F_UNLCK ) ) {
2001-05-02 10:52:25 +04:00
fprintf ( stderr , " ERROR: lock test failed (ret=%d errno=%d) \n " , ret , ( int ) errno ) ;
2007-10-11 00:34:30 +04:00
exit ( 1 ) ;
1998-07-29 07:08:05 +04:00
} else {
2007-10-11 00:34:30 +04:00
exit ( 0 ) ;
1998-07-29 07:08:05 +04:00
}
}
2001-05-02 11:58:40 +04:00
unlink ( DATA ) ;
fd = open ( DATA , O_RDWR | O_CREAT | O_EXCL , 0600 ) ;
1998-07-29 07:08:05 +04:00
2001-05-02 10:52:25 +04:00
if ( fd = = - 1 ) {
fprintf ( stderr , " ERROR: failed to open %s (errno=%d) \n " ,
DATA , ( int ) errno ) ;
2007-10-11 00:34:30 +04:00
exit ( 1 ) ;
2001-05-02 10:52:25 +04:00
}
1998-07-29 07:08:05 +04:00
lock . l_type = F_WRLCK ;
lock . l_whence = SEEK_SET ;
lock . l_start = 0 ;
2012-04-05 03:59:41 +04:00
lock . l_len = 0x100000004LL ;
1998-07-29 07:08:05 +04:00
lock . l_pid = getpid ( ) ;
2012-04-05 03:59:41 +04:00
/* set a 100000004 byte write lock, should conflict with the above */
ret = fcntl ( fd , F_SETLK , & lock ) ;
1998-07-29 07:08:05 +04:00
sys_waitpid ( pid , & status , 0 ) ;
unlink ( DATA ) ;
2012-04-05 03:59:41 +04:00
if ( ret ! = 0 ) {
fprintf ( stderr , " ERROR: failed to lock %s (errno=%d) \n " ,
DATA , ( int ) errno ) ;
exit ( 1 ) ;
}
if ( lock . l_len < 0x100000004LL ) {
2023-08-03 16:50:07 +03:00
fprintf ( stderr , " ERROR: setting lock overflowed \n " ) ;
2012-04-05 03:59:41 +04:00
exit ( 1 ) ;
}
1999-12-13 16:27:58 +03:00
# if defined(WIFEXITED) && defined(WEXITSTATUS)
if ( WIFEXITED ( status ) ) {
status = WEXITSTATUS ( status ) ;
} else {
status = 1 ;
}
# else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
status = ( status = = 0 ) ? 0 : 1 ;
# endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
2001-05-02 10:52:25 +04:00
if ( status ) {
fprintf ( stderr , " ERROR: lock test failed with status=%d \n " ,
status ) ;
}
2007-10-11 00:34:30 +04:00
exit ( status ) ;
1998-07-29 07:08:05 +04:00
}