]> cygwin.com Git - cygwin-apps/setup.git/blame - io_stream_file.cc
2002-07-15 Robert Collins <rbtcollins@hotmail.com>
[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
16#if 0
17static const char *cvsid =
18 "\n%%% $Id$\n";
19#endif
20
2b48ecd0 21#if defined(WIN32) && !defined (_CYGWIN_)
b24c88b3 22#include "win32.h"
2b48ecd0 23#include "port.h"
2b48ecd0
RC
24#include "mklink2.h"
25#endif
26
aa1e3b4d
RC
27#include "mkdir.h"
28
29
b24c88b3
RC
30#include <stdio.h>
31#include <stdlib.h>
ca9506cc 32#include <errno.h>
b24c88b3 33#include <unistd.h>
94852d65
RC
34#if HAVE_SYS_STAT_H
35#include <sys/stat.h>
36#endif
37#include <stdexcept>
38
b24c88b3 39#include "io_stream_file.h"
19911586
RC
40#include "IOStreamProvider.h"
41
94852d65 42
19911586
RC
43/* completely private iostream registration class */
44class FileProvider : public IOStreamProvider
45{
46public:
47 int exists (String const &path) const
48 {return io_stream_file::exists(path);}
49 int remove (String const &path) const
50 {return io_stream_file::remove(path);}
51 int mklink (String const &a , String const &b, io_stream_link_t c) const
52 {return io_stream_file::mklink(a,b,c);}
53 io_stream *open (String const &a,String const &b) const
54 {return new io_stream_file (a, b);}
55 ~FileProvider (){}
56 int move (String const &a,String const &b) const
57 {return io_stream_file::move (a, b);}
58 int mkdir_p (enum path_type_t isadir, String const &path) const
94852d65
RC
59 {
60 return ::mkdir_p (isadir == PATH_TO_DIR ? 1 : 0, path.cstr_oneuse());
61 }
19911586
RC
62protected:
63 FileProvider() // no creating this
64 {
65 io_stream::registerProvider (theInstance, "file://");
66 }
67 FileProvider(FileProvider const &); // no copying
68 FileProvider &operator=(FileProvider const &); // no assignment
69private:
70 static FileProvider theInstance;
71};
72FileProvider FileProvider::theInstance = FileProvider();
73
b24c88b3
RC
74
75/* for set_mtime */
76#define FACTOR (0x19db1ded53ea710LL)
77#define NSPERSEC 10000000LL
78
3c054baf
RC
79io_stream_file::io_stream_file (String const &name, String const &mode):
80fp(), fname(name),lmode (mode)
b24c88b3 81{
b24c88b3 82 errno = 0;
3c054baf 83 if (!name.size() || !mode.size())
b24c88b3 84 return;
3c054baf 85 fp = fopen (name.cstr_oneuse(), mode.cstr_oneuse());
b24c88b3
RC
86 if (!fp)
87 lasterr = errno;
88}
89
90io_stream_file::~io_stream_file ()
91{
b24c88b3
RC
92 if (fp)
93 fclose (fp);
e9440f0f 94 destroyed = 1;
b24c88b3
RC
95}
96
97int
3c054baf 98io_stream_file::exists (String const &path)
b24c88b3 99{
2b48ecd0 100#if defined(WIN32) && !defined (_CYGWIN_)
3c054baf 101 if (_access (path.cstr_oneuse(), 0) == 0)
2b48ecd0
RC
102#else
103 if (access (path.cstr_oneuse(), F_OK) == 0)
104#endif
b24c88b3
RC
105 return 1;
106 return 0;
107}
108
109int
3c054baf 110io_stream_file::remove (String const &path)
b24c88b3 111{
3c054baf 112 if (!path.size())
b24c88b3 113 return 1;
2b48ecd0 114#if defined(WIN32) && !defined (_CYGWIN_)
3c054baf 115 unsigned long w = GetFileAttributes (path.cstr_oneuse());
b24c88b3
RC
116 if (w != 0xffffffff && w & FILE_ATTRIBUTE_DIRECTORY)
117 {
3c054baf 118 char *tmp = new char [path.size() + 10];
b24c88b3
RC
119 int i = 0;
120 do
121 {
122 i++;
3c054baf 123 sprintf (tmp, "%s.old-%d", path.cstr_oneuse(), i);
b24c88b3
RC
124 }
125 while (GetFileAttributes (tmp) != 0xffffffff);
126 fprintf (stderr, "warning: moving directory \"%s\" out of the way.\n",
3c054baf
RC
127 path.cstr_oneuse());
128 MoveFile (path.cstr_oneuse(), tmp);
5e0464a1 129 delete[] tmp;
b24c88b3 130 }
4849e2fc 131 SetFileAttributes (path.cstr_oneuse(), w & ~FILE_ATTRIBUTE_READONLY);
3c054baf 132 return !DeleteFileA (path.cstr_oneuse());
2b48ecd0
RC
133#else
134 // FIXME: try rmdir if unlink fails - remove the dir
135 return unlink (path.cstr_oneuse());
136#endif
b24c88b3
RC
137}
138
139int
3c054baf 140io_stream_file::mklink (String const &from, String const &to,
b24c88b3
RC
141 io_stream_link_t linktype)
142{
3c054baf 143 if (!from.size() || !to.size())
b24c88b3 144 return 1;
2b48ecd0 145#if defined(WIN32) && !defined (_CYGWIN_)
b24c88b3
RC
146 switch (linktype)
147 {
148 case IO_STREAM_SYMLINK:
3c054baf 149 return mkcygsymlink (from.cstr_oneuse(), to.cstr_oneuse());
b24c88b3
RC
150 case IO_STREAM_HARDLINK:
151 return 1;
152 }
2b48ecd0
RC
153#else
154 switch (linktype)
155 {
156 case IO_STREAM_SYMLINK:
157 return symlink (to.cstr_oneuse(), from.cstr_oneuse());
158 case IO_STREAM_HARDLINK:
159 return link (to.cstr_oneuse(), from.cstr_oneuse());
160 }
161#endif
b24c88b3
RC
162 return 1;
163}
164
165/* virtuals */
166
167
7c7034e8
RC
168ssize_t
169io_stream_file::read (void *buffer, size_t len)
b24c88b3
RC
170{
171 if (fp)
172 return fread (buffer, 1, len, fp);
173 return 0;
174}
175
7c7034e8
RC
176ssize_t
177io_stream_file::write (const void *buffer, size_t len)
b24c88b3
RC
178{
179 if (fp)
180 return fwrite (buffer, 1, len, fp);
181 return 0;
182}
183
7c7034e8
RC
184ssize_t
185io_stream_file::peek (void *buffer, size_t len)
b24c88b3 186{
b24c88b3
RC
187 if (fp)
188 {
7c7034e8
RC
189 int pos = ftell (fp);
190 ssize_t rv = fread (buffer, 1, len, fp);
b24c88b3
RC
191 fseek (fp, pos, SEEK_SET);
192 return rv;
193 }
194 return 0;
195}
196
197long
198io_stream_file::tell ()
199{
200 if (fp)
201 {
202 return ftell (fp);
203 }
204 return 0;
205}
206
ca9506cc
RC
207int
208io_stream_file::seek (long where, io_stream_seek_t whence)
209{
7c7034e8
RC
210 if (fp)
211 {
212 return fseek (fp, where, (int) whence);
213 }
214 lasterr = EBADF;
215 return -1;
ca9506cc
RC
216}
217
b24c88b3
RC
218int
219io_stream_file::error ()
220{
221 if (fp)
222 return ferror (fp);
223 return lasterr;
224}
225
226int
227io_stream_file::set_mtime (int mtime)
228{
3c054baf 229 if (!fname.size())
b24c88b3
RC
230 return 1;
231 if (fp)
232 fclose (fp);
2b48ecd0 233#if defined(WIN32) && !defined (_CYGWIN_)
b24c88b3
RC
234 long long ftimev = mtime * NSPERSEC + FACTOR;
235 FILETIME ftime;
236 ftime.dwHighDateTime = ftimev >> 32;
237 ftime.dwLowDateTime = ftimev;
238 HANDLE h =
3c054baf 239 CreateFileA (fname.cstr_oneuse(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
b24c88b3
RC
240 0, OPEN_EXISTING,
241 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
242 if (h)
243 {
244 SetFileTime (h, 0, 0, &ftime);
245 CloseHandle (h);
b24c88b3
RC
246 return 0;
247 }
2b48ecd0
RC
248#else
249 throw new runtime_error ("set_mtime not supported on posix yet.");
250#endif
b24c88b3
RC
251 return 1;
252}
7c7034e8
RC
253
254int
3c054baf 255io_stream_file::move (String const &from, String const &to)
7c7034e8 256{
3c054baf 257 if (!from.size()|| !to.size())
7c7034e8 258 return 1;
3c054baf 259 return rename (from.cstr_oneuse(), to.cstr_oneuse());
7c7034e8 260}
341988b9
RC
261
262size_t
263io_stream_file::get_size ()
264{
3c054baf 265 if (!fname.size())
341988b9 266 return 0;
2b48ecd0 267#if defined(WIN32) && !defined (_CYGWIN_)
e0a4db64
RC
268 HANDLE h;
269 WIN32_FIND_DATA buf;
270 DWORD ret = 0;
271
272 h = FindFirstFileA (fname.cstr_oneuse(), &buf);
273 if (h != INVALID_HANDLE_VALUE)
274 {
275 if (buf.nFileSizeHigh == 0)
276 ret = buf.nFileSizeLow;
277 FindClose (h);
278 }
279 return ret;
2b48ecd0
RC
280#else
281 struct stat buf;
282 if (stat(fname.cstr_oneuse(), &buf))
283 throw new runtime_error ("Failed to stat file - has it been deleted?");
284 return buf.st_size;
285#endif
341988b9 286}
This page took 0.082144 seconds and 5 git commands to generate.