# HG changeset patch # User František Kučera # Date 1704499588 -3600 # Node ID 2068a992e97e64f337b06a1d3c4cd89c5016d0b9 # Parent 808f05faab3010dccbde71cc930ace06af34f153 xattr: tolerate ENOTSUP (behave like there are no attributes when not supported on given FS) diff -r 808f05faab30 -r 2068a992e97e XAttrs.cpp --- a/XAttrs.cpp Sat Jan 06 00:41:26 2024 +0100 +++ b/XAttrs.cpp Sat Jan 06 01:06:28 2024 +0100 @@ -26,23 +26,30 @@ std::string xattrGet( const std::string fileName, const std::string name, - bool* exists = nullptr) { + bool* exists = nullptr, + bool* supported = nullptr) { std::string buffer; ssize_t size = getxattr(fileName.c_str(), name.c_str(), nullptr, 0); if (size > 0) { buffer.resize(size); getxattr(fileName.c_str(), name.c_str(), buffer.data(), buffer.size()); if (exists) *exists = true; + if (supported) *supported = true; return buffer; } else if (size == 0) { if (exists) *exists = true; + if (supported) *supported = true; return ""; } else if (errno == ENODATA) { if (exists) *exists = false; + if (supported) *supported = true; return ""; } else if (errno == ERANGE) { // rare race condition - the value has changed between the two calls return xattrGet(fileName, name, exists); + } else if (errno == ENOTSUP) { + if (supported) *supported = false; + return ""; } else { throw std::logic_error( std::string("Unable to get extended attribute: ") @@ -53,7 +60,8 @@ bool xattrSet(const std::string fileName, const std::string name, const std::string value, - bool exists = true) { + bool exists = true, + bool* supported = nullptr) { int result; if (exists) { result = setxattr( @@ -67,13 +75,16 @@ if (result < 0 && errno == ENODATA) return false; } - if (result < 0) throw std::logic_error( + if (result < 0 && errno == ENOTSUP && supported) *supported = false; + else if (result < 0) throw std::logic_error( std::string("Unable to set extended attribute: ") + strerror(errno)); - else return true; + + return true; } -std::vector xattrList(const std::string fileName) { +std::vector +xattrList(const std::string fileName, bool* supported = nullptr) { std::string buffer; ssize_t size = listxattr(fileName.c_str(), nullptr, 0); if (size >= 0) { @@ -84,10 +95,14 @@ for (const char* k = buffer.c_str(); strlen(k); k += strlen(k) + 1) { result.push_back(k); } + if (supported) *supported = true; return result; } else if (errno == ERANGE) { // rare race condition - the list has changed between the two calls return xattrList(fileName); + } else if (errno == ENOTSUP) { + if (supported) *supported = false; + return std::vector(); } else { throw std::logic_error( std::string("Unable to list extended attributes: ")