--- IO-AIO/AIO.xs 2019/09/06 22:03:45 1.279 +++ IO-AIO/AIO.xs 2022/09/25 16:30:51 1.297 @@ -21,20 +21,6 @@ #include #include -/* the incompetent fool that created musl keeps __linux__, refuses - * to implement any linux standard apis, and also has no way to test - * for his broken iplementation. don't complain to me if this fails - * for you. - */ -#if __linux__ && (defined __GLIBC__ || defined __UCLIBC__) -# include -# ifdef FS_IOC_FIEMAP -# include -# include -# define HAVE_FIEMAP 1 -# endif -#endif - /* perl namespace pollution */ #undef VERSION @@ -86,6 +72,7 @@ #include #include + #include #include #include #include @@ -123,6 +110,28 @@ # include #endif +/* MUST be included before linux/fs.h, as the latter includes + * linux/mount.h, which is incompatible to sys/mount.h + */ +#if HAVE_SYS_MOUNT_H +# include +#endif + +/* the incompetent fool that created musl keeps __linux__, refuses + * to implement any linux standard apis, and also has no way to test + * for his broken implementation. don't complain to me if this fails + * for you. + */ +#if __linux__ && (defined __GLIBC__ || defined __UCLIBC__) +# include /* MUST be included after sys/mount.h */ +# ifdef FS_IOC_FIEMAP +# include +# include +# undef HAVE_FIEMAP +# define HAVE_FIEMAP 1 +# endif +#endif + #if HAVE_ST_XTIMENSEC # define ATIMENSEC PL_statcache.st_atimensec # define MTIMENSEC PL_statcache.st_mtimensec @@ -170,6 +179,8 @@ #endif typedef SV SV8; /* byte-sv, used for argument-checking */ +typedef char *octet_string; +typedef char *octet_string_ornull; typedef int aio_rfd; /* read file desriptor */ typedef int aio_wfd; /* write file descriptor */ @@ -228,6 +239,17 @@ # define PAGESIZE sysconf (_SC_PAGESIZE) #endif +/* solaris perl seems to declare a wrong syscall function that clashes with system includes */ +#ifdef __sun +# undef HAVE_SYSCALL +#endif + +#if HAVE_SYSCALL +#include +#else +# define syscall(nr,...) (errno = ENOSYS, -1) +#endif + /*****************************************************************************/ #if !_POSIX_MAPPED_FILES @@ -346,7 +368,7 @@ req->flags |= EIO_FLAG_PTR1_FREE; /* heuristic: start with 512 bytes (8 extents), and if that isn't enough, */ - /* increase in 3.5kb steps */ + /* increase in fixed steps */ if (count < 0) count = 8; @@ -409,11 +431,11 @@ { struct fiemap_extent *e = incmap->fm_extents + count; - if (e->fe_logical + e->fe_length >= end_offset) - goto done; - fiemap->fm_extents [fiemap->fm_mapped_extents++] = *e; + if (e->fe_logical >= end_offset) + goto done; + if (e->fe_flags & FIEMAP_EXTENT_LAST) goto done; @@ -1083,6 +1105,34 @@ /*****************************************************************************/ +/* extract a ref-to-array of strings into a temporary c style string vector */ +static char ** +extract_stringvec (SV *sv, const char *croakmsg) +{ + if (!SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV) + croak ("%s", croakmsg); + + AV *av = (AV *)SvRV (sv); + int i, nelem = av_len (av) + 1; + char **vecp = (char **)SvPVX (sv_2mortal (newSV (sizeof (char *) * (nelem + 1)))); + + for (i = 0; i < nelem; ++i) + { + SV **e = av_fetch (av, i, 0); + + if (e && *e) + vecp[i] = SvPVbyte_nolen (*e); + else + vecp[i] = ""; + } + + vecp[nelem] = 0; + + return vecp; +} + +/*****************************************************************************/ + XS(boot_IO__AIO) ecb_cold; MODULE = IO::AIO PACKAGE = IO::AIO @@ -1193,6 +1243,10 @@ const_iv (MAP_32BIT) const_iv (MAP_HUGETLB) const_iv (MAP_STACK) + const_iv (MAP_FIXED_NOREPLACE) + const_iv (MAP_SHARED_VALIDATE) + const_iv (MAP_SYNC) + const_iv (MAP_UNINITIALIZED) const_iv (MREMAP_MAYMOVE) const_iv (MREMAP_FIXED) @@ -1297,6 +1351,8 @@ const_iv (MFD_CLOEXEC) const_iv (MFD_ALLOW_SEALING) const_iv (MFD_HUGETLB) + const_iv (MFD_HUGETLB_2MB) + const_iv (MFD_HUGETLB_1GB) const_iv (CLOCK_REALTIME) const_iv (CLOCK_MONOTONIC) @@ -1331,6 +1387,112 @@ const_iv (STATX_ATTR_ENCRYPTED) const_iv (STATX_ATTR_AUTOMOUNT) + const_iv (AT_FDCWD) + const_iv (AT_SYMLINK_NOFOLLOW) + const_iv (AT_EACCESS) + const_iv (AT_REMOVEDIR) + const_iv (AT_SYMLINK_FOLLOW) + const_iv (AT_NO_AUTOMOUNT) + const_iv (AT_EMPTY_PATH) + const_iv (AT_STATX_SYNC_TYPE) + const_iv (AT_STATX_AS_STAT) + const_iv (AT_STATX_FORCE_SYNC) + const_iv (AT_STATX_DONT_SYNC) + const_iv (AT_RECURSIVE) + + const_iv (OPEN_TREE_CLONE) + + const_iv (FSOPEN_CLOEXEC) + + const_iv (FSPICK_CLOEXEC) + const_iv (FSPICK_SYMLINK_NOFOLLOW) + const_iv (FSPICK_NO_AUTOMOUNT) + const_iv (FSPICK_EMPTY_PATH) + + const_iv (MOVE_MOUNT_F_SYMLINKS) + const_iv (MOVE_MOUNT_F_AUTOMOUNTS) + const_iv (MOVE_MOUNT_F_EMPTY_PATH) + const_iv (MOVE_MOUNT_T_SYMLINKS) + const_iv (MOVE_MOUNT_T_AUTOMOUNTS) + const_iv (MOVE_MOUNT_T_EMPTY_PATH) + + /* waitid */ + const_iv (P_PID) + const_iv (P_PIDFD) + const_iv (P_PGID) + const_iv (P_ALL) + + const_iv (FSCONFIG_SET_FLAG) + const_iv (FSCONFIG_SET_STRING) + const_iv (FSCONFIG_SET_BINARY) + const_iv (FSCONFIG_SET_PATH) + const_iv (FSCONFIG_SET_PATH_EMPTY) + const_iv (FSCONFIG_SET_FD) + const_iv (FSCONFIG_CMD_CREATE) + const_iv (FSCONFIG_CMD_RECONFIGURE) + + const_iv (MOUNT_ATTR_RDONLY) + const_iv (MOUNT_ATTR_NOSUID) + const_iv (MOUNT_ATTR_NODEV) + const_iv (MOUNT_ATTR_NOEXEC) + const_iv (MOUNT_ATTR__ATIME) + const_iv (MOUNT_ATTR_RELATIME) + const_iv (MOUNT_ATTR_NOATIME) + const_iv (MOUNT_ATTR_STRICTATIME) + const_iv (MOUNT_ATTR_NODIRATIME) + + /* sys/mount.h */ + const_iv (MS_RDONLY) + const_iv (MS_NOSUID) + const_iv (MS_NODEV) + const_iv (MS_NOEXEC) + const_iv (MS_SYNCHRONOUS) + const_iv (MS_REMOUNT) + const_iv (MS_MANDLOCK) + const_iv (MS_DIRSYNC) + const_iv (MS_NOATIME) + const_iv (MS_NODIRATIME) + const_iv (MS_BIND) + const_iv (MS_MOVE) + const_iv (MS_REC) + const_iv (MS_SILENT) + const_iv (MS_POSIXACL) + const_iv (MS_UNBINDABLE) + const_iv (MS_PRIVATE) + const_iv (MS_SLAVE) + const_iv (MS_SHARED) + const_iv (MS_RELATIME) + const_iv (MS_KERNMOUNT) + const_iv (MS_I_VERSION) + const_iv (MS_STRICTATIME) + const_iv (MS_LAZYTIME) + const_iv (MS_ACTIVE) + const_iv (MS_NOUSER) + const_iv (MS_RMT_MASK) + const_iv (MS_MGC_VAL) + const_iv (MS_MGC_MSK) + + const_iv (MNT_FORCE) + const_iv (MNT_DETACH) + const_iv (MNT_EXPIRE) + const_iv (UMOUNT_NOFOLLOW) + + const_iv (BLKROSET) + const_iv (BLKROGET) + const_iv (BLKRRPART) + const_iv (BLKGETSIZE) + const_iv (BLKFLSBUF) + const_iv (BLKRASET) + const_iv (BLKRAGET) + const_iv (BLKFRASET) + const_iv (BLKFRAGET) + const_iv (BLKSECTSET) + const_iv (BLKSECTGET) + const_iv (BLKSSZGET) + const_iv (BLKBSZGET) + const_iv (BLKBSZSET) + const_iv (BLKGETSIZE64) + /* these are libeio constants, and are independent of gendef0 */ const_eio (SEEK_SET) const_eio (SEEK_CUR) @@ -2530,7 +2692,7 @@ XPUSHs (retval); } -int +ssize_t splice (aio_rfd rfh, SV *off_in, aio_wfd wfh, SV *off_out, size_t length, unsigned int flags) CODE: { @@ -2548,7 +2710,7 @@ OUTPUT: RETVAL -int +ssize_t tee (aio_rfd rfh, aio_wfd wfh, size_t length, unsigned int flags) CODE: #if HAVE_LINUX_SPLICE @@ -2601,6 +2763,58 @@ } void +pidfd_open (int pid, unsigned int flags = 0) + PPCODE: +{ + /*GENDEF0_SYSCALL(pidfd_open,434)*/ + int fd = syscall (SYS_pidfd_open, pid, flags); + XPUSHs (newmortalFH (fd, O_RDWR)); +} + +int +pidfd_send_signal (SV *pidfh, int sig, SV *siginfo = &PL_sv_undef, unsigned int flags = 0) + PPCODE: +{ + int res; +#if HAVE_SIGINFO_T + siginfo_t si = { 0 }; + + if (SvOK (siginfo)) + { + HV *hv; + SV **svp; + + if (!SvROK (siginfo) || SvTYPE (SvRV (siginfo)) != SVt_PVHV) + croak ("siginfo argument must be a hashref with 'code', 'pid', 'uid' and 'value_int' or 'value_ptr' members, caught"); + + hv = (HV *)SvRV (siginfo); + + if ((svp = hv_fetchs (hv, "code" , 0))) si.si_code = SvIV (*svp); + if ((svp = hv_fetchs (hv, "pid" , 0))) si.si_pid = SvIV (*svp); + if ((svp = hv_fetchs (hv, "uid" , 0))) si.si_uid = SvIV (*svp); + if ((svp = hv_fetchs (hv, "value_int", 0))) si.si_value.sival_int = SvIV (*svp); + if ((svp = hv_fetchs (hv, "value_ptr", 0))) si.si_value.sival_ptr = (void *)SvIV (*svp); + } + + /*GENDEF0_SYSCALL(pidfd_send_signal,424)*/ + res = syscall (SYS_pidfd_send_signal, s_fileno_croak (pidfh, 0), sig, SvOK (siginfo) ? &si : 0, flags); +#else + res = (errno = ENOSYS, -1); +#endif + + XPUSHs (sv_2mortal (newSViv (res))); +} + +void +pidfd_getfd (SV *pidfh, int targetfd, unsigned int flags = 0) + PPCODE: +{ + /*GENDEF0_SYSCALL(pidfd_getfd,438)*/ + int fd = syscall (SYS_pidfd_getfd, s_fileno_croak (pidfh, 0), targetfd, flags); + XPUSHs (newmortalFH (fd, O_RDWR)); +} + +void eventfd (unsigned int initval = 0, int flags = 0) PPCODE: { @@ -2674,12 +2888,12 @@ } void -memfd_create (SV8 *pathname, int flags = 0) +memfd_create (octet_string pathname, int flags = 0) PPCODE: { int fd; #if HAVE_MEMFD_CREATE - fd = memfd_create (SvPVbyte_nolen (pathname), flags); + fd = memfd_create (pathname, flags); #else fd = (errno = ENOSYS, -1); #endif @@ -2687,6 +2901,55 @@ XPUSHs (newmortalFH (fd, O_RDWR)); } +int +fexecve (SV *fh, SV *args, SV *envs = &PL_sv_undef) + CODE: +{ + int fd = PerlIO_fileno (IoIFP (sv_2io (fh))); + char **envp, **argv; + argv = extract_stringvec (args, "IO::AIO::fexecve: args must be an array of strings"); + if (!SvOK (envs)) + { + extern char **environ; + envp = environ; + } + else + envp = extract_stringvec (envs, "IO::AIO::fexecve: envs must be an array of strings"); +#if _POSIX_VERSION >= 200809L + RETVAL = fexecve (fd, argv, envp); +#else + RETVAL = (errno = ENOSYS, -1); +#endif +} + OUTPUT: RETVAL + +int +mount (octet_string special, octet_string path, octet_string fstype, UV flags = 0, octet_string_ornull data = 0) + CODE: +#if HAVE_MOUNT + RETVAL = mount (special, path, fstype, flags, data); +#else + RETVAL = (errno = ENOSYS, -1); +#endif + OUTPUT: RETVAL + +int +umount (octet_string path, int flags = 0) + CODE: + if (flags) +#if HAVE_UMOUNT2 + RETVAL = umount2 (path, flags); +#else + RETVAL = (errno = ENOSYS, -1); +#endif + else +#if HAVE_MOUNT + RETVAL = umount (path); +#else + RETVAL = (errno = ENOSYS, -1); +#endif + OUTPUT: RETVAL + UV get_fdlimit () CODE: @@ -2729,7 +2992,7 @@ if (errno == EPERM) { - /* setlimit failed with EPERM - maybe we can't raise the hardlimit, or maybe */ + /* setrlimit failed with EPERM - maybe we can't raise the hardlimit, or maybe */ /* our limit overflows a system-wide limit */ /* try an adaptive algorithm, but do not lower the hardlimit */ rl.rlim_max = 0; @@ -2738,7 +3001,7 @@ rl.rlim_max |= bit; rl.rlim_cur = rl.rlim_max; - /* nevr decrease the hard limit */ + /* never decrease the hard limit */ if (rl.rlim_max < orig_rlim_max) break;