--- IO-AIO/AIO.xs 2011/02/15 03:21:41 1.181 +++ IO-AIO/AIO.xs 2011/07/17 04:20:04 1.188 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -25,61 +24,57 @@ /* perl namespace pollution */ #undef VERSION +/* perl stupidly overrides readdir and maybe others */ +/* with thread-unsafe versions, imagine that :( */ +#undef readdir +#undef opendir +#undef closedir + #ifdef _WIN32 -# define EIO_STRUCT_DIRENT Direntry_t -# undef malloc -# undef free - -// perl overrides all those nice win32 functions -# undef open -# undef read -# undef write -# undef send -# undef recv -# undef stat -# undef fstat -# define lstat stat -# undef truncate -# undef ftruncate -# undef open -# undef close -# undef unlink -# undef rmdir -# undef rename -# undef lseek - -# define chown(a,b,c) (errno = ENOSYS, -1) -# define fchown(a,b,c) (errno = ENOSYS, -1) -# define fchmod(a,b) (errno = ENOSYS, -1) -# define symlink(a,b) (errno = ENOSYS, -1) -# define readlink(a,b,c) (errno = ENOSYS, -1) -# define mknod(a,b,c) (errno = ENOSYS, -1) -# define truncate(a,b) (errno = ENOSYS, -1) -# define ftruncate(fd,o) chsize ((fd), (o)) -# define fsync(fd) _commit (fd) -# define opendir(fd) (errno = ENOSYS, 0) -# define readdir(fd) (errno = ENOSYS, -1) -# define closedir(fd) (errno = ENOSYS, -1) -# define mkdir(a,b) mkdir (a) + #define EIO_STRUCT_DIRENT Direntry_t + #undef malloc + #undef free + + // perl overrides all those nice libc functions + #undef open + #undef read + #undef write + #undef send + #undef recv + #undef stat + #undef lstat + #undef fstat + #undef truncate + #undef ftruncate + #undef open + #undef link + #undef close + #undef unlink + #undef mkdir + #undef rmdir + #undef rename + #undef lseek + #undef opendir + #undef readdir + #undef closedir + #undef chmod + #undef fchmod + #undef dup + #undef dup2 + #undef abort + #undef pipe #else -# include -# include -# include -# include -# include -# define EIO_STRUCT_DIRENT struct dirent + #include + #include + #include + #include + #include #endif -/* perl stupidly overrides readdir and maybe others */ -/* with thread-unsafe versions, imagine that :( */ -#undef readdir -#undef opendir -#undef closedir - #define EIO_STRUCT_STAT Stat_t /* use NV for 32 bit perls as it allows larger offsets */ @@ -123,6 +118,59 @@ #include "libeio/config.h" #include "libeio/eio.h" +static int req_invoke (eio_req *req); +#define EIO_FINISH(req) req_invoke (req) +static void req_destroy (eio_req *grp); +#define EIO_DESTROY(req) req_destroy (req) + +#include "libeio/eio.c" + +/* Linux/others */ +#ifndef O_ASYNC +# define O_ASYNC 0 +#endif +#ifndef O_DIRECT +# define O_DIRECT 0 +#endif +#ifndef O_NOATIME +# define O_NOATIME 0 +#endif + +/* POSIX */ +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif +#ifndef O_NOCTTY +# define O_NOCTTY 0 +#endif +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif +#ifndef O_EXEC +# define O_EXEC 0 +#endif +#ifndef O_SEARCH +# define O_SEARCH 0 +#endif +#ifndef O_DIRECTORY +# define O_DIRECTORY 0 +#endif +#ifndef O_DSYNC +# define O_DSYNC 0 +#endif +#ifndef O_RSYNC +# define O_RSYNC 0 +#endif +#ifndef O_SYNC +# define O_SYNC 0 +#endif +#ifndef O_TTY_INIT +# define O_TTY_INIT 0 +#endif + #ifndef POSIX_FADV_NORMAL # define POSIX_FADV_NORMAL 0 #endif @@ -179,6 +227,12 @@ # define PROT_EXEC 0 #endif +#ifndef ST_RDONLY +# define ST_RDONLY 0 +#endif +#ifndef ST_NOSUID +# define ST_NOSUID 0 +#endif #ifndef ST_NODEV # define ST_NODEV 0 #endif @@ -272,17 +326,10 @@ # define PAGESIZE sysconf (_SC_PAGESIZE) #endif -static int req_invoke (eio_req *req); -#define EIO_FINISH(req) req_invoke (req) -static void req_destroy (eio_req *grp); -#define EIO_DESTROY(req) req_destroy (req) - enum { FLAG_SV2_RO_OFF = 0x40, /* data was set readonly */ }; -#include "libeio/eio.c" - typedef eio_req *aio_req; typedef eio_req *aio_req_ornot; @@ -497,6 +544,7 @@ { SV *rv = &PL_sv_undef; +#ifndef _WIN32 if (req->result >= 0) { EIO_STRUCT_STATVFS *f = EIO_STATVFS_BUF (req); @@ -516,6 +564,7 @@ hv_store (hv, "flag" , sizeof ("flag" ) - 1, newSVval64 (f->f_flag ), 0); hv_store (hv, "namemax", sizeof ("namemax") - 1, newSVval64 (f->f_namemax), 0); } +#endif PUSHs (rv); } @@ -541,6 +590,7 @@ break; case EIO_READLINK: + case EIO_REALPATH: if (req->result > 0) PUSHs (sv_2mortal (newSVpvn (req->ptr2, req->result))); break; @@ -550,6 +600,7 @@ case EIO_FSTAT: PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT; PL_laststatval = req->result; + /* if compilation fails here then perl's Stat_t is not struct _stati64 */ PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); PUSHs (sv_result); break; @@ -611,8 +662,6 @@ static void req_cancel_subs (aio_req grp) { - aio_req sub; - if (grp->type != EIO_GROUP) return; @@ -622,8 +671,7 @@ eio_grp_cancel (grp); } -static void -create_respipe (void) +static void create_respipe (void) { if (s_epipe_renew (&respipe)) croak ("IO::AIO: unable to initialize result pipe"); @@ -687,8 +735,7 @@ #define MMAP_MAGIC PERL_MAGIC_ext -static int -mmap_free (pTHX_ SV *sv, MAGIC *mg) +static int mmap_free (pTHX_ SV *sv, MAGIC *mg) { int old_errno = errno; munmap (mg->mg_ptr, (size_t)mg->mg_obj); @@ -714,8 +761,7 @@ /*****************************************************************************/ -static SV * -get_cb (SV *cb_sv) +static SV * get_cb (SV *cb_sv) { SvGETMAGIC (cb_sv); return SvOK (cb_sv) ? s_get_cv_croak (cb_sv) : 0; @@ -767,6 +813,22 @@ const_iv (O_EXCL) const_iv (O_APPEND) + const_iv (O_ASYNC) + const_iv (O_DIRECT) + const_iv (O_NOATIME) + + const_iv (O_CLOEXEC) + const_iv (O_NOCTTY) + const_iv (O_NOFOLLOW) + const_iv (O_NONBLOCK) + const_iv (O_EXEC) + const_iv (O_SEARCH) + const_iv (O_DIRECTORY) + const_iv (O_DSYNC) + const_iv (O_RSYNC) + const_iv (O_SYNC) + const_iv (O_TTY_INIT) + const_iv (S_IFIFO) const_iv (S_IFCHR) const_iv (S_IFBLK) @@ -833,6 +895,8 @@ const_eio (SYNC_FILE_RANGE_WRITE) const_eio (SYNC_FILE_RANGE_WAIT_AFTER) + const_eio (FALLOC_FL_KEEP_SIZE) + const_eio (READDIR_DENTS) const_eio (READDIR_DIRS_FIRST) const_eio (READDIR_STAT_ORDER) @@ -959,27 +1023,50 @@ } void +aio_fallocate (SV *fh, int mode, off_t offset, size_t len, SV *callback=&PL_sv_undef) + PPCODE: +{ + int fd = s_fileno_croak (fh, 0); + dREQ; + + req->type = EIO_FALLOCATE; + req->sv1 = newSVsv (fh); + req->int1 = fd; + req->int2 = mode; + req->offs = offset; + req->size = len; + + REQ_SEND (req); +} + +void aio_close (SV *fh, SV *callback=&PL_sv_undef) PPCODE: { - static int close_pipe = -1; /* dummy fd to close fds via dup2 */ + static int close_fd = -1; /* dummy fd to close fds via dup2 */ int fd = s_fileno_croak (fh, 0); dREQ; - if (close_pipe < 0) + if (expect_false (close_fd < 0)) { int pipefd [2]; - if (pipe (pipefd) < 0 - || close (pipefd [1]) < 0 - || fcntl (pipefd [0], F_SETFD, FD_CLOEXEC) < 0) + if ( +#ifdef _WIN32 + _pipe (pipefd, 1, _O_BINARY) < 0 +#else + pipe (pipefd) < 0 + || fcntl (pipefd [0], F_SETFD, FD_CLOEXEC) < 0 +#endif + || close (pipefd [1]) < 0 + ) abort (); /*D*/ - close_pipe = pipefd [0]; + close_fd = pipefd [0]; } req->type = EIO_DUP2; - req->int1 = close_pipe; + req->int1 = close_fd; req->sv2 = newSVsv (fh); req->int2 = fd; @@ -1041,12 +1128,14 @@ void aio_readlink (SV8 *path, SV *callback=&PL_sv_undef) + ALIAS: + aio_readlink = EIO_READLINK + aio_realpath = EIO_REALPATH PPCODE: { - SV *data; dREQ; - req->type = EIO_READLINK; + req->type = ix; req->sv1 = newSVsv (path); req->ptr1 = SvPVbyte_nolen (req->sv1);