* Simplified the recently introduced handling for symlinks a bit.

* Unfortunately it's not allowed to set user xattrs on symlinks. So, if
  we've failed in fs_write_attr() to set an extended attribute, we check
  whether the node is a symlink and the attribute just a "BEOS:TYPE",
  and pretend to have succeeded in this case. Thus we avoid annoying
  error messages e.g. in unzip.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22183 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-09-05 18:23:21 +00:00
parent 363d1373f4
commit 540d4f7b6e
1 changed files with 24 additions and 12 deletions

View File

@ -176,17 +176,11 @@ public:
// not a system FD, we need to get a path for it.
Descriptor* descriptor = get_descriptor(fileFD);
if (descriptor && !descriptor->IsSystemFD()) {
if (SymlinkDescriptor* symlinkDescriptor
= dynamic_cast<SymlinkDescriptor*>(descriptor)) {
status_t error = symlinkDescriptor->GetPath(tempPath);
if (error != B_OK)
return error;
path = tempPath.c_str();
fileFD = -1;
} else {
// We don't know how to get a path.
return B_BAD_VALUE;
}
status_t error = descriptor->GetPath(tempPath);
if (error != B_OK)
return error;
path = tempPath.c_str();
fileFD = -1;
}
}
@ -346,6 +340,18 @@ public:
return (fFD < 0 ? fPath.c_str() : NULL);
}
bool IsSymlink() const
{
struct stat st;
int result;
if (Path())
result = lstat(Path(), &st);
else
result = fstat(fFD, &st);
return (result == 0 && S_ISLNK(st.st_mode));
}
private:
string fPath;
int fFD;
@ -554,8 +560,14 @@ fs_write_attr(int fd, const char *_attribute, uint32 type, off_t pos,
result = fsetxattr(localFD.FD(), attribute.c_str(), attributeBuffer,
toWrite, 0);
}
if (result < 0)
if (result < 0) {
// Setting user attributes on symlinks is not allowed. So, if this is
// a symlink and we're only supposed to write a "BEOS:TYPE" attribute
// we silently pretend to have succeeded.
if (localFD.IsSymlink() && strcmp(_attribute, "BEOS:TYPE") == 0)
return writeBytes;
return -1;
}
return writeBytes;
}