]> cygwin.com Git - cygwin-apps/setup.git/blame - io_stream_cygfile.cc
2002-01-27 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / io_stream_cygfile.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
21
22#include "win32.h"
23#include <stdio.h>
24#include <stdlib.h>
ca9506cc 25#include <errno.h>
b24c88b3
RC
26#include "log.h"
27#include "port.h"
28#include "mount.h"
29#include "mkdir.h"
30#include "mklink2.h"
31#include <unistd.h>
341988b9 32#include "filemanip.h"
b24c88b3
RC
33
34#include "io_stream.h"
35#include "io_stream_cygfile.h"
36
37/* For set mtime */
38#define FACTOR (0x19db1ded53ea710LL)
39#define NSPERSEC 10000000LL
40
41static void
42get_root_dir_now ()
43{
44 if (get_root_dir ())
45 return;
46 read_mounts ();
47}
48
49io_stream_cygfile::io_stream_cygfile (const char *name, const char *mode)
50{
51 fname = NULL;
52 fp = NULL;
53 errno = 0;
54 if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0] ||
55 !mode || IsBadStringPtr (mode, 5) || !mode[0])
56 return;
57
58 /* do this every time because the mount points may change due to fwd/back button use...
59 * TODO: make this less...manual
60 */
61 get_root_dir_now ();
62 if (!get_root_dir ())
63 /* TODO: assign a errno for "no mount table :} " */
64 return;
65
66 fname = cygpath (name, 0);
5e0464a1
RC
67 lmode = new char[strlen(mode) + 1];
68 strcpy (lmode,mode);
b24c88b3
RC
69 fp = fopen (fname, mode);
70 if (!fp)
71 lasterr = errno;
72}
73
74io_stream_cygfile::~io_stream_cygfile ()
75{
76 if (lmode)
5e0464a1 77 delete[] lmode;
b24c88b3 78 if (fname)
5e0464a1 79 delete[] fname;
b24c88b3
RC
80 if (fp)
81 fclose (fp);
e9440f0f 82 destroyed = 1;
b24c88b3
RC
83}
84
85/* Static members */
86int
87io_stream_cygfile::exists (const char *path)
88{
89 get_root_dir_now ();
90 if (get_root_dir () && _access (cygpath (path, 0), 0) == 0)
91 return 1;
92 return 0;
93}
94
95int
96io_stream_cygfile::remove (const char *path)
97{
98 if (!path)
99 return 1;
100 get_root_dir_now ();
101 if (!get_root_dir ())
102 /* TODO: assign a errno for "no mount table :} " */
103 return 1;
104
105 unsigned long w = GetFileAttributes (cygpath (path, 0));
106 if (w != 0xffffffff && w & FILE_ATTRIBUTE_DIRECTORY)
107 {
5e0464a1 108 char *tmp = new char [strlen (cygpath (path, 0)) + 10];
b24c88b3
RC
109 int i = 0;
110 do
111 {
112 i++;
113 sprintf (tmp, "%s.old-%d", cygpath (path, 0), i);
114 }
115 while (GetFileAttributes (tmp) != 0xffffffff);
116 fprintf (stderr, "warning: moving directory \"%s\" out of the way.\n",
117 path);
118 MoveFile (cygpath (path, 0), tmp);
5e0464a1 119 delete[] tmp;
b24c88b3
RC
120 }
121 return !DeleteFileA (cygpath (path, 0));
122}
123
124int
125io_stream_cygfile::mklink (const char *from, const char *to,
126 io_stream_link_t linktype)
127{
128 /* FIXME: badstring check */
129 if (!from || !to)
130 return 1;
131 switch (linktype)
132 {
133 case IO_STREAM_SYMLINK:
134 return mkcygsymlink (cygpath (from, 0), to);
135 case IO_STREAM_HARDLINK:
136 {
137 /* For now, just copy */
138 /* textmode alert: should we translate when linking from an binmode to a
139 text mode mount and vice verca?
140 */
141 io_stream *in = io_stream::open (cygpath (to, 0), "rb");
142 if (!in)
143 {
144 log (LOG_TIMESTAMP, "could not open %s for reading in mklink",
145 to);
146 return 1;
147 }
148 io_stream *out = io_stream::open (cygpath (from, 0), "wb");
149 if (!out)
150 {
151 log (LOG_TIMESTAMP, "could not open %s for writing in mklink",
152 from);
153 delete in;
154 return 1;
155 }
156
157 ssize_t len;
158 char buf[16384];
159 while ((len = in->read (buf, 16384)) > 0)
160 {
161 ssize_t wrote = out->write (buf, len);
162 if (wrote != len)
163 {
164 log (LOG_TIMESTAMP, "error writing to %s in mklink", from);
165 delete in;
166 delete out;
167 return 1;
168 }
169 }
170 delete in;
171 delete out;
172 if (len == 0)
173 return 0;
174 log (LOG_TIMESTAMP,
175 "read error reading %s while copying to %s (emulated hardlink)",
176 to, from);
177 return 1;
178 }
179 }
180 return 1;
181}
182
183
184/* virtuals */
185
7c7034e8
RC
186ssize_t
187io_stream_cygfile::read (void *buffer, size_t len)
b24c88b3
RC
188{
189 if (fp)
190 return fread (buffer, 1, len, fp);
191 return 0;
192}
193
7c7034e8
RC
194ssize_t
195io_stream_cygfile::write (const void *buffer, size_t len)
b24c88b3
RC
196{
197 if (fp)
198 return fwrite (buffer, 1, len, fp);
199 return 0;
200}
201
7c7034e8
RC
202ssize_t
203io_stream_cygfile::peek (void *buffer, size_t len)
b24c88b3
RC
204{
205 log (LOG_TIMESTAMP, "io_stream_cygfile::peek called");
206 if (fp)
207 {
7c7034e8
RC
208 int pos = ftell (fp);
209 ssize_t rv = fread (buffer, 1, len, fp);
b24c88b3
RC
210 fseek (fp, pos, SEEK_SET);
211 return rv;
212 }
213 return 0;
214}
215
216long
217io_stream_cygfile::tell ()
218{
219 if (fp)
220 {
221 return ftell (fp);
222 }
223 return 0;
224}
225
ca9506cc
RC
226int
227io_stream_cygfile::seek (long where, io_stream_seek_t whence)
228{
229 if (fp)
7c7034e8
RC
230 {
231 return fseek (fp, where, (int) whence);
232 }
ca9506cc
RC
233 lasterr = EBADF;
234 return -1;
235}
236
b24c88b3
RC
237int
238io_stream_cygfile::error ()
239{
240 if (fp)
241 return ferror (fp);
242 return lasterr;
243}
244
245int
246cygmkdir_p (int isadir, const char *name)
247{
248 if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0])
249 return 1;
250 get_root_dir_now ();
251 if (!get_root_dir ())
252 /* TODO: assign a errno for "no mount table :} " */
253 return 1;
254 return mkdir_p (isadir, cygpath (name, 0));
255}
256
b24c88b3
RC
257int
258io_stream_cygfile::set_mtime (int mtime)
259{
260 if (!fname)
261 return 1;
262 if (fp)
263 fclose (fp);
264 long long ftimev = mtime * NSPERSEC + FACTOR;
265 FILETIME ftime;
266 ftime.dwHighDateTime = ftimev >> 32;
267 ftime.dwLowDateTime = ftimev;
268 HANDLE h =
269 CreateFileA (fname, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
270 0, OPEN_EXISTING,
271 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
272 if (h)
273 {
274 SetFileTime (h, 0, 0, &ftime);
275 CloseHandle (h);
bb849dbd 276#if 0
b24c88b3
RC
277 fp = fopen (fname, lmode);
278 if (!fp)
279 lasterr = errno;
bb849dbd 280#endif
b24c88b3
RC
281 return 0;
282 }
bb849dbd
RC
283#if 0
284// this results in truncated files.
285// also, semantically, it's nonsense, you cannot write to a file after setting the
286// mtime without changing the mtime
b24c88b3
RC
287 fp = fopen (fname, lmode);
288 if (!fp)
289 lasterr = errno;
bb849dbd 290#endif
b24c88b3
RC
291 return 1;
292}
7c7034e8
RC
293
294int
295io_stream_cygfile::move (char const *from, char const *to)
296{
297 if (!from || IsBadStringPtr (from, MAX_PATH) || !from[0] ||
298 !to || IsBadStringPtr (to, MAX_PATH) || !to[0])
299 return 1;
300 get_root_dir_now ();
301 if (!get_root_dir ())
302 /* TODO: assign a errno for "no mount table :} " */
303 return 1;
304 return rename (cygpath (from, 0), cygpath (to, 0));
305}
341988b9
RC
306
307size_t
308io_stream_cygfile::get_size ()
309{
310 if (!fname)
311 return 0;
312 return get_file_size (fname);
313}
This page took 0.054081 seconds and 5 git commands to generate.