unsigned int CSMBFile::Read(void *lpBuf, int64_t uiBufSize) { if (m_fd == -1) return 0; CSingleLock lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); /* work around stupid bug in samba */ /* some samba servers has a bug in it where the */ /* 17th bit will be ignored in a request of data */ /* this can lead to a very small return of data */ /* also worse, a request of exactly 64k will return */ /* as if eof, client has a workaround for windows */ /* thou it seems other servers are affected too */ if( uiBufSize >= 64*1024-2 ) uiBufSize = 64*1024-2; int bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); if ( bytesRead < 0 && errno == EINVAL ) { CLog::Log(LOGERROR, "%s - Error( %d, %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno)); bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); } if ( bytesRead < 0 ) { CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno)); return 0; } return (unsigned int)bytesRead; }
ssize_t CSMBFile::Read(void *lpBuf, size_t uiBufSize) { if (uiBufSize > SSIZE_MAX) uiBufSize = SSIZE_MAX; if (m_fd == -1) return -1; // Some external libs (libass) use test read with zero size and // null buffer pointer to check whether file is readable, but // libsmbclient always return "-1" if called with null buffer // regardless of buffer size. // To overcome this, force return "0" in that case. if (uiBufSize == 0 && lpBuf == NULL) return 0; CSingleLock lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); ssize_t bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); if (m_allowRetry && bytesRead < 0 && errno == EINVAL ) { CLog::Log(LOGERROR, "%s - Error( %" PRIdS ", %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno)); bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); } if ( bytesRead < 0 ) CLog::Log(LOGERROR, "%s - Error( %" PRIdS ", %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno)); return bytesRead; }
ssize_t CSMBFile::Read(void *lpBuf, size_t uiBufSize) { if (uiBufSize > SSIZE_MAX) uiBufSize = SSIZE_MAX; if (m_fd == -1) return -1; // Some external libs (libass) use test read with zero size and // null buffer pointer to check whether file is readable, but // libsmbclient always return "-1" if called with null buffer // regardless of buffer size. // To overcome this, force return "0" in that case. if (uiBufSize == 0 && lpBuf == NULL) return 0; CSingleLock lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); /* work around stupid bug in samba */ /* some samba servers has a bug in it where the */ /* 17th bit will be ignored in a request of data */ /* this can lead to a very small return of data */ /* also worse, a request of exactly 64k will return */ /* as if eof, client has a workaround for windows */ /* thou it seems other servers are affected too */ // FIXME: does this workaround still required? ssize_t totalRead = 0; uint8_t* buf = (uint8_t*)lpBuf; do { const ssize_t readSize = (uiBufSize >= 64 * 1024 - 2) ? 64 * 1024 - 2 : uiBufSize; ssize_t r = smbc_read(m_fd, buf + totalRead, readSize); if (r < 0) { if (errno == EINVAL) { CLog::LogF(LOGWARNING, "Error %d: \"%s\" - Retrying", errno, strerror(errno)); r = smbc_read(m_fd, buf + totalRead, readSize); } if (r < 0) { CLog::LogF(LOGERROR, "Error %d: \"%s\"", errno, strerror(errno)); if (totalRead == 0) return -1; break; } } totalRead += r; uiBufSize -= r; if (r != readSize) break; } while (uiBufSize > 0); return totalRead; }
int64_t CSMBFile::Seek(int64_t iFilePosition, int iWhence) { if (m_fd == -1) return -1; CSingleLock lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); int64_t pos = smbc_lseek(m_fd, iFilePosition, iWhence); if ( pos < 0 ) { CLog::Log(LOGERROR, "%s - Error( %" PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno)); return -1; } return (int64_t)pos; }
ssize_t CSMBFile::Read(void *lpBuf, size_t uiBufSize) { if (uiBufSize > SSIZE_MAX) uiBufSize = SSIZE_MAX; if (m_fd == -1) return -1; // Some external libs (libass) use test read with zero size and // null buffer pointer to check whether file is readable, but // libsmbclient always return "-1" if called with null buffer // regardless of buffer size. // To overcome this, force return "0" in that case. if (uiBufSize == 0 && lpBuf == NULL) return 0; CSingleLock lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); /* work around stupid bug in samba */ /* some samba servers has a bug in it where the */ /* 17th bit will be ignored in a request of data */ /* this can lead to a very small return of data */ /* also worse, a request of exactly 64k will return */ /* as if eof, client has a workaround for windows */ /* thou it seems other servers are affected too */ if( uiBufSize >= 64*1024-2 ) uiBufSize = 64*1024-2; ssize_t bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); if (m_allowRetry && bytesRead < 0 && errno == EINVAL ) { CLog::Log(LOGERROR, "%s - Error( %" PRIdS ", %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno)); bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize); } if ( bytesRead < 0 ) CLog::Log(LOGERROR, "%s - Error( %" PRIdS ", %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno)); return bytesRead; }
int64_t CSmbFile::Seek(int64_t iFilePosition, int iWhence) { if (m_fd == -1) return -1; CSingleLock lock(smb); // Init not called since it has to be "inited" by now #ifdef TARGET_POSIX smb.SetActivityTime(); #endif int64_t pos = smbc_lseek(m_fd, iFilePosition, iWhence); if ( pos < 0 ) { #ifdef TARGET_WINDOWS CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno))); #else CLog::Log(LOGERROR, "%s - Error( %"PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno)); #endif return -1; } return (int64_t)pos; }