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
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/File.hpp"
00040
00041 #ifdef BLOCXX_WIN32
00042 #include <io.h>
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <memory.h>
00046 #else
00047 #include <fcntl.h>
00048 #ifdef BLOCXX_HAVE_UNISTD_H
00049 #include <unistd.h>
00050 #endif
00051 #endif
00052
00053
00054 namespace BLOCXX_NAMESPACE
00055 {
00056 #ifdef BLOCXX_WIN32
00057 namespace
00058 {
00060
00061 int
00062 doLock(HANDLE hFile, bool doWait, DWORD lockType)
00063 {
00064 if (hFile == INVALID_HANDLE_VALUE)
00065 {
00066 return -1;
00067 }
00068
00069 DWORD flags = lockType;
00070 if (!doWait)
00071 {
00072 flags |= LOCKFILE_FAIL_IMMEDIATELY;
00073 }
00074
00075 OVERLAPPED ov;
00076 memset(&ov, 0, sizeof(ov));
00077 if (!LockFileEx(hFile, flags, 0, 0xffffffff,
00078 0xffffffff, &ov))
00079 {
00080 return -1;
00081 }
00082
00083 return 0;
00084 }
00085
00086 }
00087
00089 File::File(const File& x) : m_hdl(BLOCXX_INVALID_FILEHANDLE)
00090 {
00091 if( x.m_hdl != BLOCXX_INVALID_FILEHANDLE )
00092 {
00093 DuplicateHandle(GetCurrentProcess(), x.m_hdl, GetCurrentProcess(),
00094 &m_hdl , 0, FALSE, DUPLICATE_SAME_ACCESS);
00095 }
00096 }
00098 int
00099 File::getLock(ELockType type)
00100 {
00101 return doLock(m_hdl, true, type == E_WRITE_LOCK ?
00102 LOCKFILE_EXCLUSIVE_LOCK : 0);
00103 }
00105 int
00106 File::tryLock(ELockType type)
00107 {
00108 return doLock(m_hdl, false, type == E_WRITE_LOCK ?
00109 LOCKFILE_EXCLUSIVE_LOCK : 0);
00110 }
00112 int
00113 File::unlock()
00114 {
00115 if (m_hdl == INVALID_HANDLE_VALUE)
00116 {
00117 return -1;
00118 }
00119
00120 OVERLAPPED ov;
00121 memset(&ov, 0, sizeof(ov));
00122 if (!UnlockFileEx(m_hdl, 0, 0xffffffff, 0xffffffff, &ov))
00123 {
00124 return -1;
00125 }
00126
00127 return 0;
00128 }
00129
00130 #else // NOT WIN32
00131
00133 File::File(const File& x) : m_hdl(dup(x.m_hdl))
00134 {
00135 }
00136
00137 namespace {
00139
00140 int
00141 doLock(int hdl, int cmd, short int type)
00142 {
00143 struct flock lck;
00144 ::memset (&lck, '\0', sizeof (lck));
00145 lck.l_type = type;
00146 lck.l_whence = 0;
00147 lck.l_start = 0L;
00148 lck.l_len = 0L;
00149 return ::fcntl(hdl, cmd, &lck);
00150 }
00151 }
00153 int
00154 File::getLock(ELockType type)
00155 {
00156 return doLock(m_hdl, F_SETLKW, type == E_WRITE_LOCK ?
00157 F_WRLCK : F_RDLCK);
00158 }
00160 int
00161 File::tryLock(ELockType type)
00162 {
00163 return doLock(m_hdl, F_SETLK, type == E_WRITE_LOCK ?
00164 F_WRLCK : F_RDLCK);
00165 }
00167 int
00168 File::unlock()
00169 {
00170 return doLock(m_hdl, F_SETLK, F_UNLCK);
00171 }
00172 #endif
00173
00174 }
00175