00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/File.hpp"
00041 #include "blocxx/Logger.hpp"
00042 #include "blocxx/Format.hpp"
00043
00044 #ifdef BLOCXX_WIN32
00045 #include <io.h>
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 #include <memory.h>
00049 #else
00050 #include <fcntl.h>
00051 #ifdef BLOCXX_HAVE_UNISTD_H
00052 #include <unistd.h>
00053 #endif
00054 #endif
00055
00056
00057 namespace BLOCXX_NAMESPACE
00058 {
00059 #ifdef BLOCXX_WIN32
00060 namespace
00061 {
00063
00064 int
00065 doLock(HANDLE hFile, bool doWait, DWORD lockType)
00066 {
00067 if (hFile == INVALID_HANDLE_VALUE)
00068 {
00069 return -1;
00070 }
00071
00072 DWORD flags = lockType;
00073 if (!doWait)
00074 {
00075 flags |= LOCKFILE_FAIL_IMMEDIATELY;
00076 }
00077
00078 OVERLAPPED ov;
00079 memset(&ov, 0, sizeof(ov));
00080 if (!LockFileEx(hFile, flags, 0, 0xffffffff,
00081 0xffffffff, &ov))
00082 {
00083 return -1;
00084 }
00085
00086 return 0;
00087 }
00088
00089 }
00090
00092 File::File(const File& x) : m_hdl(BLOCXX_INVALID_FILEHANDLE)
00093 {
00094 if( x.m_hdl != BLOCXX_INVALID_FILEHANDLE )
00095 {
00096 DuplicateHandle(GetCurrentProcess(), x.m_hdl, GetCurrentProcess(),
00097 &m_hdl , 0, FALSE, DUPLICATE_SAME_ACCESS);
00098 }
00099 }
00101 int
00102 File::getLock(ELockType type)
00103 {
00104 return doLock(m_hdl, true, type == E_WRITE_LOCK ?
00105 LOCKFILE_EXCLUSIVE_LOCK : 0);
00106 }
00108 int
00109 File::tryLock(ELockType type)
00110 {
00111 return doLock(m_hdl, false, type == E_WRITE_LOCK ?
00112 LOCKFILE_EXCLUSIVE_LOCK : 0);
00113 }
00115 int
00116 File::unlock()
00117 {
00118 if (m_hdl == INVALID_HANDLE_VALUE)
00119 {
00120 return -1;
00121 }
00122
00123 OVERLAPPED ov;
00124 memset(&ov, 0, sizeof(ov));
00125 if (!UnlockFileEx(m_hdl, 0, 0xffffffff, 0xffffffff, &ov))
00126 {
00127 return -1;
00128 }
00129
00130 return 0;
00131 }
00132
00133 #else // NOT WIN32
00134
00136 File::File(const File& x)
00137 : m_hdl(x.m_hdl != BLOCXX_INVALID_FILEHANDLE ?
00138 dup(x.m_hdl) : BLOCXX_INVALID_FILEHANDLE)
00139 {
00140 }
00141
00142 namespace {
00144
00145 int
00146 doLock(int hdl, int cmd, short int type)
00147 {
00148 struct flock lck;
00149 ::memset (&lck, '\0', sizeof (lck));
00150 lck.l_type = type;
00151 lck.l_whence = 0;
00152 lck.l_start = 0L;
00153 lck.l_len = 0L;
00154 return ::fcntl(hdl, cmd, &lck);
00155 }
00156 }
00158 int
00159 File::getLock(ELockType type)
00160 {
00161 return doLock(m_hdl, F_SETLKW, type == E_WRITE_LOCK ?
00162 F_WRLCK : F_RDLCK);
00163 }
00165 int
00166 File::tryLock(ELockType type)
00167 {
00168 return doLock(m_hdl, F_SETLK, type == E_WRITE_LOCK ?
00169 F_WRLCK : F_RDLCK);
00170 }
00172 int
00173 File::unlock()
00174 {
00175 return doLock(m_hdl, F_SETLK, F_UNLCK);
00176 }
00177 #endif
00178
00180 File::~File()
00181 {
00182 if (close() == -1)
00183 {
00184 int lerrno = errno;
00185 Logger lgr("blocxx.common");
00186 BLOCXX_LOG_ERROR(lgr,
00187 Format("Closing file handle %1 failed: %2",
00188 m_hdl, lerrno)
00189 );
00190 errno = lerrno;
00191 }
00192 }
00193
00194 }
00195