--- libeio/eio.c 2011/12/30 07:38:00 1.114 +++ libeio/eio.c 2012/04/24 18:47:50 1.120 @@ -1,7 +1,7 @@ /* * libeio implementation * - * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann + * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -210,7 +210,7 @@ #define D_NAME(entp) entp->d_name /* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */ - #if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ + #if __FreeBSD__ || __NetBSD__ || __OpenBSD__ #define _DIRENT_HAVE_D_TYPE /* sigh */ #define D_INO(de) (de)->d_fileno #define D_NAMLEN(de) (de)->d_namlen @@ -1034,8 +1034,7 @@ #if HAVE_SYS_SYNCFS res = (int)syscall (__NR_syncfs, (int)(fd)); #else - res = -1; - errno = ENOSYS; + res = EIO_ENOSYS (); #endif if (res < 0 && errno == ENOSYS && fd >= 0) @@ -1075,11 +1074,10 @@ static int eio__fallocate (int fd, int mode, off_t offset, size_t len) { -#if HAVE_FALLOCATE +#if HAVE_LINUX_FALLOCATE return fallocate (fd, mode, offset, len); #else - errno = ENOSYS; - return -1; + return EIO_ENOSYS (); #endif } @@ -1104,8 +1102,9 @@ FUBd; - errno = 0; - return count; + /* linux's readahead basically only fails for EBADF or EINVAL (not mmappable) */ + /* but not for e.g. EIO or eof, so we also never fail */ + return 0; } #endif @@ -1150,7 +1149,7 @@ if (sbytes) res = sbytes; -# elif defined (__APPLE__) +# elif defined __APPLE__ off_t sbytes = count; res = sendfile (ifd, ofd, offset, &sbytes, 0, 0); @@ -1187,8 +1186,7 @@ res = TransmitFile (TO_SOCKET (ofd), h, count, 0, 0, 0, 0); #else - res = -1; - errno = ENOSYS; + res = EIO_ENOSYS (); #endif /* we assume sendfile can copy at least 128mb in one go */ @@ -1384,6 +1382,20 @@ /*****************************************************************************/ /* requests implemented outside eio_execute, because they are so large */ +static void +eio__lseek (eio_req *req) +{ + /* this usually gets optimised away completely, or your compiler sucks, */ + /* or the whence constants really are not 0, 1, 2 */ + int whence = req->int2 == EIO_SEEK_SET ? SEEK_SET + : req->int2 == EIO_SEEK_CUR ? SEEK_CUR + : req->int2 == EIO_SEEK_END ? SEEK_END + : req->int2; + + req->offs = lseek (req->int1, req->offs, whence); + req->result = req->offs == (off_t)-1 ? -1 : 0; +} + /* result will always end up in tmpbuf, there is always space for adding a 0-byte */ static int eio__realpath (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) @@ -2230,8 +2242,6 @@ X_LOCK (wrklock); etp_worker_free (self); X_UNLOCK (wrklock); - - return 0; } /*****************************************************************************/ @@ -2316,6 +2326,7 @@ case EIO_WD_CLOSE: req->result = 0; eio_wd_close_sync (req->wd); break; + case EIO_SEEK: eio__lseek (req); break; case EIO_READ: ALLOC (req->size); req->result = req->offs >= 0 ? pread (req->int1, req->ptr2, req->size, req->offs) @@ -2481,8 +2492,7 @@ break; default: - errno = ENOSYS; - req->result = -1; + req->result = EIO_ENOSYS (); break; } @@ -2571,6 +2581,11 @@ REQ (EIO_READAHEAD); req->int1 = fd; req->offs = offset; req->size = length; SEND; } +eio_req *eio_seek (int fd, off_t offset, int whence, int pri, eio_cb cb, void *data) +{ + REQ (EIO_SEEK); req->int1 = fd; req->offs = offset; req->int2 = whence; SEND; +} + eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data) { REQ (EIO_READ); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND;