2679
|
1 This file is part of MXE. |
|
2 See index.html for further information. |
|
3 |
|
4 This patch has been taken from: |
|
5 http://dev.exiv2.org/projects/exiv2/repository/revisions/2796 |
|
6 |
|
7 Index: trunk/src/basicio.cpp |
|
8 =================================================================== |
|
9 --- trunk/src/basicio.cpp (revision 2795) |
|
10 +++ trunk/src/basicio.cpp (revision 2796) |
|
11 @@ -61,6 +61,11 @@ |
|
12 # include <unistd.h> // for getpid, stat |
|
13 #endif |
|
14 |
|
15 +// Platform specific headers for handling extended attributes (xattr) |
|
16 +#if defined(__APPLE__) |
|
17 +# include <sys/xattr.h> |
|
18 +#endif |
|
19 + |
|
20 #if defined WIN32 && !defined __CYGWIN__ |
|
21 // Windows doesn't provide mode_t, nlink_t |
|
22 typedef unsigned short mode_t; |
|
23 @@ -131,6 +136,8 @@ |
|
24 int switchMode(OpMode opMode); |
|
25 //! stat wrapper for internal use |
|
26 int stat(StructStat& buf) const; |
|
27 + //! copy extended attributes (xattr) from another file |
|
28 + void copyXattrFrom(const FileIo& src); |
|
29 #if defined WIN32 && !defined __CYGWIN__ |
|
30 // Windows function to determine the number of hardlinks (on NTFS) |
|
31 DWORD winNumberOfLinks() const; |
|
32 @@ -252,6 +259,47 @@ |
|
33 return ret; |
|
34 } // FileIo::Impl::stat |
|
35 |
|
36 + void FileIo::Impl::copyXattrFrom(const FileIo& src) |
|
37 + { |
|
38 +#if defined(__APPLE__) |
|
39 +# if defined(EXV_UNICODE_PATH) |
|
40 +# error No xattr API for MacOS X with unicode support |
|
41 +# endif |
|
42 + const ssize_t namebufSize = ::listxattr(src.p_->path_.c_str(), 0, 0, 0); |
|
43 + if (namebufSize < 0) { |
|
44 + throw Error(2, src.p_->path_, strError(), "listxattr"); |
|
45 + } |
|
46 + if (namebufSize == 0) { |
|
47 + // No extended attributes in source file |
|
48 + return; |
|
49 + } |
|
50 + char namebuf[namebufSize]; |
|
51 + if (::listxattr(src.p_->path_.c_str(), namebuf, sizeof(namebuf), 0) != namebufSize) { |
|
52 + throw Error(2, src.p_->path_, strError(), "listxattr"); |
|
53 + } |
|
54 + for (ssize_t namebufPos = 0; namebufPos < namebufSize;) { |
|
55 + const char *name = namebuf + namebufPos; |
|
56 + namebufPos += strlen(name) + 1; |
|
57 + const ssize_t valueSize = ::getxattr(src.p_->path_.c_str(), name, 0, 0, 0, 0); |
|
58 + if (valueSize < 0) { |
|
59 + throw Error(2, src.p_->path_, strError(), "getxattr"); |
|
60 + } |
|
61 + char value[valueSize]; |
|
62 + if (::getxattr(src.p_->path_.c_str(), name, value, sizeof(value), 0, 0) != valueSize) { |
|
63 + throw Error(2, src.p_->path_, strError(), "getxattr"); |
|
64 + } |
|
65 +#ifdef DEBUG |
|
66 + EXV_DEBUG << "Copying xattr \"" << name << "\" with value size " << valueSize << "\n"; |
|
67 +#endif |
|
68 + if (::setxattr(path_.c_str(), name, value, valueSize, 0, 0) != 0) { |
|
69 + throw Error(2, path_, strError(), "setxattr"); |
|
70 + } |
|
71 + } |
|
72 +#else |
|
73 + // No xattr support for this platform. |
|
74 +#endif |
|
75 + } // FileIo::Impl::copyXattrFrom |
|
76 + |
|
77 #if defined WIN32 && !defined __CYGWIN__ |
|
78 DWORD FileIo::Impl::winNumberOfLinks() const |
|
79 { |
|
80 @@ -521,6 +569,7 @@ |
|
81 throw Error(10, path(), "w+b", strError()); |
|
82 } |
|
83 } |
|
84 + fileIo->p_->copyXattrFrom(*this); |
|
85 basicIo = fileIo; |
|
86 } |
|
87 else { |