blob: 02f5b8725b4abd686444c6ab9f6348e61bb8ef31 [file] [log] [blame]
Laszlo Csomor60b15f92016-09-29 08:56:42 +00001// Copyright 2016 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Laszlo Csomorb9d77672016-11-09 10:08:19 +000015#ifndef BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_
16#define BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_
Laszlo Csomor60b15f92016-09-29 08:56:42 +000017
Laszlo Csomor8a48f612016-11-17 10:18:34 +000018#include <stdint.h>
Piotr Sikorab3dc4cc2016-12-05 10:10:50 +000019#include <time.h>
Laszlo Csomor8a48f612016-11-17 10:18:34 +000020
Laszlo Csomor60b15f92016-09-29 08:56:42 +000021#include <string>
22
23namespace blaze_util {
24
Laszlo Csomoref5ceef2016-11-18 11:19:02 +000025class IPipe;
26
27IPipe* CreatePipe();
28
Laszlo Csomorce1b3e12017-01-19 14:56:30 +000029// Class to query/manipulate the last modification time (mtime) of files.
30class IFileMtime {
31 public:
32 virtual ~IFileMtime() {}
33
34 // Queries the mtime of `path` to see whether it's in the distant future.
35 // Returns true if querying succeeded and stores the result in `result`.
36 // Returns false if querying failed.
37 virtual bool GetIfInDistantFuture(const std::string &path, bool *result) = 0;
38
39 // Sets the mtime of file under `path` to the current time.
40 // Returns true if the mtime was changed successfully.
41 virtual bool SetToNow(const std::string &path) = 0;
42
43 // Sets the mtime of file under `path` to the distant future.
44 // "Distant future" should be on the order of some years into the future, like
45 // a decade.
46 // Returns true if the mtime was changed successfully.
47 virtual bool SetToDistantFuture(const std::string &path) = 0;
48};
49
50// Creates a platform-specific implementation of `IFileMtime`.
51IFileMtime *CreateFileMtime();
52
Laszlo Csomora4d0ea42016-12-19 14:30:52 +000053// Split a path to dirname and basename parts.
54std::pair<std::string, std::string> SplitPath(const std::string &path);
55
Laszlo Csomor6e2ccb72017-03-01 16:53:35 +000056#if defined(COMPILER_MSVC) || defined(__CYGWIN__)
Laszlo Csomor99b01542017-03-02 11:43:21 +000057// We cannot include <windows.h> because it #defines many symbols that conflict
58// with our function names, e.g. GetUserName, SendMessage.
59// Instead of typedef'ing HANDLE, let's use the actual type, void*. If that ever
60// changes in the future and HANDLE would no longer be compatible with void*
61// (very unlikely, given how fundamental this type is in Windows), then we'd get
62// a compilation error.
63typedef /* HANDLE */ void *file_handle_type;
Laszlo Csomor6e2ccb72017-03-01 16:53:35 +000064#else // !(defined(COMPILER_MSVC) || defined(__CYGWIN__))
65typedef int file_handle_type;
66#endif // defined(COMPILER_MSVC) || defined(__CYGWIN__)
67
Laszlo Csomor508af302017-03-02 09:09:09 +000068// Result of a `ReadFromHandle` operation.
69//
70// This is a platform-independent abstraction of `errno`. If you need to handle
71// an errno value, add an entry here and update the platform-specific
72// `ReadFromHandle` implementations accordingly.
73struct ReadFileResult {
74 enum Errors {
75 SUCCESS = 0,
76 OTHER_ERROR = 1,
77 INTERRUPTED = 2,
78 AGAIN = 3,
79 };
80};
81
82int ReadFromHandle(file_handle_type handle, void *data, size_t size,
83 int *error);
Laszlo Csomor6e2ccb72017-03-01 16:53:35 +000084
Laszlo Csomor49970e02016-11-28 08:55:47 +000085// Replaces 'content' with contents of file 'filename'.
86// If `max_size` is positive, the method reads at most that many bytes;
87// otherwise the method reads the whole file.
88// Returns false on error. Can be called from a signal handler.
89bool ReadFile(const std::string &filename, std::string *content,
90 int max_size = 0);
91
Laszlo Csomor5f277122017-02-27 12:25:11 +000092// Reads up to `size` bytes from the file `filename` into `data`.
93// There must be enough memory allocated at `data`.
94// Returns true on success, false on error.
95bool ReadFile(const std::string &filename, void *data, size_t size);
96
97// Writes `size` bytes from `data` into file `filename` and chmods it to `perm`.
Laszlo Csomor49970e02016-11-28 08:55:47 +000098// Returns false on failure, sets errno.
Laszlo Csomor5f277122017-02-27 12:25:11 +000099bool WriteFile(const void *data, size_t size, const std::string &filename,
100 unsigned int perm = 0755);
Laszlo Csomor49970e02016-11-28 08:55:47 +0000101
Laszlo Csomor508af302017-03-02 09:09:09 +0000102// Result of a `WriteToStdOutErr` operation.
103//
104// This is a platform-independent abstraction of `errno`. If you need to handle
105// an errno value, add an entry here and update the platform-specific
106// `WriteToStdOutErr` implementations accordingly.
107struct WriteResult {
108 enum Errors {
109 SUCCESS = 0,
110 OTHER_ERROR = 1, // some uncategorized error occurred
111 BROKEN_PIPE = 2, // EPIPE (reading end of the pipe is closed)
112 };
113};
114
115// Writes `size` bytes from `data` into stdout/stderr.
116// Writes to stdout if `to_stdout` is true, writes to stderr otherwise.
117// Returns one of `WriteResult::Errors`.
118//
119// This is a platform-independent abstraction of `fwrite` with `errno` checking
120// and awareness of pipes (i.e. in case stderr/stdout is connected to a pipe).
121int WriteToStdOutErr(const void *data, size_t size, bool to_stdout);
122
Laszlo Csomor918814e2017-02-08 13:28:47 +0000123enum RenameDirectoryResult {
124 kRenameDirectorySuccess = 0,
125 kRenameDirectoryFailureNotEmpty = 1,
126 kRenameDirectoryFailureOtherError = 2,
127};
128
129// Renames the directory at `old_name` to `new_name`.
130// Returns one of the RenameDirectoryResult enum values.
131int RenameDirectory(const std::string &old_name, const std::string &new_name);
132
Laszlo Csomor49970e02016-11-28 08:55:47 +0000133// Unlinks the file given by 'file_path'.
134// Returns true on success. In case of failure sets errno.
135bool UnlinkPath(const std::string &file_path);
136
Laszlo Csomor2459be32017-01-05 10:14:09 +0000137// Returns true if this path exists, following symlinks.
Laszlo Csomorb9d77672016-11-09 10:08:19 +0000138bool PathExists(const std::string& path);
139
Laszlo Csomorc3545392016-11-24 13:33:28 +0000140// Returns the real, absolute path corresponding to `path`.
141// The method resolves all symlink components of `path`.
142// Returns the empty string upon error.
143//
144// This is a wrapper around realpath(3).
145std::string MakeCanonical(const char *path);
146
Laszlo Csomor00549b42017-01-11 09:12:10 +0000147// Returns true if `path` exists, is a file or symlink to one, and is readable.
148// Follows symlinks.
149bool CanReadFile(const std::string &path);
150
151// Returns true if `path` exists, is a file or symlink to one, and is writable.
152// Follows symlinks.
153bool CanExecuteFile(const std::string &path);
154
155// Returns true if `path` exists, is a directory or symlink/junction to one, and
156// is both readable and writable.
157// Follows symlinks/junctions.
158bool CanAccessDirectory(const std::string &path);
Laszlo Csomorb9d77672016-11-09 10:08:19 +0000159
Laszlo Csomor8a48f612016-11-17 10:18:34 +0000160// Returns true if `path` refers to a directory or a symlink/junction to one.
161bool IsDirectory(const std::string& path);
162
Laszlo Csomor760f7862016-12-19 15:46:47 +0000163// Returns true if `path` is the root directory or a Windows drive root.
164bool IsRootDirectory(const std::string &path);
165
166// Returns true if `path` is absolute.
167bool IsAbsolute(const std::string &path);
168
Laszlo Csomorae16e762016-11-18 10:16:08 +0000169// Calls fsync() on the file (or directory) specified in 'file_path'.
170// pdie() if syncing fails.
171void SyncFile(const std::string& path);
172
Thiago Farina227369a2016-12-07 12:40:40 +0000173// mkdir -p path. All newly created directories use the given mode.
174// `mode` should be an octal permission mask, e.g. 0755.
175// Returns false on failure, sets errno.
176bool MakeDirectories(const std::string &path, unsigned int mode);
177
Laszlo Csomor9c951962016-11-10 13:31:27 +0000178// Returns the current working directory.
Laszlo Csomore86b04c2016-12-21 17:36:00 +0000179// The path is platform-specific (e.g. Windows path of Windows) and absolute.
Laszlo Csomor9c951962016-11-10 13:31:27 +0000180std::string GetCwd();
181
182// Changes the current working directory to `path`, returns true upon success.
183bool ChangeDirectory(const std::string& path);
184
Laszlo Csomor251bf032016-11-16 11:01:32 +0000185// Interface to be implemented by ForEachDirectoryEntry clients.
186class DirectoryEntryConsumer {
187 public:
188 virtual ~DirectoryEntryConsumer() {}
189
190 // This method is called for each entry in a directory.
191 // `name` is the full path of the entry.
192 // `is_directory` is true if this entry is a directory (but false if this is a
193 // symlink pointing to a directory).
194 virtual void Consume(const std::string &name, bool is_directory) = 0;
195};
196
197// Executes a function for each entry in a directory (except "." and "..").
198//
199// Returns true if the `path` referred to a directory or directory symlink,
200// false otherwise.
201//
202// See DirectoryEntryConsumer for more details.
203void ForEachDirectoryEntry(const std::string &path,
204 DirectoryEntryConsumer *consume);
205
Laszlo Csomord6297fb2016-12-20 09:38:53 +0000206#if defined(COMPILER_MSVC) || defined(__CYGWIN__)
Laszlo Csomora6695572017-01-18 10:58:17 +0000207// Like `AsWindowsPath` but the result is absolute and has UNC prefix if needed.
208bool AsWindowsPathWithUncPrefix(const std::string &path, std::wstring *wpath);
Laszlo Csomor44ecf9a2017-01-10 10:41:26 +0000209
210// Same as `AsWindowsPath`, but returns a lowercase 8dot3 style shortened path.
211// Result will never have a UNC prefix.
212bool AsShortWindowsPath(const std::string &path, std::string *result);
Laszlo Csomord6297fb2016-12-20 09:38:53 +0000213#endif // defined(COMPILER_MSVC) || defined(__CYGWIN__)
214
Laszlo Csomor60b15f92016-09-29 08:56:42 +0000215} // namespace blaze_util
216
Laszlo Csomorb9d77672016-11-09 10:08:19 +0000217#endif // BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_