📄 osutil.cxx
字号:
entryPtr = ::readdir_r(directory, entryBuffer);
if (entryPtr == NULL)
return FALSE;
#else
if ((entryPtr = ::readdir(directory)) == NULL)
return FALSE;
*entryBuffer = *entryPtr;
strcpy(entryBuffer->d_name, entryPtr->d_name);
#endif
} while (strcmp(entryBuffer->d_name, "." ) == 0 || strcmp(entryBuffer->d_name, "..") == 0);
/* Ignore this file if we can't get info about it */
if (PFile::GetInfo(*this+entryBuffer->d_name, *entryInfo) == 0)
continue;
if (scanMask == PFileInfo::AllPermissions)
return TRUE;
} while ((entryInfo->type & scanMask) == 0);
return TRUE;
}
BOOL PDirectory::IsSubDir() const
{
if (entryInfo == NULL)
return FALSE;
return entryInfo->type == PFileInfo::SubDirectory;
}
BOOL PDirectory::Restart(int newScanMask)
{
scanMask = newScanMask;
if (directory != NULL)
rewinddir(directory);
return TRUE;
}
PString PDirectory::GetEntryName() const
{
if (entryBuffer == NULL)
return PString();
return entryBuffer->d_name;
}
BOOL PDirectory::GetInfo(PFileInfo & info) const
{
if (entryInfo == NULL)
return FALSE;
info = *entryInfo;
return TRUE;
}
BOOL PDirectory::Exists(const PString & p)
{
struct stat sbuf;
if (stat((const char *)p, &sbuf) != 0)
return FALSE;
return S_ISDIR(sbuf.st_mode);
}
BOOL PDirectory::Create(const PString & p, int perm)
{
PAssert(!p.IsEmpty(), "attempt to create dir with empty name");
PINDEX last = p.GetLength()-1;
PString str = p;
if (p[last] == '/')
str = p.Left(last);
#ifdef P_VXWORKS
return mkdir(str) == 0;
#else
return mkdir(str, perm) == 0;
#endif
}
BOOL PDirectory::Remove(const PString & p)
{
PAssert(!p.IsEmpty(), "attempt to remove dir with empty name");
PString str = p.Left(p.GetLength()-1);
return rmdir(str) == 0;
}
PString PDirectory::GetVolume() const
{
PString volume;
#if defined(P_QNX)
int fd;
char mounton[257];
if ((fd = open(operator+("."), O_RDONLY)) != -1) {
mounton[256] = 0;
devctl(fd, DCMD_FSYS_MOUNTED_ON, mounton, 256, 0);
close(fd);
volume = strdup(mounton);
}
#else
struct stat status;
if (stat(operator+("."), &status) != -1) {
dev_t my_dev = status.st_dev;
#if defined(P_LINUX) || defined(P_IRIX)
FILE * fp = setmntent(MOUNTED, "r");
if (fp != NULL) {
struct mntent * mnt;
while ((mnt = getmntent(fp)) != NULL) {
if (stat(mnt->mnt_dir, &status) != -1 && status.st_dev == my_dev) {
volume = mnt->mnt_fsname;
break;
}
}
}
endmntent(fp);
#elif defined(P_SOLARIS)
FILE * fp = fopen("/etc/mnttab", "r");
if (fp != NULL) {
struct mnttab mnt;
while (getmntent(fp, &mnt) == 0) {
if (stat(mnt.mnt_mountp, &status) != -1 && status.st_dev == my_dev) {
volume = mnt.mnt_special;
break;
}
}
}
fclose(fp);
#elif defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_MACOSX) || defined(P_MACOS)
struct statfs * mnt;
int count = getmntinfo(&mnt, MNT_NOWAIT);
for (int i = 0; i < count; i++) {
if (stat(mnt[i].f_mntonname, &status) != -1 && status.st_dev == my_dev) {
volume = mnt[i].f_mntfromname;
break;
}
}
#elif defined (P_AIX)
struct fstab * fs;
setfsent();
while ((fs = getfsent()) != NULL) {
if (stat(fs->fs_file, &status) != -1 && status.st_dev == my_dev) {
volume = fs->fs_spec;
break;
}
}
endfsent();
#elif defined (P_VXWORKS)
PAssertAlways("Get Volume - not implemented for VxWorks");
return PString::Empty();
#else
#warning Platform requires implemetation of GetVolume()
#endif
}
#endif
return volume;
}
BOOL PDirectory::GetVolumeSpace(PInt64 & total, PInt64 & free, DWORD & clusterSize) const
{
#if defined(P_LINUX) || defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_MACOSX) || defined(P_MACOS)
struct statfs fs;
if (statfs(operator+("."), &fs) == -1)
return FALSE;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bavail*(PInt64)fs.f_bsize;
return TRUE;
#elif defined(P_AIX) || defined(P_VXWORKS)
struct statfs fs;
if (statfs((char *) ((const char *)operator+(".") ), &fs) == -1)
return FALSE;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bavail*(PInt64)fs.f_bsize;
return TRUE;
#elif defined(P_SOLARIS)
struct statvfs buf;
if (statvfs(operator+("."), &buf) != 0)
return FALSE;
clusterSize = buf.f_frsize;
total = buf.f_blocks * buf.f_frsize;
free = buf.f_bfree * buf.f_frsize;
return TRUE;
#elif defined(P_IRIX)
struct statfs fs;
if (statfs(operator+("."), &fs, sizeof(struct statfs), 0) == -1)
return FALSE;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bfree*(PInt64)fs.f_bsize;
return TRUE;
#elif defined(P_QNX)
struct statvfs fs;
if (statvfs(operator+("."), &fs) == -1)
return FALSE;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bavail*(PInt64)fs.f_bsize;
return TRUE;
#else
#warning Platform requires implemetation of GetVolumeSpace()
return FALSE;
#endif
}
PDirectory PDirectory::GetParent() const
{
if (IsRoot())
return *this;
return *this + "..";
}
PStringArray PDirectory::GetPath() const
{
PStringArray path;
if (IsEmpty())
return path;
PStringArray tokens = Tokenise("/");
path.SetSize(tokens.GetSize()+1);
PINDEX count = 1; // First path field is volume name, empty under unix
for (PINDEX i = 0; i < tokens.GetSize(); i++) {
if (!tokens[i])
path[count++] = tokens[i];
}
path.SetSize(count);
return path;
}
///////////////////////////////////////////////////////////////////////////////
//
// PFile
//
void PFile::SetFilePath(const PString & newName)
{
PINDEX p;
if ((p = newName.FindLast('/')) == P_MAX_INDEX)
path = CanonicaliseDirectory("") + newName;
else
path = CanonicaliseDirectory(newName(0,p)) + newName(p+1, P_MAX_INDEX);
}
BOOL PFile::Open(OpenMode mode, int opt)
{
Close();
clear();
if (opt > 0)
removeOnClose = (opt & Temporary) != 0;
if (path.IsEmpty()) {
char templateStr[3+6+1];
strcpy(templateStr, "PWL");
#ifndef P_VXWORKS
#ifdef P_RTEMS
_reent _reent_data;
memset(&_reent_data, 0, sizeof(_reent_data));
os_handle = _mkstemp_r(&_reent_data, templateStr);
#else
os_handle = mkstemp(templateStr);
#endif // P_RTEMS
if (!ConvertOSError(os_handle))
return FALSE;
} else {
#else
static int number = 0;
sprintf(templateStr+3, "%06d", number++);
path = templateStr;
}
{
#endif // !P_VXWORKS
int oflags = 0;
switch (mode) {
case ReadOnly :
oflags |= O_RDONLY;
if (opt == ModeDefault)
opt = MustExist;
break;
case WriteOnly :
oflags |= O_WRONLY;
if (opt == ModeDefault)
opt = Create|Truncate;
break;
case ReadWrite :
oflags |= O_RDWR;
if (opt == ModeDefault)
opt = Create;
break;
default :
PAssertAlways(PInvalidParameter);
}
if ((opt&Create) != 0)
oflags |= O_CREAT;
if ((opt&Exclusive) != 0)
oflags |= O_EXCL;
if ((opt&Truncate) != 0)
oflags |= O_TRUNC;
if (!ConvertOSError(os_handle = PX_NewHandle(GetClass(), ::open(path, oflags, DEFAULT_FILE_MODE))))
return FALSE;
}
#ifndef P_VXWORKS
return ConvertOSError(::fcntl(os_handle, F_SETFD, 1));
#else
return TRUE;
#endif
}
BOOL PFile::SetLength(off_t len)
{
return ConvertOSError(ftruncate(GetHandle(), len));
}
BOOL PFile::Rename(const PFilePath & oldname, const PString & newname, BOOL force)
{
if (newname.Find('/') != P_MAX_INDEX) {
errno = EINVAL;
return FALSE;
}
if (rename(oldname, oldname.GetPath() + newname) == 0)
return TRUE;
if (!force || errno == ENOENT || !Exists(newname))
return FALSE;
if (!Remove(newname, TRUE))
return FALSE;
return rename(oldname, oldname.GetPath() + newname) == 0;
}
BOOL PFile::Move(const PFilePath & oldname, const PFilePath & newname, BOOL force)
{
PFilePath from = oldname.GetDirectory() + oldname.GetFileName();
PFilePath to = newname.GetDirectory() + newname.GetFileName();
if (rename(from, to) == 0)
return TRUE;
if (errno == EXDEV)
return Copy(from, to, force) && Remove(from);
if (force && errno == EEXIST)
if (Remove(to, TRUE))
if (rename(from, to) == 0)
return TRUE;
return FALSE;
}
BOOL PFile::Exists(const PFilePath & name)
{
#ifdef P_VXWORKS
// access function not defined for VxWorks
// as workaround, open the file in read-only mode
// if it succeeds, the file exists
PFile file(name, ReadOnly, MustExist);
BOOL exists = file.IsOpen();
if(exists == TRUE)
file.Close();
return exists;
#else
return access(name, 0) == 0;
#endif // P_VXWORKS
}
BOOL PFile::Access(const PFilePath & name, OpenMode mode)
{
#ifdef P_VXWORKS
// access function not defined for VxWorks
// as workaround, open the file in specified mode
// if it succeeds, the access is allowed
PFile file(name, mode, ModeDefault);
BOOL access = file.IsOpen();
if(access == TRUE)
file.Close();
return access;
#else
int accmode;
switch (mode) {
case ReadOnly :
accmode = R_OK;
break;
case WriteOnly :
accmode = W_OK;
break;
default :
accmode = R_OK | W_OK;
}
return access(name, accmode) == 0;
#endif // P_VXWORKS
}
BOOL PFile::GetInfo(const PFilePath & name, PFileInfo & status)
{
status.type = PFileInfo::UnknownFileType;
struct stat s;
#ifdef P_VXWORKS
if (stat(name, &s) != OK)
#else
if (lstat(name, &s) != 0)
#endif // P_VXWORKS
return FALSE;
#ifndef P_VXWORKS
if (S_ISLNK(s.st_mode)) {
status.type = PFileInfo::SymbolicLink;
if (stat(name, &s) != 0) {
status.created = 0;
status.modified = 0;
status.accessed = 0;
status.size = 0;
status.permissions = PFileInfo::AllPermissions;
return TRUE;
}
}
else
#endif // !P_VXWORKS
if (S_ISREG(s.st_mode))
status.type = PFileInfo::RegularFile;
else if (S_ISDIR(s.st_mode))
status.type = PFileInfo::SubDirectory;
else if (S_ISFIFO(s.st_mode))
status.type = PFileInfo::Fifo;
else if (S_ISCHR(s.st_mode))
status.type = PFileInfo::CharDevice;
else if (S_ISBLK(s.st_mode))
status.type = PFileInfo::BlockDevice;
#if !defined(__BEOS__) && !defined(P_VXWORKS)
else if (S_ISSOCK(s.st_mode))
status.type = PFileInfo::SocketDevice;
#endif // !__BEOS__ || !P_VXWORKS
status.created = s.st_ctime;
status.modified = s.st_mtime;
status.accessed = s.st_atime;
status.size = s.st_size;
status.permissions = s.st_mode & PFileInfo::AllPermissions;
return TRUE;
}
BOOL PFile::SetPermissions(const PFilePath & name, int permissions)
{
mode_t mode = 0;
mode |= S_IROTH;
mode |= S_IRGRP;
if (permissions & PFileInfo::WorldExecute)
mode |= S_IXOTH;
if (permissions & PFileInfo::WorldWrite)
mode |= S_IWOTH;
if (permissions & PFileInfo::WorldRead)
mode |= S_IROTH;
if (permissions & PFileInfo::GroupExecute)
mode |= S_IXGRP;
if (permissions & PFileInfo::GroupWrite)
mode |= S_IWGRP;
if (permissions & PFileInfo::GroupRead)
mode |= S_IRGRP;
if (permissions & PFileInfo::UserExecute)
mode |= S_IXUSR;
if (permissions & PFileInfo::UserWrite)
mode |= S_IWUSR;
if (permissions & PFileInfo::UserRead)
mode |= S_IRUSR;
#ifdef P_VXWORKS
PFile file(name, ReadOnly, MustExist);
if (file.IsOpen())
return (::ioctl(file.GetHandle(), FIOATTRIBSET, mode) >= 0);
return FALSE;
#else
return chmod ((const char *)name, mode) == 0;
#endif // P_VXWORKS
}
///////////////////////////////////////////////////////////////////////////////
// PTextFile
BOOL PTextFile::WriteLine (const PString & line)
{
if (!Write((const char *)line, line.GetLength()))
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -