#include <sys/ioctl.h>
typedef struct {
char c;
} Size1;
typedef struct {
char c[20];
} Size20;
typedef struct {
char c[IOCPARM_MASK];
} SizeMax;
#define EQ_CHECK(name) \
fprintf(fp, " assert_eq!(%s, %u);\n", #name, name)
#define IOC_CHECK(dir, type, nr, size) \
fprintf(fp, " assert_eq!(ioc(%lu, %lu, %lu, %lu), 0x%lx);\n", \
((unsigned long) (dir)), \
((unsigned long) (type)), \
((unsigned long) (nr)), \
((unsigned long) (size)), \
((unsigned long) _IOC((dir), (type), (nr), (size))))
#define IO_CHECK(type, nr) \
fprintf(fp, " assert_eq!(io(%lu, %lu), 0x%lx);\n", \
((unsigned long) (type)), \
((unsigned long) (nr)), \
((unsigned long) _IO((type), (nr))))
#define IOFN_CHECK(rustfn, cfn, type, nr, passed_type) \
fprintf(fp, " assert_eq!(%s::<%s>(%lu, %lu), 0x%lx, \"Expected %s::<%s>(%lu, %lu) to equal 0x%lx\");\n", \
#rustfn, \
#passed_type, \
((unsigned long) (type)), \
((unsigned long) (nr)), \
((unsigned long) cfn((type), (nr), passed_type)), \
#rustfn, \
#passed_type, \
((unsigned long) (type)), \
((unsigned long) (nr)), \
((unsigned long) cfn((type), (nr), passed_type)))
#define IOFN_CHECKS(rustfn, cfn) \
do { \
IOFN_CHECK(ior, _IOR, 0, 0, Size1); \
IOFN_CHECK(ior, _IOR, 1, 1, Size20); \
IOFN_CHECK(ior, _IOR, 0, 0, SizeMax); \
IOFN_CHECK(ior, _IOR, 0, 0xff, Size1); \
IOFN_CHECK(ior, _IOR, 0, 0xff, SizeMax); \
IOFN_CHECK(ior, _IOR, 0xff, 0, Size1); \
IOFN_CHECK(ior, _IOR, 0xff, 0, SizeMax); \
IOFN_CHECK(ior, _IOR, 0xff, 0xff, Size1); \
IOFN_CHECK(ior, _IOR, 0xff, 0xff, SizeMax); \
} while (0)
static int ioctl_ccompat_test(char const *arch) {
char filename[256];
FILE *fp;
sprintf(filename, "src/ccompat_tests_macos.rs");
fp = fopen(filename, "w");
if (fp == NULL) {
perror(filename);
return 1;
}
fprintf(fp, "//! This is an automatically generated file; do not edit.\n");
fprintf(fp, "//! Generated by gen_ccompat_tests.c on %s %s\n", __DATE__, __TIME__);
fprintf(fp, "use super::*;\n");
fprintf(fp, "\n");
fprintf(fp, "#[repr(C)]\n");
fprintf(fp, "struct Size1([u8; 1]);\n");
fprintf(fp, "\n");
fprintf(fp, "#[repr(C)]\n");
fprintf(fp, "struct Size20([u8; 20]);\n");
fprintf(fp, "\n");
fprintf(fp, "#[repr(C)]\n");
fprintf(fp, "struct SizeMax([u8; %u]);\n", IOCPARM_MASK);
fprintf(fp, "\n");
fprintf(fp, "#[test]\n");
fprintf(fp, "fn test_ioctl_ccompat() {\n");
fprintf(fp, " assert_eq!(core::mem::size_of::<Size1>(), 1);\n");
fprintf(fp, " assert_eq!(core::mem::size_of::<Size20>(), 20);\n");
fprintf(fp, " assert_eq!(core::mem::size_of::<SizeMax>(), %u);\n", IOCPARM_MASK);
fprintf(fp, "\n");
EQ_CHECK(IOCPARM_MASK);
EQ_CHECK(IOCPARM_MAX);
EQ_CHECK(IOC_VOID);
EQ_CHECK(IOC_OUT);
EQ_CHECK(IOC_IN);
IOC_CHECK(IOC_VOID, 0, 0, 0);
IOC_CHECK(IOC_OUT, 0, 0, 0);
IOC_CHECK(IOC_IN, 0, 0, 0);
IOC_CHECK(IOC_IN|IOC_OUT, 0, 0, 0);
IOC_CHECK(IOC_OUT, 1, 1, 20);
IOC_CHECK(IOC_OUT, 0, 0, IOCPARM_MASK);
IOC_CHECK(IOC_OUT, 0, 0xff, 0);
IOC_CHECK(IOC_OUT, 0, 0xff, IOCPARM_MASK);
IOC_CHECK(IOC_OUT, 0xff, 0, 0);
IOC_CHECK(IOC_OUT, 0xff, 0, IOCPARM_MASK);
IOC_CHECK(IOC_OUT, 0xff, 0xff, 0);
IOC_CHECK(IOC_OUT, 0xff, 0xff, IOCPARM_MASK);
IO_CHECK(0, 0);
IO_CHECK(1, 1);
IO_CHECK(0, 0xff);
IO_CHECK(0xff, 0);
IO_CHECK(0xff, 0xff);
IOFN_CHECKS(ior, _IOR);
IOFN_CHECKS(iow, _IOW);
IOFN_CHECKS(iowr, _IOWR);
fprintf(fp, "}\n");
fclose(fp);
return 0;
}