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 }