Skip to content

Commit

Permalink
Merge pull request #2354 from rowanborder/pr_2341_mac_osx_fix
Browse files Browse the repository at this point in the history
Fix for ::posix_fallocate on Mac OSX and add header with low level I/O helpers
  • Loading branch information
taketwo authored Jun 22, 2018
2 parents b81431b + f4c4ece commit 6cae3f2
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 157 deletions.
89 changes: 28 additions & 61 deletions io/include/pcl/io/impl/pcd_io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,43 +44,11 @@
#include <fcntl.h>
#include <string>
#include <stdlib.h>
#include <pcl/io/boost.h>
#include <pcl/console/print.h>
#include <pcl/io/boost.h>
#include <pcl/io/low_level_io.h>
#include <pcl/io/pcd_io.h>

#ifdef _WIN32
# include <io.h>
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif // WIN32_LEAN_AND_MEAN
# ifndef NOMINMAX
# define NOMINMAX
# endif // NOMINMAX
# include <windows.h>
# define pcl_open _open
# define pcl_close(fd) _close(fd)
# define pcl_lseek(fd,offset,origin) _lseek(fd,offset,origin)
# define pcl_read(fd,dest,size) _read(fd,dest,size)
/* ssize_t is also not available (copy/paste from MinGW) */
#ifdef _MSC_VER
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef int ssize_t;
#endif /* _WIN64 */
#endif /* _SSIZE_T_DEFINED */
#endif /* _MSC_VER */
#else
# include <sys/mman.h>
# define pcl_open open
# define pcl_close(fd) close(fd)
# define pcl_lseek(fd,offset,origin) lseek(fd,offset,origin)
# define pcl_read(fd,dest,size) ::read(fd,dest,size)
#endif

#include <pcl/io/lzf.h>

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -162,7 +130,7 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,
return (-1);
}
#else
int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int fd = io::raw_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0)
{
throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
Expand Down Expand Up @@ -207,20 +175,20 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,

#else
// Allocate disk space for the entire file to prevent bus errors.
if (::posix_fallocate (fd, 0, data_idx + data_size) != 0)
if (io::raw_fallocate (fd, data_idx + data_size) != 0)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
PCL_ERROR ("[pcl::PCDWriter::writeBinary] posix_fallocate errno: %d strerror: %s\n", errno, strerror (errno));

throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during posix_fallocate ()!");
return (-1);
}

char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
char *map = static_cast<char*> (::mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
return (-1);
Expand Down Expand Up @@ -252,9 +220,9 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,
#if _WIN32
UnmapViewOfFile (map);
#else
if (munmap (map, (data_idx + data_size)) == -1)
if (::munmap (map, (data_idx + data_size)) == -1)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
return (-1);
Expand All @@ -264,7 +232,7 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,
#if _WIN32
CloseHandle (h_native_file);
#else
pcl_close (fd);
io::raw_close (fd);
#endif
resetLockingPermissions (file_name, file_lock);
return (0);
Expand Down Expand Up @@ -294,7 +262,7 @@ pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name,
return (-1);
}
#else
int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int fd = io::raw_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0)
{
throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during open!");
Expand Down Expand Up @@ -391,7 +359,7 @@ pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name,
else
{
#if !_WIN32
pcl_close (fd);
io::raw_close (fd);
#endif
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during compression!");
Expand All @@ -406,20 +374,20 @@ pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name,

#else
// Allocate disk space for the entire file to prevent bus errors.
if (::posix_fallocate (fd, 0, compressed_final_size) != 0)
if (io::raw_fallocate (fd, compressed_final_size) != 0)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] posix_fallocate errno: %d strerror: %s\n", errno, strerror (errno));

throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during posix_fallocate ()!");
return (-1);
}

char *map = static_cast<char*> (mmap (0, compressed_final_size, PROT_WRITE, MAP_SHARED, fd, 0));
char *map = static_cast<char*> (::mmap (0, compressed_final_size, PROT_WRITE, MAP_SHARED, fd, 0));
if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during mmap ()!");
return (-1);
Expand All @@ -441,9 +409,9 @@ pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name,
#if _WIN32
UnmapViewOfFile (map);
#else
if (munmap (map, (compressed_final_size)) == -1)
if (::munmap (map, (compressed_final_size)) == -1)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during munmap ()!");
return (-1);
Expand All @@ -454,7 +422,7 @@ pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name,
#if _WIN32
CloseHandle (h_native_file);
#else
pcl_close (fd);
io::raw_close (fd);
#endif
resetLockingPermissions (file_name, file_lock);

Expand Down Expand Up @@ -666,7 +634,7 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,
return (-1);
}
#else
int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int fd = io::raw_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0)
{
throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
Expand Down Expand Up @@ -706,20 +674,20 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,

#else
// Allocate disk space for the entire file to prevent bus errors.
if (::posix_fallocate (fd, 0, data_idx + data_size) != 0)
if (io::raw_fallocate (fd, data_idx + data_size) != 0)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
PCL_ERROR ("[pcl::PCDWriter::writeBinary] posix_fallocate errno: %d strerror: %s\n", errno, strerror (errno));

throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during posix_fallocate ()!");
return (-1);
}

char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
char *map = static_cast<char*> (::mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
return (-1);
Expand Down Expand Up @@ -751,9 +719,9 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,
#if _WIN32
UnmapViewOfFile (map);
#else
if (munmap (map, (data_idx + data_size)) == -1)
if (::munmap (map, (data_idx + data_size)) == -1)
{
pcl_close (fd);
io::raw_close (fd);
resetLockingPermissions (file_name, file_lock);
throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
return (-1);
Expand All @@ -763,7 +731,7 @@ pcl::PCDWriter::writeBinary (const std::string &file_name,
#if _WIN32
CloseHandle(h_native_file);
#else
pcl_close (fd);
io::raw_close (fd);
#endif

resetLockingPermissions (file_name, file_lock);
Expand Down Expand Up @@ -944,11 +912,10 @@ pcl::PCDWriter::writeASCII (const std::string &file_name,
fs << result << "\n";
}
fs.close (); // Close file

resetLockingPermissions (file_name, file_lock);

return (0);
}

#endif //#ifndef PCL_IO_PCD_IO_H_

165 changes: 165 additions & 0 deletions io/include/pcl/io/low_level_io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2012-, Open Perception, Inc.
* Copyright (c) 2018 Fizyr BV. - https://fizyr.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

/**
* This file defines compatibility wrappers for low level I/O functions.
* Implemented as inlinable functions to prevent any performance overhead.
*/

#ifndef __PCL_IO_LOW_LEVEL_IO__
#define __PCL_IO_LOW_LEVEL_IO__

#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <io.h>
# include <windows.h>
# include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#else
# include <unistd.h>
# include <sys/mman.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/fcntl.h>
#endif

namespace pcl
{
namespace io
{
#ifdef _WIN32
inline int raw_open(const char * pathname, int flags, int mode)
{
return ::_open(pathname, flags, mode);
}

inline int raw_open(const char * pathname, int flags)
{
return ::_open(pathname, flags);
}

inline int raw_close(int fd)
{
return ::_close(fd);
}

inline int raw_lseek(int fd, long offset, int whence)
{
return ::_lseek(fd, offset, whence);
}

inline int raw_read(int fd, void * buffer, size_t count)
{
return ::_read(fd, buffer, count);
}

inline int raw_write(int fd, const void * buffer, size_t count)
{
return ::_write(fd, buffer, count);
}

inline int raw_fallocate(int fd, long len)
{
return ::_chsize(fd, len);
}
#else
inline int raw_open(const char * pathname, int flags, int mode)
{
return ::open(pathname, flags, mode);
}

inline int raw_open(const char * pathname, int flags)
{
return ::open(pathname, flags);
}

inline int raw_close(int fd)
{
return ::close(fd);
}

inline off_t raw_lseek(int fd, off_t offset, int whence)
{
return ::lseek(fd, offset, whence);
}

inline ssize_t raw_read(int fd, void * buffer, size_t count)
{
return ::read(fd, buffer, count);
}

inline ssize_t raw_write(int fd, const void * buffer, size_t count)
{
return ::write(fd, buffer, count);
}

# ifndef __APPLE__
inline int raw_fallocate(int fd, off_t len)
{
return ::posix_fallocate(fd, 0, len);
}
# else
inline int raw_fallocate(int fd, off_t len)
{
// Try to allocate contiguous space first.
::fstore_t store = {F_ALLOCATEALL | F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, len};
if (::fcntl(fd, F_PREALLOCATE, &store) < 0)
{
// Try fragmented if that failed.
store.fst_flags = F_ALLOCATEALL;
int ret = ::fcntl(fd, F_PREALLOCATE, &store);

// Bail if it still failed.
if (ret < 0) {
return ret;
}
}

// File could be larger than requested, so truncate.
return ::ftruncate(fd, len);
}
# endif // __APPLE__
#endif // _WIN32

}
}
#endif // __PCL_IO_LOW_LEVEL_IO__
Loading

0 comments on commit 6cae3f2

Please sign in to comment.