xattr: tolerate ENOTSUP (behave like there are no attributes when not supported on given FS) v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 06 Jan 2024 01:06:28 +0100
branchv_0
changeset 39 2068a992e97e
parent 38 808f05faab30
child 40 df1376ef9f6d
xattr: tolerate ENOTSUP (behave like there are no attributes when not supported on given FS)
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<std::string> xattrList(const std::string fileName) {
+std::vector<std::string>
+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<std::string>();
 	} else {
 		throw std::logic_error(
 				std::string("Unable to list extended attributes: ")