]> cygwin.com Git - cygwin-apps/setup.git/blame - io_stream_file.cc
Added dpiAwareness element to manifest
[cygwin-apps/setup.git] / io_stream_file.cc
CommitLineData
b24c88b3
RC
1/*
2 * Copyright (c) 2001, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
b24c88b3 16#include "win32.h"
2b48ecd0 17#include "mklink2.h"
2f0315ad 18#include "filemanip.h"
aa1e3b4d
RC
19#include "mkdir.h"
20
b24c88b3
RC
21#include <stdio.h>
22#include <stdlib.h>
ca9506cc 23#include <errno.h>
b24c88b3 24#include <unistd.h>
94852d65 25
b24c88b3 26#include "io_stream_file.h"
19911586 27#include "IOStreamProvider.h"
781a9555 28#include "LogSingleton.h"
19911586
RC
29
30/* completely private iostream registration class */
31class FileProvider : public IOStreamProvider
32{
33public:
a3a02820 34 int exists (const std::string& path) const
19911586 35 {return io_stream_file::exists(path);}
a3a02820 36 int remove (const std::string& path) const
19911586 37 {return io_stream_file::remove(path);}
a3a02820 38 int mklink (const std::string& a , const std::string& b, io_stream_link_t c) const
19911586 39 {return io_stream_file::mklink(a,b,c);}
26922cd2
CV
40 io_stream *open (const std::string& a,const std::string& b, mode_t m) const
41 {return new io_stream_file (a, b, m);}
19911586 42 ~FileProvider (){}
a3a02820 43 int move (const std::string& a,const std::string& b) const
19911586 44 {return io_stream_file::move (a, b);}
b41c2908 45 int mkdir_p (path_type_t isadir, const std::string& path, mode_t mode) const
94852d65 46 {
b41c2908 47 return ::mkdir_p (isadir == PATH_TO_DIR ? 1 : 0, path.c_str(), mode);
94852d65 48 }
19911586
RC
49protected:
50 FileProvider() // no creating this
51 {
52 io_stream::registerProvider (theInstance, "file://");
53 }
54 FileProvider(FileProvider const &); // no copying
55 FileProvider &operator=(FileProvider const &); // no assignment
56private:
57 static FileProvider theInstance;
58};
59FileProvider FileProvider::theInstance = FileProvider();
60
2f0315ad
CV
61wchar_t *
62io_stream_file::w_str ()
63{
64 if (!wname)
65 {
66 wname = new wchar_t [fname.size () + 7];
67 if (wname)
68 mklongpath (wname, fname.c_str (), fname.size () + 7);
69 }
70 return wname;
71}
72
26922cd2 73io_stream_file::io_stream_file (const std::string& name, const std::string& mode, mode_t perms) : fp(), lasterr (0), fname(name), wname (NULL)
b24c88b3 74{
b24c88b3 75 errno = 0;
6dcfeb7d 76 if (!name.size())
b24c88b3 77 return;
6dcfeb7d 78 if (mode.size ())
2f0315ad 79 {
1e029da2 80 fp = nt_wfopen (w_str (), mode.c_str (), perms);
6dcfeb7d
CV
81 if (!fp)
82 lasterr = errno;
2f0315ad 83 }
b24c88b3
RC
84}
85
86io_stream_file::~io_stream_file ()
87{
b24c88b3
RC
88 if (fp)
89 fclose (fp);
2f0315ad
CV
90 if (wname)
91 delete [] wname;
b24c88b3
RC
92}
93
94int
a3a02820 95io_stream_file::exists (const std::string& path)
b24c88b3 96{
558484cc 97 DWORD attr;
1e029da2
YS
98 size_t len = 2 * path.size () + 7;
99 WCHAR wname[len];
100 mklongpath (wname, path.c_str (), len);
101 attr = GetFileAttributesW (wname);
558484cc 102 return attr != INVALID_FILE_ATTRIBUTES
27f40a12 103 && !(attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));
b24c88b3
RC
104}
105
106int
a3a02820 107io_stream_file::remove (const std::string& path)
b24c88b3 108{
3c054baf 109 if (!path.size())
b24c88b3 110 return 1;
1e029da2
YS
111 size_t len = path.size () + 7;
112 WCHAR wpath[len];
113 mklongpath (wpath, path.c_str (), len);
2f0315ad 114
1e029da2
YS
115 unsigned long w = GetFileAttributesW (wpath);
116 if (w == INVALID_FILE_ATTRIBUTES)
117 return 0;
118 if (w & FILE_ATTRIBUTE_DIRECTORY)
b24c88b3 119 {
1e029da2
YS
120 len = wcslen (wpath);
121 WCHAR tmp[len + 10];
122 wcscpy (tmp, wpath);
123 int i = 0;
124 do
b24c88b3 125 {
1e029da2
YS
126 i++;
127 swprintf (tmp + len, L"old-%d", i);
b24c88b3 128 }
1e029da2 129 while (GetFileAttributesW (tmp) != INVALID_FILE_ATTRIBUTES);
781a9555
JT
130 Log (LOG_TIMESTAMP) << "warning: moving directory \"" << path.c_str()
131 << "\" out of the way." << endLog;
1e029da2 132 MoveFileW (wpath, tmp);
b24c88b3 133 }
1e029da2
YS
134 SetFileAttributesW (wpath, w & ~FILE_ATTRIBUTE_READONLY);
135 return !DeleteFileW (wpath);
b24c88b3
RC
136}
137
138int
a3a02820 139io_stream_file::mklink (const std::string& from, const std::string& to,
b24c88b3
RC
140 io_stream_link_t linktype)
141{
3c054baf 142 if (!from.size() || !to.size())
b24c88b3
RC
143 return 1;
144 switch (linktype)
145 {
146 case IO_STREAM_SYMLINK:
d2a3615c 147 return mkcygsymlink (from.c_str(), to.c_str());
b24c88b3
RC
148 case IO_STREAM_HARDLINK:
149 return 1;
150 }
151 return 1;
152}
153
154/* virtuals */
155
156
7c7034e8
RC
157ssize_t
158io_stream_file::read (void *buffer, size_t len)
b24c88b3 159{
4e30c4f6
CV
160 ssize_t ret = 0;
161
162 if (len && fp && !feof (fp))
163 {
164 clearerr (fp);
165 size_t fret = fread (buffer, 1, len, fp);
166 if (fret < len && ferror (fp))
167 {
168 lasterr = errno;
169 ret = -1;
170 }
171 else
172 ret = (ssize_t) fret;
173 }
174 return ret;
b24c88b3
RC
175}
176
7c7034e8
RC
177ssize_t
178io_stream_file::write (const void *buffer, size_t len)
b24c88b3 179{
4e30c4f6
CV
180 ssize_t ret = 0;
181
182 if (len && fp)
183 {
184 clearerr (fp);
185 size_t fret = fwrite (buffer, 1, len, fp);
186 if (fret < len && ferror (fp))
187 {
188 lasterr = errno;
189 ret = -1;
190 }
191 else
192 ret = (ssize_t) fret;
193 }
194 return ret;
b24c88b3
RC
195}
196
7c7034e8
RC
197ssize_t
198io_stream_file::peek (void *buffer, size_t len)
b24c88b3 199{
b24c88b3
RC
200 if (fp)
201 {
44d31ea0 202 off_t pos = ftello (fp);
64a12e7e 203 ssize_t rv = read (buffer, len);
44d31ea0 204 fseeko (fp, pos, SEEK_SET);
b24c88b3
RC
205 return rv;
206 }
207 return 0;
208}
209
44d31ea0 210off_t
b24c88b3
RC
211io_stream_file::tell ()
212{
213 if (fp)
44d31ea0
CV
214 return ftello (fp);
215
b24c88b3
RC
216 return 0;
217}
218
44d31ea0
CV
219off_t
220io_stream_file::seek (off_t where, io_stream_seek_t whence)
ca9506cc 221{
7c7034e8 222 if (fp)
44d31ea0
CV
223 return fseeko (fp, where, (int) whence);
224
7c7034e8
RC
225 lasterr = EBADF;
226 return -1;
ca9506cc
RC
227}
228
b24c88b3
RC
229int
230io_stream_file::error ()
231{
232 if (fp)
233 return ferror (fp);
234 return lasterr;
235}
236
237int
26922cd2 238io_stream_file::set_mtime (time_t mtime)
b24c88b3 239{
3c054baf 240 if (!fname.size())
b24c88b3
RC
241 return 1;
242 if (fp)
243 fclose (fp);
244 long long ftimev = mtime * NSPERSEC + FACTOR;
245 FILETIME ftime;
246 ftime.dwHighDateTime = ftimev >> 32;
247 ftime.dwLowDateTime = ftimev;
2f0315ad 248 HANDLE h;
1e029da2
YS
249 h = CreateFileW (w_str(), GENERIC_WRITE,
250 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
251 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
2f0315ad 252 if (h != INVALID_HANDLE_VALUE)
b24c88b3
RC
253 {
254 SetFileTime (h, 0, 0, &ftime);
255 CloseHandle (h);
b24c88b3
RC
256 return 0;
257 }
b24c88b3
RC
258 return 1;
259}
7c7034e8
RC
260
261int
a3a02820 262io_stream_file::move (const std::string& from, const std::string& to)
7c7034e8 263{
3c054baf 264 if (!from.size()|| !to.size())
7c7034e8 265 return 1;
d2a3615c 266 return rename (from.c_str(), to.c_str());
7c7034e8 267}
341988b9 268
6dcfeb7d
CV
269/* This only handles file < 2GB. The chance that files in the distro
270 get bigger is rather small, though... */
341988b9
RC
271size_t
272io_stream_file::get_size ()
273{
3c054baf 274 if (!fname.size())
341988b9 275 return 0;
e0a4db64 276 HANDLE h;
e0a4db64 277 DWORD ret = 0;
1e029da2
YS
278 h = CreateFileW (w_str (), GENERIC_READ,
279 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
280 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
281 if (h != INVALID_HANDLE_VALUE)
2f0315ad 282 {
1e029da2
YS
283 ret = GetFileSize (h, NULL);
284 CloseHandle (h);
e0a4db64
RC
285 }
286 return ret;
341988b9 287}
This page took 0.162916 seconds and 6 git commands to generate.