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