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 #ifndef FileOperations_h 7 #define FileOperations_h 8 9 #include <stdio.h> 10 #include <string> 11 12 #if defined(_WIN32) || defined(_WIN64) 13 #include <windows.h> 14 #define PATHSEP_CHAR '\\' 15 #define PATHSEP_STRING "\\" 16 #else 17 #define PATHSEP_CHAR '/' 18 #define PATHSEP_STRING "/" 19 #endif 20 21 // Make sure that all directories on path exist, excluding the final element of 22 // the path. 23 void ensurePath(std::string Path); 24 25 std::string getAbsolutePath(const std::string &Filename); 26 27 // Used to synchronize access when writing to an analysis file, so that 28 // concurrently running clang instances don't clobber each other's data. 29 // On Windows, we use a named mutex. On POSIX platforms, we use flock on the 30 // source files. flock is advisory locking, and doesn't interfere with clang's 31 // own opening of the source files (i.e. to interfere, clang would have to be 32 // using flock itself, which it does not). 33 struct AutoLockFile { 34 // Absolute path to the analysis file 35 std::string Filename; 36 37 #if defined(_WIN32) || defined(_WIN64) 38 // Handle for the named Mutex 39 HANDLE Handle = NULL; 40 #else 41 // fd for the *source* file that corresponds to the analysis file. We use 42 // the source file because it doesn't change while the analysis file gets 43 // repeatedly replaced by a new version written to a separate tmp file. 44 // This fd is used when using flock to synchronize access. 45 int FileDescriptor = -1; 46 #endif 47 48 // SrcFile should be the absolute path to the source code file, and DstFile 49 // the absolute path to the corresponding analysis file. This constructor 50 // will block until exclusive access has been obtained. 51 AutoLockFile(const std::string &SrcFile, const std::string &DstFile); 52 ~AutoLockFile(); 53 54 // Check after constructing to ensure the mutex was properly set up. 55 bool success(); 56 57 // There used to be an `openFile` method here but we switched to directly 58 // using a std::ifstream for the input file in able to take advantage of its 59 // support for variable length lines (as opposed to fgets which takes a fixed 60 // size buffer). 61 62 // Open a new tmp file for writing the new analysis data to. Caller is 63 // responsible for fclose'ing it. 64 FILE *openTmp(); 65 // Replace the existing analysis file with the new "tmp" one that has the new 66 // data. Returns false on error. 67 bool moveTmp(); 68 }; 69 70 #endif 71