Mercurial > hg > CbC > CbC_gcc
comparison gcc/d/dmd/root/file.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 | |
2 /* Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved | |
3 * http://www.digitalmars.com | |
4 * Distributed under the Boost Software License, Version 1.0. | |
5 * (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 * https://github.com/D-Programming-Language/dmd/blob/master/src/root/file.c | |
7 */ | |
8 | |
9 #include "dsystem.h" | |
10 #include "file.h" | |
11 | |
12 #if _WIN32 | |
13 #include <windows.h> | |
14 #endif | |
15 | |
16 #if POSIX | |
17 #include <utime.h> | |
18 #endif | |
19 | |
20 #include "filename.h" | |
21 #include "array.h" | |
22 #include "rmem.h" | |
23 | |
24 /****************************** File ********************************/ | |
25 | |
26 File::File(const FileName *n) | |
27 { | |
28 ref = 0; | |
29 buffer = NULL; | |
30 len = 0; | |
31 name = const_cast<FileName *>(n); | |
32 } | |
33 | |
34 File *File::create(const char *n) | |
35 { | |
36 return new File(n); | |
37 } | |
38 | |
39 File::File(const char *n) | |
40 { | |
41 ref = 0; | |
42 buffer = NULL; | |
43 len = 0; | |
44 name = new FileName(n); | |
45 } | |
46 | |
47 File::~File() | |
48 { | |
49 if (buffer) | |
50 { | |
51 if (ref == 0) | |
52 mem.xfree(buffer); | |
53 #if _WIN32 | |
54 if (ref == 2) | |
55 UnmapViewOfFile(buffer); | |
56 #endif | |
57 } | |
58 } | |
59 | |
60 /************************************* | |
61 */ | |
62 | |
63 bool File::read() | |
64 { | |
65 if (len) | |
66 return false; // already read the file | |
67 #if POSIX | |
68 size_t size; | |
69 struct stat buf; | |
70 ssize_t numread; | |
71 | |
72 const char *name = this->name->toChars(); | |
73 //printf("File::read('%s')\n",name); | |
74 int fd = open(name, O_RDONLY); | |
75 if (fd == -1) | |
76 { | |
77 //printf("\topen error, errno = %d\n",errno); | |
78 goto err1; | |
79 } | |
80 | |
81 if (!ref) | |
82 ::free(buffer); | |
83 ref = 0; // we own the buffer now | |
84 | |
85 //printf("\tfile opened\n"); | |
86 if (fstat(fd, &buf)) | |
87 { | |
88 printf("\tfstat error, errno = %d\n",errno); | |
89 goto err2; | |
90 } | |
91 size = (size_t)buf.st_size; | |
92 #ifdef IN_GCC | |
93 buffer = (unsigned char *) ::xmalloc(size + 2); | |
94 #else | |
95 buffer = (unsigned char *) ::malloc(size + 2); | |
96 #endif | |
97 if (!buffer) | |
98 { | |
99 printf("\tmalloc error, errno = %d\n",errno); | |
100 goto err2; | |
101 } | |
102 | |
103 numread = ::read(fd, buffer, size); | |
104 if (numread != (ssize_t)size) | |
105 { | |
106 printf("\tread error, errno = %d\n",errno); | |
107 goto err2; | |
108 } | |
109 | |
110 if (close(fd) == -1) | |
111 { | |
112 printf("\tclose error, errno = %d\n",errno); | |
113 goto err; | |
114 } | |
115 | |
116 len = size; | |
117 | |
118 // Always store a wchar ^Z past end of buffer so scanner has a sentinel | |
119 buffer[size] = 0; // ^Z is obsolete, use 0 | |
120 buffer[size + 1] = 0; | |
121 return false; | |
122 | |
123 err2: | |
124 close(fd); | |
125 err: | |
126 ::free(buffer); | |
127 buffer = NULL; | |
128 len = 0; | |
129 | |
130 err1: | |
131 return true; | |
132 #elif _WIN32 | |
133 DWORD size; | |
134 DWORD numread; | |
135 | |
136 const char *name = this->name->toChars(); | |
137 HANDLE h = CreateFileA(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, | |
138 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); | |
139 if (h == INVALID_HANDLE_VALUE) | |
140 goto err1; | |
141 | |
142 if (!ref) | |
143 ::free(buffer); | |
144 ref = 0; | |
145 | |
146 size = GetFileSize(h,NULL); | |
147 #ifdef IN_GCC | |
148 buffer = (unsigned char *) ::xmalloc(size + 2); | |
149 #else | |
150 buffer = (unsigned char *) ::malloc(size + 2); | |
151 #endif | |
152 if (!buffer) | |
153 goto err2; | |
154 | |
155 if (ReadFile(h,buffer,size,&numread,NULL) != TRUE) | |
156 goto err2; | |
157 | |
158 if (numread != size) | |
159 goto err2; | |
160 | |
161 if (!CloseHandle(h)) | |
162 goto err; | |
163 | |
164 len = size; | |
165 | |
166 // Always store a wchar ^Z past end of buffer so scanner has a sentinel | |
167 buffer[size] = 0; // ^Z is obsolete, use 0 | |
168 buffer[size + 1] = 0; | |
169 return 0; | |
170 | |
171 err2: | |
172 CloseHandle(h); | |
173 err: | |
174 ::free(buffer); | |
175 buffer = NULL; | |
176 len = 0; | |
177 | |
178 err1: | |
179 return true; | |
180 #else | |
181 assert(0); | |
182 #endif | |
183 } | |
184 | |
185 /********************************************* | |
186 * Write a file. | |
187 * Returns: | |
188 * false success | |
189 */ | |
190 | |
191 bool File::write() | |
192 { | |
193 #if POSIX | |
194 ssize_t numwritten; | |
195 | |
196 const char *name = this->name->toChars(); | |
197 int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, (6 << 6) | (4 << 3) | 4); | |
198 if (fd == -1) | |
199 goto err; | |
200 | |
201 numwritten = ::write(fd, buffer, len); | |
202 if ((ssize_t)len != numwritten) | |
203 goto err2; | |
204 | |
205 if (close(fd) == -1) | |
206 goto err; | |
207 | |
208 return false; | |
209 | |
210 err2: | |
211 close(fd); | |
212 ::remove(name); | |
213 err: | |
214 return true; | |
215 #elif _WIN32 | |
216 DWORD numwritten; | |
217 | |
218 const char *name = this->name->toChars(); | |
219 HANDLE h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS, | |
220 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); | |
221 if (h == INVALID_HANDLE_VALUE) | |
222 goto err; | |
223 | |
224 if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE) | |
225 goto err2; | |
226 | |
227 if (len != numwritten) | |
228 goto err2; | |
229 | |
230 if (!CloseHandle(h)) | |
231 goto err; | |
232 return false; | |
233 | |
234 err2: | |
235 CloseHandle(h); | |
236 DeleteFileA(name); | |
237 err: | |
238 return true; | |
239 #else | |
240 assert(0); | |
241 #endif | |
242 } | |
243 | |
244 void File::remove() | |
245 { | |
246 #if POSIX | |
247 ::remove(this->name->toChars()); | |
248 #elif _WIN32 | |
249 DeleteFileA(this->name->toChars()); | |
250 #else | |
251 assert(0); | |
252 #endif | |
253 } | |
254 | |
255 const char *File::toChars() | |
256 { | |
257 return name->toChars(); | |
258 } |