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