2 * Copyright (c) 2001, Robert Collins.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
17 static const char *cvsid
=
32 #include "filemanip.h"
34 #include "io_stream.h"
35 #include "io_stream_cygfile.h"
38 #define FACTOR (0x19db1ded53ea710LL)
39 #define NSPERSEC 10000000LL
44 if (get_root_dir ().size())
49 io_stream_cygfile::io_stream_cygfile (String
const &name
, String
const &mode
) : fp(), fname()
52 if (!name
.size() || !mode
.size())
55 /* do this every time because the mount points may change due to fwd/back button use...
56 * TODO: make this less...manual
59 if (!get_root_dir ().size())
60 /* TODO: assign a errno for "no mount table :} " */
63 fname
= cygpath (name
.cstr_oneuse(), 0);
65 fp
= fopen (fname
.cstr_oneuse(), mode
.cstr_oneuse());
70 io_stream_cygfile::~io_stream_cygfile ()
79 io_stream_cygfile::exists (String
const &path
)
82 if (get_root_dir ().size() && _access (cygpath (path
.cstr_oneuse(), 0).cstr_oneuse(), 0) == 0)
88 io_stream_cygfile::remove (String
const &path
)
93 if (!get_root_dir ().size())
94 /* TODO: assign a errno for "no mount table :} " */
97 unsigned long w
= GetFileAttributes (cygpath (path
.cstr_oneuse(),0).cstr_oneuse());
98 if (w
!= 0xffffffff && w
& FILE_ATTRIBUTE_DIRECTORY
)
100 char tmp
[cygpath (path
.cstr_oneuse(),0).size() + 10];
105 sprintf (tmp
, "%s.old-%d", cygpath (path
.cstr_oneuse(),0).cstr_oneuse(), i
);
107 while (GetFileAttributes (tmp
) != 0xffffffff);
108 fprintf (stderr
, "warning: moving directory \"%s\" out of the way.\n",
110 MoveFile (cygpath (path
.cstr_oneuse(),0).cstr_oneuse(), tmp
);
112 return !DeleteFileA (cygpath (path
.cstr_oneuse(),0).cstr_oneuse());
116 io_stream_cygfile::mklink (String
const &from
, String
const &to
,
117 io_stream_link_t linktype
)
119 if (!from
.size() || !to
.size())
123 case IO_STREAM_SYMLINK
:
124 return mkcygsymlink (cygpath (from
.cstr_oneuse(),0).cstr_oneuse(), to
.cstr_oneuse());
125 case IO_STREAM_HARDLINK
:
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?
131 io_stream
*in
= io_stream::open (cygpath (to
.cstr_oneuse(),0), "rb");
134 log (LOG_TIMESTAMP
, String("could not open ") + to
+" for reading in mklink");
137 io_stream
*out
= io_stream::open (cygpath (from
.cstr_oneuse(),0), "wb");
140 log (LOG_TIMESTAMP
, String("could not open ")+ from
+ " for writing in mklink");
145 if (io_stream::copy (in
, out
))
147 log (LOG_TIMESTAMP
, String ("Failed to hardlink ")+ from
+ "->" +to
+
148 " during file copy.");
165 io_stream_cygfile::read (void *buffer
, size_t len
)
168 return fread (buffer
, 1, len
, fp
);
173 io_stream_cygfile::write (const void *buffer
, size_t len
)
176 return fwrite (buffer
, 1, len
, fp
);
181 io_stream_cygfile::peek (void *buffer
, size_t len
)
183 log (LOG_TIMESTAMP
, "io_stream_cygfile::peek called");
186 int pos
= ftell (fp
);
187 ssize_t rv
= fread (buffer
, 1, len
, fp
);
188 fseek (fp
, pos
, SEEK_SET
);
195 io_stream_cygfile::tell ()
205 io_stream_cygfile::seek (long where
, io_stream_seek_t whence
)
209 return fseek (fp
, where
, (int) whence
);
216 io_stream_cygfile::error ()
224 cygmkdir_p (enum path_type_t isadir
, String
const &name
)
229 if (!get_root_dir ().size())
230 /* TODO: assign a errno for "no mount table :} " */
232 return mkdir_p (isadir
== PATH_TO_DIR
? 1 : 0, cygpath (name
.cstr_oneuse(),0).cstr_oneuse());
236 io_stream_cygfile::set_mtime (int mtime
)
242 long long ftimev
= mtime
* NSPERSEC
+ FACTOR
;
244 ftime
.dwHighDateTime
= ftimev
>> 32;
245 ftime
.dwLowDateTime
= ftimev
;
247 CreateFileA (fname
.cstr_oneuse(), GENERIC_WRITE
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
249 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_BACKUP_SEMANTICS
, 0);
252 SetFileTime (h
, 0, 0, &ftime
);
255 fp
= fopen (fname
, lmode
);
262 // this results in truncated files.
263 // also, semantically, it's nonsense, you cannot write to a file after setting the
264 // mtime without changing the mtime
265 fp
= fopen (fname
, lmode
);
273 io_stream_cygfile::move (String
const &from
, String
const &to
)
275 if (!from
.size() || !to
.size())
278 if (!get_root_dir ().size())
279 /* TODO: assign a errno for "no mount table :} " */
281 return rename (cygpath (from
.cstr_oneuse(),0).cstr_oneuse(), cygpath (to
.cstr_oneuse(),0).cstr_oneuse());
285 io_stream_cygfile::get_size ()
289 return get_file_size (fname
);