--- IO-AIO/AIO.xs 2008/10/13 10:38:17 1.132 +++ IO-AIO/AIO.xs 2009/06/03 12:24:49 1.140 @@ -314,9 +314,13 @@ break; case EIO_READ: - SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); - *SvEND (req->sv2) = 0; - PUSHs (sv_2mortal (newSViv (req->result))); + { + SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); + *SvEND (req->sv2) = 0; + SvPOK_only (req->sv2); + SvSETMAGIC (req->sv2); + PUSHs (sv_2mortal (newSViv (req->result))); + } break; case EIO_DUP2: @@ -501,7 +505,18 @@ \ if (GIMME_V != G_VOID) \ XPUSHs (req_sv (req, AIO_REQ_KLASS)); - + +static int +extract_fd (SV *fh, int wr) +{ + int fd = PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh))); + + if (fd < 0) + croak ("illegal fh argument, either not an OS file or read/write mode mismatch"); + + return fd; +} + MODULE = IO::AIO PACKAGE = IO::AIO PROTOTYPES: ENABLE @@ -511,6 +526,7 @@ stash = gv_stashpv ("IO::AIO", 1); newCONSTSUB (stash, "EXDEV", newSViv (EXDEV)); + newCONSTSUB (stash, "ENOSYS", newSViv (ENOSYS)); newCONSTSUB (stash, "O_RDONLY", newSViv (O_RDONLY)); newCONSTSUB (stash, "O_WRONLY", newSViv (O_WRONLY)); newCONSTSUB (stash, "O_CREAT", newSViv (O_CREAT)); @@ -518,6 +534,10 @@ #ifndef _WIN32 newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); #endif + newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); + newCONSTSUB (stash, "SYNC_FILE_RANGE_WAIT_BEFORE", newSViv (EIO_SYNC_FILE_RANGE_WAIT_BEFORE)); + newCONSTSUB (stash, "SYNC_FILE_RANGE_WRITE" , newSViv (EIO_SYNC_FILE_RANGE_WRITE)); + newCONSTSUB (stash, "SYNC_FILE_RANGE_WAIT_AFTER" , newSViv (EIO_SYNC_FILE_RANGE_WAIT_AFTER)); create_respipe (); @@ -588,11 +608,30 @@ aio_fdatasync = EIO_FDATASYNC PPCODE: { + int fd = extract_fd (fh, 0); dREQ; req->type = ix; req->sv1 = newSVsv (fh); - req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); + req->int1 = fd; + + REQ_SEND (req); +} + +void +aio_sync_file_range (SV *fh, SV *offset, SV *nbytes, IV flags, SV *callback=&PL_sv_undef) + PROTOTYPE: $$$$;$ + PPCODE: +{ + int fd = extract_fd (fh, 0); + dREQ; + + req->type = EIO_SYNC_FILE_RANGE; + req->sv1 = newSVsv (fh); + req->int1 = fd; + req->offs = SvVAL64 (offset); + req->size = SvVAL64 (nbytes); + req->int2 = flags; REQ_SEND (req); } @@ -603,6 +642,7 @@ PPCODE: { static int close_pipe = -1; /* dummy fd to close fds via dup2 */ + int fd = extract_fd (fh, 0); dREQ; if (close_pipe < 0) @@ -620,7 +660,7 @@ req->type = EIO_DUP2; req->int1 = close_pipe; req->sv2 = newSVsv (fh); - req->int2 = PerlIO_fileno (IoIFP (sv_2io (fh))); + req->int2 = fd; REQ_SEND (req); } @@ -634,12 +674,10 @@ PPCODE: { STRLEN svlen; + int fd = extract_fd (fh, ix == EIO_WRITE); char *svptr = SvPVbyte (data, svlen); UV len = SvUV (length); - SvUPGRADE (data, SVt_PV); - SvPOK_on (data); - if (dataoffset < 0) dataoffset += svlen; @@ -654,20 +692,17 @@ } else { - /* read: grow scalar as necessary */ + /* read: check type and grow scalar as necessary */ + SvUPGRADE (data, SVt_PV); svptr = SvGROW (data, len + dataoffset + 1); } - if (len < 0) - croak ("length must not be negative"); - { dREQ; req->type = ix; req->sv1 = newSVsv (fh); - req->int1 = PerlIO_fileno (ix == EIO_READ ? IoIFP (sv_2io (fh)) - : IoOFP (sv_2io (fh))); + req->int1 = fd; req->offs = SvOK (offset) ? SvVAL64 (offset) : -1; req->size = len; req->sv2 = SvREFCNT_inc (data); @@ -704,13 +739,15 @@ PROTOTYPE: $$$$;$ PPCODE: { + int ifd = extract_fd (in_fh , 0); + int ofd = extract_fd (out_fh, 0); dREQ; req->type = EIO_SENDFILE; req->sv1 = newSVsv (out_fh); - req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh))); + req->int1 = ofd; req->sv2 = newSVsv (in_fh); - req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh))); + req->int2 = ifd; req->offs = SvVAL64 (in_offset); req->size = length; @@ -722,11 +759,12 @@ PROTOTYPE: $$$;$ PPCODE: { + int fd = extract_fd (fh, 0); dREQ; req->type = EIO_READAHEAD; req->sv1 = newSVsv (fh); - req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); + req->int1 = fd; req->offs = SvVAL64 (offset); req->size = length;