Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * io/ufs_file_base.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002, 2005, 2008 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008 Ilja Andronov <sni4ok@yandex.ru> 00008 * Copyright (C) 2008-2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00009 * Copyright (C) 2009 Johannes Singler <singler@ira.uka.de> 00010 * 00011 * Distributed under the Boost Software License, Version 1.0. 00012 * (See accompanying file LICENSE_1_0.txt or copy at 00013 * http://www.boost.org/LICENSE_1_0.txt) 00014 **************************************************************************/ 00015 00016 #include <stxxl/bits/io/ufs_file_base.h> 00017 #include <stxxl/bits/common/error_handling.h> 00018 00019 #ifdef BOOST_MSVC 00020 #include <windows.h> 00021 #else 00022 #include <unistd.h> 00023 #include <fcntl.h> 00024 #endif 00025 #include <cstdio> 00026 00027 00028 __STXXL_BEGIN_NAMESPACE 00029 00030 00031 const char * ufs_file_base::io_type() const 00032 { 00033 return "ufs_base"; 00034 } 00035 00036 ufs_file_base::ufs_file_base( 00037 const std::string & filename, 00038 int mode) : file_des(-1), mode_(mode), filename(filename) 00039 { 00040 int flags = 0; 00041 00042 if (mode & RDONLY) 00043 { 00044 flags |= O_RDONLY; 00045 } 00046 00047 if (mode & WRONLY) 00048 { 00049 flags |= O_WRONLY; 00050 } 00051 00052 if (mode & RDWR) 00053 { 00054 flags |= O_RDWR; 00055 } 00056 00057 if (mode & CREAT) 00058 { 00059 flags |= O_CREAT; 00060 } 00061 00062 if (mode & TRUNC) 00063 { 00064 flags |= O_TRUNC; 00065 } 00066 00067 #ifndef STXXL_DIRECT_IO_OFF 00068 if (mode & DIRECT) 00069 { 00070 flags |= O_DIRECT; 00071 } 00072 #endif 00073 00074 if (mode & SYNC) 00075 { 00076 flags |= O_RSYNC; 00077 flags |= O_DSYNC; 00078 flags |= O_SYNC; 00079 } 00080 00081 #ifdef BOOST_MSVC 00082 flags |= O_BINARY; // the default in MS is TEXT mode 00083 #endif 00084 00085 #ifdef BOOST_MSVC 00086 const int perms = S_IREAD | S_IWRITE; 00087 #else 00088 const int perms = S_IREAD | S_IWRITE | S_IRGRP | S_IWGRP; 00089 #endif 00090 00091 if ((file_des = ::open(filename.c_str(), flags, perms)) < 0) 00092 STXXL_THROW2(io_error, "::open() rc=" << file_des << " path=" << filename << " flags=" << flags); 00093 00094 if (!(mode & NO_LOCK)) 00095 { 00096 lock(); 00097 } 00098 } 00099 00100 ufs_file_base::~ufs_file_base() 00101 { 00102 close(); 00103 } 00104 00105 void ufs_file_base::close() 00106 { 00107 scoped_mutex_lock fd_lock(fd_mutex); 00108 00109 if (file_des == -1) 00110 return; 00111 00112 if (::close(file_des) < 0) 00113 stxxl_function_error(io_error); 00114 00115 file_des = -1; 00116 } 00117 00118 void ufs_file_base::lock() 00119 { 00120 #ifdef BOOST_MSVC 00121 // not yet implemented 00122 #else 00123 scoped_mutex_lock fd_lock(fd_mutex); 00124 struct flock lock_struct; 00125 lock_struct.l_type = (mode_ & RDONLY) ? F_RDLCK : F_RDLCK | F_WRLCK; 00126 lock_struct.l_whence = SEEK_SET; 00127 lock_struct.l_start = 0; 00128 lock_struct.l_len = 0; // lock all bytes 00129 if ((::fcntl(file_des, F_SETLK, &lock_struct)) < 0) 00130 STXXL_THROW2(io_error, "::fcntl(,F_SETLK,) path=" << filename << " fd=" << file_des); 00131 #endif 00132 } 00133 00134 file::offset_type ufs_file_base::_size() 00135 { 00136 #ifdef BOOST_MSVC 00137 struct _stat64 st; 00138 stxxl_check_ge_0(_fstat64(file_des, &st), io_error); 00139 #else 00140 struct stat st; 00141 stxxl_check_ge_0(::fstat(file_des, &st), io_error); 00142 #endif 00143 return st.st_size; 00144 } 00145 00146 file::offset_type ufs_file_base::size() 00147 { 00148 scoped_mutex_lock fd_lock(fd_mutex); 00149 return _size(); 00150 } 00151 00152 void ufs_file_base::set_size(offset_type newsize) 00153 { 00154 scoped_mutex_lock fd_lock(fd_mutex); 00155 offset_type cur_size = _size(); 00156 00157 if (!(mode_ & RDONLY)) 00158 { 00159 #ifdef BOOST_MSVC 00160 HANDLE hfile; 00161 stxxl_check_ge_0(hfile = (HANDLE) ::_get_osfhandle(file_des), io_error); 00162 00163 LARGE_INTEGER desired_pos; 00164 desired_pos.QuadPart = newsize; 00165 00166 if (!SetFilePointerEx(hfile, desired_pos, NULL, FILE_BEGIN)) 00167 stxxl_win_lasterror_exit("SetFilePointerEx in ufs_file_base::set_size(..) oldsize=" << cur_size << 00168 " newsize=" << newsize << " ", io_error); 00169 00170 if (!SetEndOfFile(hfile)) 00171 stxxl_win_lasterror_exit("SetEndOfFile oldsize=" << cur_size << 00172 " newsize=" << newsize << " ", io_error); 00173 #else 00174 stxxl_check_ge_0(::ftruncate(file_des, newsize), io_error); 00175 #endif 00176 } 00177 00178 #ifndef BOOST_MSVC 00179 if (newsize > cur_size) 00180 stxxl_check_ge_0(::lseek(file_des, newsize - 1, SEEK_SET), io_error); 00181 #endif 00182 } 00183 00184 void ufs_file_base::remove() 00185 { 00186 close(); 00187 ::remove(filename.c_str()); 00188 } 00189 00190 void ufs_file_base::unlink() 00191 { 00192 ::remove(filename.c_str()); 00193 } 00194 00195 __STXXL_END_NAMESPACE 00196 // vim: et:ts=4:sw=4