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