summaryrefslogtreecommitdiffstats
path: root/src/exiv2-r2796.patch
blob: 34332da0c87f4a67351d459fd75d6270c01c16cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
This file is part of MXE.
See index.html for further information.

This patch has been taken from:
http://dev.exiv2.org/projects/exiv2/repository/revisions/2796

Index: trunk/src/basicio.cpp
===================================================================
--- trunk/src/basicio.cpp	(revision 2795)
+++ trunk/src/basicio.cpp	(revision 2796)
@@ -61,6 +61,11 @@
 # include <unistd.h>                    // for getpid, stat
 #endif
 
+// Platform specific headers for handling extended attributes (xattr)
+#if defined(__APPLE__)
+# include <sys/xattr.h>
+#endif
+
 #if defined WIN32 && !defined __CYGWIN__
 // Windows doesn't provide mode_t, nlink_t
 typedef unsigned short mode_t;
@@ -131,6 +136,8 @@
         int switchMode(OpMode opMode);
         //! stat wrapper for internal use
         int stat(StructStat& buf) const;
+        //! copy extended attributes (xattr) from another file
+        void copyXattrFrom(const FileIo& src);
 #if defined WIN32 && !defined __CYGWIN__
         // Windows function to determine the number of hardlinks (on NTFS)
         DWORD winNumberOfLinks() const;
@@ -252,6 +259,47 @@
         return ret;
     } // FileIo::Impl::stat
 
+    void FileIo::Impl::copyXattrFrom(const FileIo& src)
+    {
+#if defined(__APPLE__)
+# if defined(EXV_UNICODE_PATH)
+#  error No xattr API for MacOS X with unicode support
+# endif
+        const ssize_t namebufSize = ::listxattr(src.p_->path_.c_str(), 0, 0, 0);
+        if (namebufSize < 0) {
+            throw Error(2, src.p_->path_, strError(), "listxattr");
+        }
+        if (namebufSize == 0) {
+            // No extended attributes in source file
+            return;
+        }
+        char namebuf[namebufSize];
+        if (::listxattr(src.p_->path_.c_str(), namebuf, sizeof(namebuf), 0) != namebufSize) {
+            throw Error(2, src.p_->path_, strError(), "listxattr");
+        }
+        for (ssize_t namebufPos = 0; namebufPos < namebufSize;) {
+            const char *name = namebuf + namebufPos;
+            namebufPos += strlen(name) + 1;
+            const ssize_t valueSize = ::getxattr(src.p_->path_.c_str(), name, 0, 0, 0, 0);
+            if (valueSize < 0) {
+                throw Error(2, src.p_->path_, strError(), "getxattr");
+            }
+            char value[valueSize];
+            if (::getxattr(src.p_->path_.c_str(), name, value, sizeof(value), 0, 0) != valueSize) {
+                throw Error(2, src.p_->path_, strError(), "getxattr");
+            }
+#ifdef DEBUG
+            EXV_DEBUG << "Copying xattr \"" << name << "\" with value size " << valueSize << "\n";
+#endif
+            if (::setxattr(path_.c_str(), name, value, valueSize, 0, 0) != 0) {
+                throw Error(2, path_, strError(), "setxattr");
+            }
+        }
+#else
+        // No xattr support for this platform.
+#endif
+    } // FileIo::Impl::copyXattrFrom
+
 #if defined WIN32 && !defined __CYGWIN__
     DWORD FileIo::Impl::winNumberOfLinks() const
     {
@@ -521,6 +569,7 @@
                     throw Error(10, path(), "w+b", strError());
                 }
             }
+            fileIo->p_->copyXattrFrom(*this);
             basicIo = fileIo;
         }
         else {