diff options
author | Adam Mitz <mitza@ociweb.com> | 2015-11-12 15:59:58 -0600 |
---|---|---|
committer | Adam Mitz <mitza@ociweb.com> | 2015-11-12 15:59:58 -0600 |
commit | 3910f0188c0363b6c8b200f2bc2da9b9bc01c35f (patch) | |
tree | 8a3542b3bb638d723f8786e80fb0f72af7cde462 /ACE/ace/OS_NS_sys_sendfile.cpp | |
parent | 52f30d9ddbfeac44a5197732ac65ee2c1ffadc39 (diff) | |
download | ATCD-3910f0188c0363b6c8b200f2bc2da9b9bc01c35f.tar.gz |
In sendfile_emulation(), fall back on read() if the descriptor is for a file that can't be used with mmap().
Diffstat (limited to 'ACE/ace/OS_NS_sys_sendfile.cpp')
-rw-r--r-- | ACE/ace/OS_NS_sys_sendfile.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/ACE/ace/OS_NS_sys_sendfile.cpp b/ACE/ace/OS_NS_sys_sendfile.cpp index 03928ea21c1..33839acc660 100644 --- a/ACE/ace/OS_NS_sys_sendfile.cpp +++ b/ACE/ace/OS_NS_sys_sendfile.cpp @@ -11,13 +11,17 @@ # include "ace/OS_NS_sys_sendfile.inl" #endif /* ACE_HAS_INLINED_OSCALLS */ +#include "ace/Malloc_Base.h" +#include "ace/OS_Memory.h" +#include "ace/os_include/os_errno.h" + ACE_BEGIN_VERSIONED_NAMESPACE_DECL #if defined ACE_HAS_SENDFILE && ACE_HAS_SENDFILE == 0 ssize_t ACE_OS::sendfile_emulation (ACE_HANDLE out_fd, ACE_HANDLE in_fd, - off_t * offset, + off_t *offset, size_t count) { // @@ Is it possible to inline a call to ::TransmitFile() on @@ -26,10 +30,24 @@ ACE_OS::sendfile_emulation (ACE_HANDLE out_fd, // @@ We may want set up a signal lease (or oplock) if supported by // the platform so that we don't get a bus error if the mmap()ed // file is truncated. - void * const buf = - ACE_OS::mmap (0, count, PROT_READ, MAP_SHARED, in_fd, *offset); + void *buf = ACE_OS::mmap (0, count, PROT_READ, MAP_SHARED, in_fd, *offset); + const bool use_read = buf == MAP_FAILED && errno == ENODEV; + ACE_OFF_T prev_pos; - if (buf == MAP_FAILED) + if (use_read) + { +# ifdef ACE_HAS_ALLOC_HOOKS + ACE_ALLOCATOR_RETURN (buf, + ACE_Allocator::instance ()->malloc (count), -1); +# else + ACE_NEW_RETURN (buf, char[count], -1); +# endif + prev_pos = ACE_OS::lseek (in_fd, 0, SEEK_CUR); + if (ACE_OS::lseek (in_fd, *offset, SEEK_SET) == -1 + || ACE_OS::read (in_fd, buf, count) == -1) + return -1; + } + else if (buf == MAP_FAILED) return -1; #if defined (ACE_WIN32) || defined (HPUX) @@ -39,7 +57,17 @@ ACE_OS::sendfile_emulation (ACE_HANDLE out_fd, ssize_t const r = ACE_OS::write (out_fd, buf, count); #endif /* ACE_WIN32 */ - (void) ACE_OS::munmap (buf, count); + if (use_read) + { + ACE_OS::lseek (in_fd, prev_pos, SEEK_SET); +# ifdef ACE_HAS_ALLOC_HOOKS + ACE_Allocator::instance ()->free (buf); +# else + delete[] static_cast<char *> (buf); +# endif + } + else + (void) ACE_OS::munmap (buf, count); if (r > 0) *offset += static_cast<off_t> (r); |