]> git.lyx.org Git - lyx.git/blob - src/support/fs_extras.C
whitespace cleanup
[lyx.git] / src / support / fs_extras.C
1 // -*- C++ -*-
2 /* \file fs_extras.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11
12 #include <config.h>
13
14 #include "fs_extras.h"
15
16 #include <boost/filesystem/config.hpp>
17 #include <boost/filesystem/exception.hpp>
18 #include <boost/detail/workaround.hpp>
19 #include <boost/throw_exception.hpp>
20
21 #ifdef HAVE_SYS_TYPES_H
22 # include <sys/types.h>
23 #endif
24 #ifdef HAVE_SYS_STAT_H
25 # include <sys/stat.h>
26 #endif
27 #include <fcntl.h>
28
29 // BOOST_POSIX or BOOST_WINDOWS specify which API to use.
30 # if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
31 #   if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
32 #     define BOOST_WINDOWS
33 #   else
34 #     define BOOST_POSIX
35 #   endif
36 # endif
37
38 #if defined (BOOST_WINDOWS)
39 # define WIN32_LEAN_AND_MEAN
40 # include <windows.h>
41 #endif
42
43 namespace fs = boost::filesystem;
44
45 namespace boost {
46 namespace filesystem {
47
48 bool is_readable(path const & ph)
49 {
50 #ifdef BOOST_POSIX
51         return ::access(ph.string().c_str(), R_OK) == 0;
52 #endif
53 #ifdef BOOST_WINDOWS
54         DWORD const attr = ::GetFileAttributes(ph.string().c_str());
55         return attr != INVALID_FILE_ATTRIBUTES &&
56                 (attr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY;
57 #endif
58 }
59
60
61 bool is_writable(path const & ph)
62 {
63 #ifdef BOOST_POSIX
64         return ::access(ph.string().c_str(), W_OK) == 0;
65 #endif
66 #ifdef BOOST_WINDOWS
67         DWORD const attr = ::GetFileAttributes(ph.string().c_str());
68         if (attr != INVALID_FILE_ATTRIBUTES &&
69             (attr & FILE_ATTRIBUTE_READONLY) != 0) {
70                 // Read-only - no write access
71                 return false;
72         }
73         return attr != INVALID_FILE_ATTRIBUTES &&
74                 (attr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY;
75 #endif
76 }
77
78
79 bool is_readonly(path const & ph)
80 {
81 #ifdef BOOST_POSIX
82         return is_readable(ph) && !is_writable(ph);
83 #endif
84 #ifdef BOOST_WINDOWS
85         DWORD const attr = ::GetFileAttributes(ph.string().c_str());
86         return (attr != INVALID_FILE_ATTRIBUTES
87                 && (attr & FILE_ATTRIBUTE_READONLY));
88 #endif
89 }
90
91
92 void copy_file(path const & source, path const & target, bool noclobber)
93 {
94
95 #ifdef BOOST_POSIX
96         int const infile = ::open(source.string().c_str(), O_RDONLY);
97         if (infile == -1) {
98                 boost::throw_exception(
99                         filesystem_error(
100                                 "boost::filesystem::copy_file",
101                                 source, target,
102                                 fs::detail::system_error_code()));
103         }
104
105         struct stat source_stat;
106         int const ret = ::fstat(infile, &source_stat);
107         if (ret == -1) {
108                 ::close(infile);
109                 boost::throw_exception(
110                         filesystem_error(
111                                 "boost::filesystem::copy_file",
112                                 source, target,
113                                 fs::detail::system_error_code()));
114         }
115
116         int const flags = O_WRONLY | O_CREAT | (noclobber ? O_EXCL : O_TRUNC);
117
118         int const outfile = ::open(target.string().c_str(), flags, source_stat.st_mode);
119         if (outfile == -1) {
120                 ::close(infile);
121                 boost::throw_exception(
122                         filesystem_error(
123                                 "boost::filesystem::copy_file",
124                                 source, target,
125                                 fs::detail::system_error_code()));
126         }
127
128         std::size_t const buf_sz = 32768;
129         char buf[buf_sz];
130         ssize_t in = -1;
131         ssize_t out = -1;
132
133         while (true) {
134                 in = ::read(infile, buf, buf_sz);
135                 if (in == -1) {
136                         break;
137                 } else if (in == 0) {
138                         break;
139                 } else {
140                         out = ::write(outfile, buf, in);
141                         if (out == -1) {
142                                 break;
143                         }
144                 }
145         }
146
147         ::close(infile);
148         ::close(outfile);
149
150         if (in == -1 || out == -1)
151                 boost::throw_exception(
152                         filesystem_error(
153                                 "boost::filesystem::copy_file",
154                                 source, target,
155                                 fs::detail::system_error_code()));
156 #endif
157 #ifdef BOOST_WINDOWS
158         if (::CopyFile(source.string().c_str(), target.string().c_str(), noclobber) == 0) {
159                 boost::throw_exception(
160                         filesystem_error(
161                                 "boost::filesystem::copy_file",
162                                 source, target,
163                                 fs::detail::system_error_code()));
164         }
165 #endif
166 }
167
168 }
169 }