static int s3fs_readlink()

in src/s3fs.cpp [801:881]


static int s3fs_readlink(const char* _path, char* buf, size_t size)
{
    if(!_path || !buf || 0 == size){
        return 0;
    }
    WTF8_ENCODE(path)
    std::string strValue;

    S3FS_PRN_INFO("[path=%s]", path);

    // check symbolic link cache
    if(!StatCache::getStatCacheData()->GetSymlink(std::string(path), strValue)){
        // not found in cache, then open the path
        {   // scope for AutoFdEntity
            AutoFdEntity autoent;
            FdEntity*    ent;
            int          result;
            if(0 != (result = get_local_fent(autoent, &ent, path, O_RDONLY))){
                S3FS_PRN_ERR("could not get fent(file=%s)", path);
                return result;
            }

            // Get symlink attr
            std::string  strType;
            std::string strTarget;
            if (!ent->GetSymlinkAttr(strType, strTarget)) {
                // Do nothing
            }

            off_t readsize;
            if (strType == "header") {
                if(strTarget.empty()){
                    S3FS_PRN_ERR("could not get symlink target");
                    return -EIO;
                }
                readsize = strTarget.length();
                if(static_cast<off_t>(size) <= readsize){
                    readsize = size - 1;
                }
                memcpy(buf, strTarget.c_str(), readsize);
                buf[readsize] = '\0';
            } else {
                // Get size
                if(!ent->GetSize(readsize)){
                    S3FS_PRN_ERR("could not get file size(file=%s)", path);
                    return -EIO;
                }
                if(static_cast<off_t>(size) <= readsize){
                    readsize = size - 1;
                }
                // Read
                ssize_t ressize;
                if(0 > (ressize = ent->Read(autoent.GetPseudoFd(), buf, 0, readsize))){
                    S3FS_PRN_ERR("could not read file(file=%s, ressize=%zd)", path, ressize);
                    return static_cast<int>(ressize);
                }
                buf[ressize] = '\0';
            }
        }

        // check buf if it has space words.
        strValue = trim(std::string(buf));

        // decode wtf8. This will always be shorter
        if(use_wtf8){
          strValue = s3fs_wtf8_decode(strValue);
        }

        // add symbolic link cache
        if(!StatCache::getStatCacheData()->AddSymlink(std::string(path), strValue)){
          S3FS_PRN_ERR("failed to add symbolic link cache for %s", path);
        }
    }
    // copy result
    strncpy(buf, strValue.c_str(), size - 1);
    buf[size - 1] = '\0';

    S3FS_MALLOCTRIM(0);

    return 0;
}