diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
commit | 8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch) | |
tree | 4099e8021376c7d8c05bdf8503093d80e9c7bad0 /tests | |
parent | Initial commit. (diff) | |
download | samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip |
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/README | 10 | ||||
-rw-r--r-- | tests/fcntl_lock.c | 132 | ||||
-rw-r--r-- | tests/fcntl_lock_thread.c | 117 | ||||
-rw-r--r-- | tests/ftruncate.c | 31 | ||||
-rw-r--r-- | tests/getgroups.c | 66 | ||||
-rw-r--r-- | tests/oldquotas.c | 115 | ||||
-rw-r--r-- | tests/readlink.c | 36 | ||||
-rw-r--r-- | tests/shared_mmap.c | 70 | ||||
-rw-r--r-- | tests/shlib.c | 8 | ||||
-rw-r--r-- | tests/summary.c | 28 | ||||
-rw-r--r-- | tests/sysquotas.c | 92 | ||||
-rw-r--r-- | tests/trivial.c | 7 |
12 files changed, 712 insertions, 0 deletions
diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..cf1be8b --- /dev/null +++ b/tests/README @@ -0,0 +1,10 @@ +This directory contains autoconf test programs that are too large to +comfortably fit in configure.in. + +These programs should test one feature of the OS and exit(0) if it +works or exit(1) if it doesn't work (do _not_ use return) + +The programs should be kept simple and to the point. Beautiful/fast +code is not necessary + + diff --git a/tests/fcntl_lock.c b/tests/fcntl_lock.c new file mode 100644 index 0000000..242b9f7 --- /dev/null +++ b/tests/fcntl_lock.c @@ -0,0 +1,132 @@ +/* test whether fcntl locking works on this system */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#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; + int fd, ret, status=1; + pid_t pid; + char *testdir = NULL; + + testdir = getenv("TESTDIR"); + if (testdir) chdir(testdir); + + alarm(10); + + if (!(pid=fork())) { + sleep(2); + fd = open(DATA, O_RDONLY); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0x100000000LL; + 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)) { + fprintf(stderr,"ERROR: lock test failed (ret=%d errno=%d)\n", ret, (int)errno); + exit(1); + } else { + exit(0); + } + } + + unlink(DATA); + fd = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0x100000004LL; + lock.l_pid = getpid(); + + /* set a 100000004 byte write lock, should conflict with the above */ + ret = fcntl(fd,F_SETLK,&lock); + + sys_waitpid(pid, &status, 0); + + unlink(DATA); + + if (ret != 0) { + fprintf(stderr,"ERROR: failed to lock %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + if (lock.l_len < 0x100000004LL) { + fprintf(stderr,"ERROR: setting lock overflowed\n"); + exit(1); + } + +#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) */ + + if (status) { + fprintf(stderr,"ERROR: lock test failed with status=%d\n", + status); + } + + exit(status); +} diff --git a/tests/fcntl_lock_thread.c b/tests/fcntl_lock_thread.c new file mode 100644 index 0000000..e341514 --- /dev/null +++ b/tests/fcntl_lock_thread.c @@ -0,0 +1,117 @@ +/* test whether fcntl locking works between threads on this Linux system */ + +#include <unistd.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#include <fcntl.h> + +#include <sys/fcntl.h> + +#include <sys/wait.h> + +#include <errno.h> +#include <pthread.h> + +#define DATA "conftest.fcntl" + +#define SEEK_SET 0 + +static void *test_thread(void *thread_parm) +{ + int *status = thread_parm; + int fd, ret; + struct flock lock; + + sleep(2); + fd = open(DATA, O_RDWR); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + pthread_exit(thread_parm); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = 0; + + /* check if a lock applies */ + ret = fcntl(fd,F_SETLK,&lock); + if ((ret != -1)) { + fprintf(stderr,"ERROR: lock test failed (ret=%d errno=%d)\n", ret, (int)errno); + } else { + *status = 0; /* SUCCESS! */ + } + pthread_exit(thread_parm); +} + +/* lock a byte range in a open file */ +int main(int argc, char *argv[]) +{ + struct flock lock; + int fd, ret, status=1, rc; + pid_t pid; + char *testdir = NULL; + pthread_t thread_id; + pthread_attr_t thread_attr; + + testdir = getenv("TESTDIR"); + if (testdir) chdir(testdir); + + alarm(10); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + rc = pthread_create(&thread_id, &thread_attr, &test_thread, &status); + pthread_attr_destroy(&thread_attr); + if (rc == 0) { + fprintf(stderr,"created thread_id=%lu\n", + (unsigned long int)thread_id); + } else { + fprintf(stderr,"ERROR: thread create failed, rc=%d\n", rc); + } + + unlink(DATA); + fd = open(DATA, O_RDWR|O_CREAT|O_RDWR, 0600); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 4; + lock.l_pid = getpid(); + + /* set a 4 byte write lock */ + fcntl(fd,F_SETLK,&lock); + + sleep(4); /* allow thread to try getting lock */ + + unlink(DATA); + +#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) */ + + if (status) { + fprintf(stderr,"ERROR: lock test failed with status=%d\n", + status); + } + + exit(status); +} diff --git a/tests/ftruncate.c b/tests/ftruncate.c new file mode 100644 index 0000000..4612376 --- /dev/null +++ b/tests/ftruncate.c @@ -0,0 +1,31 @@ +/* test whether ftruncte() can extend a file */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define DATA "conftest.trunc" +#define LEN 7663 + +int main(void) +{ + int *buf; + int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); + + if (fd == -1) { + exit(1); + } + + ftruncate(fd, LEN); + + unlink(DATA); + + if (lseek(fd, 0, SEEK_END) == LEN) { + exit(0); + } + exit(1); +} diff --git a/tests/getgroups.c b/tests/getgroups.c new file mode 100644 index 0000000..ab56480 --- /dev/null +++ b/tests/getgroups.c @@ -0,0 +1,66 @@ +/* this tests whether getgroups actually returns lists of integers + rather than gid_t. The test only works if the user running + the test is in at least 1 group + + The test is designed to check for those broken OSes that define + getgroups() as returning an array of gid_t but actually return a + array of ints! Ultrix is one culprit + */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <grp.h> + +int main(void) +{ + int i; + int *igroups; + char *cgroups; + int grp = 0; + int ngroups = getgroups(0,&grp); + + if (sizeof(gid_t) == sizeof(int)) { + fprintf(stderr,"gid_t and int are the same size\n"); + exit(1); + } + + if (ngroups <= 0) + ngroups = 32; + + igroups = (int *)malloc(sizeof(int)*ngroups); + + for (i=0;i<ngroups;i++) + igroups[i] = 0x42424242; + + ngroups = getgroups(ngroups,(gid_t *)igroups); + + if (igroups[0] == 0x42424242) + ngroups = 0; + + if (ngroups == 0) { + printf("WARNING: can't determine getgroups return type\n"); + exit(1); + } + + cgroups = (char *)igroups; + + if (ngroups == 1 && + cgroups[2] == 0x42 && cgroups[3] == 0x42) { + fprintf(stderr,"getgroups returns gid_t\n"); + exit(1); + } + + for (i=0;i<ngroups;i++) { + if (igroups[i] == 0x42424242) { + fprintf(stderr,"getgroups returns gid_t\n"); + exit(1); + } + } + + exit(0); +} diff --git a/tests/oldquotas.c b/tests/oldquotas.c new file mode 100644 index 0000000..37d4e2d --- /dev/null +++ b/tests/oldquotas.c @@ -0,0 +1,115 @@ +/* this test should find out whether legacy quota code in disk_quotas.c + * compiles. It is a stripped-down version of disk_quotas.c, with samba + * stuff removed and only system calls, header files, and constants left. + */ + +#ifndef HAVE_SYS_QUOTAS + +/* just a quick hack because sysquotas.h is included before linux/quota.h */ +#ifdef QUOTABLOCK_SIZE +#undef QUOTABLOCK_SIZE +#endif /* defined(QUOTABLOCK_SIZE) */ + +#ifdef WITH_QUOTAS + +#if defined(SUNOS5) /* Solaris */ + +#include <fcntl.h> +#include <sys/param.h> +#include <sys/fs/ufs_quota.h> +#include <sys/mnttab.h> +#include <sys/mntent.h> + +/**************************************************************************** + Allows querying of remote hosts for quotas on NFS mounted shares. + Supports normal NFS and AMD mounts. + Alan Romeril <a.romeril@ic.ac.uk> July 2K. +****************************************************************************/ + +#include <rpc/rpc.h> +#include <rpc/types.h> +#include <rpcsvc/rquota.h> +#include <rpc/nettype.h> +#include <rpc/xdr.h> + +static bool nfs_quotas(char *nfspath, uid_t euser_id, uint64_t *bsize, + uint64_t *dfree, uint64_t *dsize) +{ + CLIENT *clnt; + clnt = clnt_create("host", RQUOTAPROG, RQUOTAVERS, "udp"); + return true; +} + +/**************************************************************************** +try to get the disk space from disk quotas (SunOS & Solaris2 version) +Quota code by Peter Urbanec (amiga@cse.unsw.edu.au). +****************************************************************************/ + +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, + uint64_t *dsize) +{ + int ret; + struct quotctl command; + nfs_quotas("", 0, bsize, dfree, dsize); + + command.op = Q_GETQUOTA; + command.uid = 0; + command.addr = NULL; + ret = ioctl(1, Q_QUOTACTL, &command); + + return true; +} + +#else /* not SunOS / Solaris */ + +#if AIX +/* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */ +#include <jfs/quota.h> +/* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */ +#define dqb_curfiles dqb_curinodes +#define dqb_fhardlimit dqb_ihardlimit +#define dqb_fsoftlimit dqb_isoftlimit +#ifdef _AIXVERSION_530 +#include <sys/statfs.h> +#include <sys/vmount.h> +#endif /* AIX 5.3 */ +#else /* !AIX - HP-UX */ +#include <sys/quota.h> +#include <devnm.h> +#endif /* AIX */ + +/**************************************************************************** +try to get the disk space from disk quotas - default version +****************************************************************************/ + +bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree, + uint64_t *dsize) +{ + struct dqblk D; +#if defined(AIX) +#ifdef _AIXVERSION_530 + quota64_t user_quota; + quotactl(path, QCMD(Q_J2GETQUOTA, USRQUOTA), 0, (char *)&user_quota); +#endif /* AIX 5.3 */ + quotactl(path, QCMD(Q_GETQUOTA, USRQUOTA), 0, (char *)&D); +#else /* !AIX */ + quotactl(Q_GETQUOTA, "", 0, &D); +#endif /* !AIX */ + return (true); +} + +#endif /* SunOS / Solaris */ + +#else /* WITH_QUOTAS */ + +#error "This test should be called with WITH_QUOTAS defined" + +#endif /* WITH_QUOTAS */ + +#else /* HAVE_SYS_QUOTAS */ + +#error "This test should not be called for systems with new quota interface" + +#endif /* HAVE_SYS_QUOTAS */ + +int main(void) { return disk_quotas(NULL, NULL, NULL, NULL); } diff --git a/tests/readlink.c b/tests/readlink.c new file mode 100644 index 0000000..a09eba4 --- /dev/null +++ b/tests/readlink.c @@ -0,0 +1,36 @@ +/* test whether readlink returns a short buffer incorrectly. + We need to return 0 in case readlink is *broken* here - this is because our waf + CHECK_CODE function does only allow generating defines in case the test succeeds +*/ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define DATA "readlink.test" +#define FNAME "rdlnk.file" + +int main(void) +{ + char buf[7]; + int ret; + ssize_t rl_ret; + + unlink(FNAME); + ret = symlink(DATA, FNAME); + if (ret == -1) { + exit(0); + } + + rl_ret = readlink(FNAME, buf, sizeof(buf)); + if (rl_ret == -1) { + unlink(FNAME); + exit(0); + } + unlink(FNAME); + exit(1); +} diff --git a/tests/shared_mmap.c b/tests/shared_mmap.c new file mode 100644 index 0000000..5c32a66 --- /dev/null +++ b/tests/shared_mmap.c @@ -0,0 +1,70 @@ +/* this tests whether we can use a shared writeable mmap on a file - + as needed for the mmap variant of FAST_SHARE_MODES */ + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define DATA "conftest.mmap" + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +int main(void) +{ + int *buf; + int i; + int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); + int count=7; + + if (fd == -1) exit(1); + + for (i=0;i<10000;i++) { + write(fd,&i,sizeof(i)); + } + + close(fd); + + if (fork() == 0) { + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + if (buf == (int *)-1) exit(1); + + while (count-- && buf[9124] != 55732) sleep(1); + + if (count <= 0) exit(1); + + buf[1763] = 7268; + exit(0); + } + + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + if (buf == (int *)-1) exit(1); + + buf[9124] = 55732; + + while (count-- && buf[1763] != 7268) sleep(1); + + unlink(DATA); + + if (count > 0) exit(0); + exit(1); +} diff --git a/tests/shlib.c b/tests/shlib.c new file mode 100644 index 0000000..eddb76f --- /dev/null +++ b/tests/shlib.c @@ -0,0 +1,8 @@ +/* a trivial function used to test building shared libraries */ + +int foo(void); + +int foo(void) +{ + return 1; +} diff --git a/tests/summary.c b/tests/summary.c new file mode 100644 index 0000000..ea48975 --- /dev/null +++ b/tests/summary.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +void exit(int); + +int main(void) +{ +#if !defined(HAVE_FCNTL_LOCK) +#error "ERROR: No locking available. Running Samba would be unsafe" +#endif + +#if !(defined(HAVE_IFACE_GETIFADDRS) || defined(HAVE_IFACE_IFCONF) || defined(HAVE_IFACE_IFREQ) || defined(HAVE_IFACE_AIX)) +#warning "WARNING: No automated network interface determination" +#endif + +#if !(defined(USE_SETEUID) || defined(USE_SETREUID) || defined(USE_SETRESUID) || defined(USE_SETUIDX) || defined(HAVE_LINUX_THREAD_CREDENTIALS)) +#error "ERROR: no seteuid method available" +#endif + +#if !(defined(STAT_STATVFS) || defined(STAT_STATFS3_OSF1) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS4) || defined(STAT_STATFS2_FSIZE) || defined(STAT_STATFS2_FS_DATA)) +#error "ERROR: No disk free routine!" +#endif + +#if !((defined(HAVE_RANDOM) || defined(HAVE_RAND)) && (defined(HAVE_SRANDOM) || defined(HAVE_SRAND))) +#error "ERROR: No random or srandom routine!" +#endif + + exit(0); +} diff --git a/tests/sysquotas.c b/tests/sysquotas.c new file mode 100644 index 0000000..1c98d20 --- /dev/null +++ b/tests/sysquotas.c @@ -0,0 +1,92 @@ +/* this test should find out what quota api is available on the os */ + + int autoconf_quota(void); + +#if defined(HAVE_QUOTACTL_4A) +/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif + +#if defined(HAVE_LINUX_QUOTA_H) +# include <linux/quota.h> +# if defined(HAVE_STRUCT_IF_DQBLK) +# define SYS_DQBLK if_dqblk +# elif defined(HAVE_STRUCT_MEM_DQBLK) +# define SYS_DQBLK mem_dqblk +# endif +#elif defined(HAVE_SYS_QUOTA_H) +# include <sys/quota.h> +#endif + +#ifdef HPUX +/* HPUX has no prototype for quotactl but we test compile with strict + error checks, which would fail without function prototype */ +extern int quotactl(int cmd, const char *special, uid_t uid, void *addr); +#endif + +#ifndef SYS_DQBLK +#define SYS_DQBLK dqblk +#endif + + int autoconf_quota(void); + + int autoconf_quota(void) +{ + int ret = -1; + struct SYS_DQBLK D; + + ret = quotactl(Q_GETQUOTA,"/dev/hda1",0,(void *)&D); + + return ret; +} + +#elif defined(HAVE_QUOTACTL_4B) +/* int quotactl(const char *path, int cmd, int id, char *addr); */ + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SYS_QUOTA_H +#include <sys/quota.h> +#endif + +#ifdef HAVE_UFS_UFS_QUOTA_H +#include <ufs/ufs/quota.h> +#endif + +#if defined(HAVE_JFS_QUOTA_H) +#include <jfs/quota.h> +#endif + + int autoconf_quota(void) +{ + int ret = -1; + struct dqblk D; + + ret = quotactl("/",Q_GETQUOTA,0,(char *) &D); + + return ret; +} + +#elif defined(HAVE_QUOTACTL_2) + +#error HAVE_QUOTACTL_2 not implemented + +#else + +#error Unknown QUOTACTL prototype + +#endif + + int main(void) +{ + autoconf_quota(); + return 0; +} diff --git a/tests/trivial.c b/tests/trivial.c new file mode 100644 index 0000000..a137c8c --- /dev/null +++ b/tests/trivial.c @@ -0,0 +1,7 @@ + +void exit(int); + +int main(void) +{ + exit(0); +} |