blob: 9c00ccc63abc64a7f41267731c4a8bf1a6ea4723 [file] [log] [blame]
Laszlo Csomor645dbc42016-12-01 12:56:43 +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
15#include "third_party/ijar/platform_utils.h"
16
17#include <errno.h>
18#include <limits.h>
19#include <stdio.h>
20
21#ifdef COMPILER_MSVC
22#else // not COMPILER_MSVC
23#include <fcntl.h>
24#include <sys/stat.h>
25#include <unistd.h>
26#endif // COMPILER_MSVC
27
28#include <string>
29
30namespace devtools_ijar {
31
Laszlo Csomor8457f3f2016-12-01 14:25:18 +000032using std::string;
33
Laszlo Csomor645dbc42016-12-01 12:56:43 +000034bool stat_file(const char* path, Stat* result) {
35#ifdef COMPILER_MSVC
36 // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order
37 // to close https://github.com/bazelbuild/bazel/issues/2157.
38 fprintf(stderr, "Not yet implemented on Windows\n");
39 return false;
40#else // not COMPILER_MSVC
41 struct stat statst;
42 if (stat(path, &statst) < 0) {
Laszlo Csomor8d6da002016-12-01 13:16:13 +000043 fprintf(stderr, "Cannot stat file %s: %s\n", path, strerror(errno));
Laszlo Csomor645dbc42016-12-01 12:56:43 +000044 return false;
45 }
46 result->total_size = statst.st_size;
47 result->file_mode = statst.st_mode;
48 result->is_directory = (statst.st_mode & S_IFDIR) != 0;
49 return true;
50#endif // COMPILER_MSVC
51}
52
Laszlo Csomor8d6da002016-12-01 13:16:13 +000053bool write_file(const char* path, mode_t perm, const void* data, size_t size) {
54#ifdef COMPILER_MSVC
55 // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order
56 // to close https://github.com/bazelbuild/bazel/issues/2157.
57 fprintf(stderr, "Not yet implemented on Windows\n");
58 return false;
59#else // not COMPILER_MSVC
60 int fd = open(path, O_CREAT | O_WRONLY, perm);
61 if (fd < 0) {
Laszlo Csomor479e18d2016-12-02 15:11:08 +000062 fprintf(stderr, "Cannot open file %s for writing: %s\n", path,
63 strerror(errno));
Laszlo Csomor8d6da002016-12-01 13:16:13 +000064 return false;
65 }
66 bool result = true;
67 if (write(fd, data, size) != size) {
Laszlo Csomor479e18d2016-12-02 15:11:08 +000068 fprintf(stderr, "Cannot write %zu bytes to file %s: %s\n", size, path,
69 strerror(errno));
Laszlo Csomor8d6da002016-12-01 13:16:13 +000070 result = false;
71 }
72 if (close(fd)) {
73 fprintf(stderr, "Cannot close file %s: %s\n", path, strerror(errno));
74 result = false;
75 }
76 return result;
77#endif // COMPILER_MSVC
78}
79
Laszlo Csomord2ed0692016-12-01 14:04:35 +000080bool read_file(const char* path, void* buffer, size_t size) {
81#ifdef COMPILER_MSVC
82 // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order
83 // to close https://github.com/bazelbuild/bazel/issues/2157.
84 fprintf(stderr, "Not yet implemented on Windows\n");
85 return false;
86#else // not COMPILER_MSVC
87 // read the input file
88 int fd = open(path, O_RDONLY);
89 if (fd < 0) {
Laszlo Csomor479e18d2016-12-02 15:11:08 +000090 fprintf(stderr, "Can't open file %s for reading: %s\n", path,
91 strerror(errno));
Laszlo Csomord2ed0692016-12-01 14:04:35 +000092 return false;
93 }
94 bool result = true;
95 size_t nb_read = 0;
96 while (nb_read < size) {
97 size_t to_read = size - nb_read;
98 if (to_read > 16384 /* 16K */) {
99 to_read = 16384;
100 }
101 ssize_t r = read(fd, static_cast<uint8_t*>(buffer) + nb_read, to_read);
102 if (r < 0) {
Laszlo Csomor479e18d2016-12-02 15:11:08 +0000103 fprintf(stderr, "Can't read %zu bytes from file %s: %s\n", to_read, path,
104 strerror(errno));
Laszlo Csomord2ed0692016-12-01 14:04:35 +0000105 result = false;
106 break;
107 }
108 nb_read += r;
109 }
110 if (close(fd)) {
111 fprintf(stderr, "Cannot close file %s: %s\n", path, strerror(errno));
112 result = false;
113 }
114 return result;
115#endif // COMPILER_MSVC
116}
117
Laszlo Csomor8457f3f2016-12-01 14:25:18 +0000118string get_cwd() {
119#ifdef COMPILER_MSVC
120 // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order
121 // to close https://github.com/bazelbuild/bazel/issues/2157.
122 fprintf(stderr, "Not yet implemented on Windows\n");
123 return "";
124#else // not COMPILER_MSVC
125 char cwd[PATH_MAX];
126 if (getcwd(cwd, PATH_MAX) == NULL) {
127 fprintf(stderr, "getcwd() failed: %s\n", strerror(errno));
128 return "";
129 } else {
130 return string(cwd);
131 }
132#endif // COMPILER_MSVC
133}
134
Laszlo Csomorb8caca02016-12-01 14:37:46 +0000135bool make_dirs(const char* path, mode_t mode) {
136#ifdef COMPILER_MSVC
137 // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order
138 // to close https://github.com/bazelbuild/bazel/issues/2157.
139 fprintf(stderr, "Not yet implemented on Windows\n");
140 return false;
141#else // not COMPILER_MSVC
142 // Directories created must have executable bit set and be owner writeable.
143 // Otherwise, we cannot write or create any file inside.
144 mode |= S_IWUSR | S_IXUSR;
145 char path_[PATH_MAX];
146 Stat file_stat;
147 strncpy(path_, path, PATH_MAX);
148 path_[PATH_MAX - 1] = 0;
149 char* pointer = path_;
150 while ((pointer = strchr(pointer, '/')) != NULL) {
151 if (path_ != pointer) { // skip leading slash
152 *pointer = 0;
153 if (!stat_file(path_, &file_stat) && mkdir(path_, mode) < 0) {
Laszlo Csomor479e18d2016-12-02 15:11:08 +0000154 fprintf(stderr, "Cannot create folder %s: %s\n", path_,
155 strerror(errno));
Laszlo Csomorb8caca02016-12-01 14:37:46 +0000156 return false;
157 }
158 *pointer = '/';
159 }
160 pointer++;
161 }
162 return true;
163#endif // COMPILER_MSVC
164}
165
Laszlo Csomor645dbc42016-12-01 12:56:43 +0000166} // namespace devtools_ijar