FileOperations.cpp (3579B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "FileOperations.h" 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 11 #if defined(_WIN32) || defined(_WIN64) 12 #include "StringOperations.h" 13 #include <direct.h> 14 #include <io.h> 15 #include <windows.h> 16 #else 17 #include <sys/file.h> 18 #include <sys/time.h> 19 #include <unistd.h> 20 #endif 21 22 #include <fcntl.h> 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 26 // Make sure that all directories on path exist, excluding the final element of 27 // the path. 28 void ensurePath(std::string Path) { 29 size_t Pos = 0; 30 if (Path[0] == PATHSEP_CHAR) { 31 Pos++; 32 } 33 34 while ((Pos = Path.find(PATHSEP_CHAR, Pos)) != std::string::npos) { 35 std::string Portion = Path.substr(0, Pos); 36 if (!Portion.empty()) { 37 #if defined(_WIN32) || defined(_WIN64) 38 int Err = _mkdir(Portion.c_str()); 39 #else 40 int Err = mkdir(Portion.c_str(), 0775); 41 #endif 42 if (Err == -1 && errno != EEXIST) { 43 perror("mkdir failed"); 44 exit(1); 45 } 46 } 47 48 Pos++; 49 } 50 } 51 52 #if defined(_WIN32) || defined(_WIN64) 53 AutoLockFile::AutoLockFile(const std::string &SrcFile, 54 const std::string &DstFile) { 55 this->Filename = DstFile; 56 std::string Hash = hash(SrcFile); 57 std::string MutexName = std::string("Local\\searchfox-") + Hash; 58 std::wstring WideMutexName; 59 WideMutexName.assign(MutexName.begin(), MutexName.end()); 60 Handle = CreateMutex(nullptr, false, WideMutexName.c_str()); 61 if (Handle == NULL) { 62 return; 63 } 64 65 if (WaitForSingleObject(Handle, INFINITE) != WAIT_OBJECT_0) { 66 return; 67 } 68 } 69 70 AutoLockFile::~AutoLockFile() { 71 ReleaseMutex(Handle); 72 CloseHandle(Handle); 73 } 74 75 bool AutoLockFile::success() { return Handle != NULL; } 76 77 FILE *AutoLockFile::openTmp() { 78 int TmpDescriptor = _open((Filename + ".tmp").c_str(), 79 _O_WRONLY | _O_APPEND | _O_CREAT | _O_BINARY, 0666); 80 return _fdopen(TmpDescriptor, "ab"); 81 } 82 83 bool AutoLockFile::moveTmp() { 84 if (_unlink(Filename.c_str()) == -1) { 85 if (errno != ENOENT) { 86 return false; 87 } 88 } 89 return rename((Filename + ".tmp").c_str(), Filename.c_str()) == 0; 90 } 91 92 std::string getAbsolutePath(const std::string &Filename) { 93 char Full[_MAX_PATH]; 94 if (!_fullpath(Full, Filename.c_str(), _MAX_PATH)) { 95 return std::string(""); 96 } 97 return std::string(Full); 98 } 99 #else 100 AutoLockFile::AutoLockFile(const std::string &SrcFile, 101 const std::string &DstFile) { 102 this->Filename = DstFile; 103 FileDescriptor = open(SrcFile.c_str(), O_RDONLY); 104 if (FileDescriptor == -1) { 105 return; 106 } 107 108 do { 109 int rv = flock(FileDescriptor, LOCK_EX); 110 if (rv == 0) { 111 break; 112 } 113 } while (true); 114 } 115 116 AutoLockFile::~AutoLockFile() { close(FileDescriptor); } 117 118 bool AutoLockFile::success() { return FileDescriptor != -1; } 119 120 FILE *AutoLockFile::openTmp() { 121 int TmpDescriptor = 122 open((Filename + ".tmp").c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666); 123 return fdopen(TmpDescriptor, "ab"); 124 } 125 126 bool AutoLockFile::moveTmp() { 127 if (unlink(Filename.c_str()) == -1) { 128 if (errno != ENOENT) { 129 return false; 130 } 131 } 132 return rename((Filename + ".tmp").c_str(), Filename.c_str()) == 0; 133 } 134 135 std::string getAbsolutePath(const std::string &Filename) { 136 char Full[4096]; 137 if (!realpath(Filename.c_str(), Full)) { 138 return std::string(""); 139 } 140 return std::string(Full); 141 } 142 #endif