create directory for lock files and set appropriate access rights
| 171 | |
| 172 | // create directory for lock files and set appropriate access rights |
| 173 | void createLockDirectory(const char* pathname) |
| 174 | { |
| 175 | struct STAT st; |
| 176 | for(;;) |
| 177 | { |
| 178 | if (access(pathname, R_OK | W_OK | X_OK) == 0) |
| 179 | { |
| 180 | if (os_utils::stat(pathname, &st) != 0) |
| 181 | system_call_failed::raise("stat", pathname); |
| 182 | if (S_ISDIR(st.st_mode)) |
| 183 | return; |
| 184 | // not exactly original meaning, but very close to it |
| 185 | system_call_failed::raise("mkdir", pathname, ENOTDIR); |
| 186 | } |
| 187 | |
| 188 | if (SYSCALL_INTERRUPTED(errno)) |
| 189 | continue; |
| 190 | if (errno == ENOENT) |
| 191 | break; |
| 192 | system_call_failed::raise("access", pathname); |
| 193 | } |
| 194 | |
| 195 | Firebird::PathName newname(pathname); |
| 196 | newname.rtrim("/"); |
| 197 | newname += ".tmp.XXXXXX"; |
| 198 | char* pathname2 = newname.begin(); |
| 199 | |
| 200 | while (!mkdtemp(pathname2)) |
| 201 | { |
| 202 | if (SYSCALL_INTERRUPTED(errno)) |
| 203 | continue; |
| 204 | (Arg::Gds(isc_lock_dir_access) << pathname2).raise(); |
| 205 | } |
| 206 | changeFileRights(pathname2, 0770); |
| 207 | |
| 208 | Firebird::PathName renameGuard(pathname2); |
| 209 | renameGuard += "/fb_rename_guard"; |
| 210 | for(;;) |
| 211 | { |
| 212 | int gfd = creat(renameGuard.c_str(), 0600); |
| 213 | if (gfd >= 0) |
| 214 | { |
| 215 | close(gfd); |
| 216 | break; |
| 217 | } |
| 218 | if (SYSCALL_INTERRUPTED(errno)) |
| 219 | continue; |
| 220 | (Arg::Gds(isc_lock_dir_access) << renameGuard).raise(); |
| 221 | } |
| 222 | |
| 223 | while (rename(pathname2, pathname) != 0) |
| 224 | { |
| 225 | if (SYSCALL_INTERRUPTED(errno)) |
| 226 | continue; |
| 227 | |
| 228 | if (errno == EEXIST || errno == ENOTEMPTY) |
| 229 | { |
| 230 | while (unlink(renameGuard.c_str()) != 0) |
no test coverage detected