Stxxl  1.4.0
io/ufs_file_base.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines