📄 osutil.cxx
字号:
#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;
}
PBoolean 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 PFalse;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bavail*(PInt64)fs.f_bsize;
return PTrue;
#elif defined(P_AIX) || defined(P_VXWORKS)
struct statfs fs;
if (statfs((char *) ((const char *)operator+(".") ), &fs) == -1)
return PFalse;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bavail*(PInt64)fs.f_bsize;
return PTrue;
#elif defined(P_SOLARIS)
struct statvfs buf;
if (statvfs(operator+("."), &buf) != 0)
return PFalse;
clusterSize = buf.f_frsize;
total = buf.f_blocks * buf.f_frsize;
free = buf.f_bfree * buf.f_frsize;
return PTrue;
#elif defined(P_IRIX)
struct statfs fs;
if (statfs(operator+("."), &fs, sizeof(struct statfs), 0) == -1)
return PFalse;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bfree*(PInt64)fs.f_bsize;
return PTrue;
#elif defined(P_QNX)
struct statvfs fs;
if (statvfs(operator+("."), &fs) == -1)
return PFalse;
clusterSize = fs.f_bsize;
total = fs.f_blocks*(PInt64)fs.f_bsize;
free = fs.f_bavail*(PInt64)fs.f_bsize;
return PTrue;
#else
#warning Platform requires implemetation of GetVolumeSpace()
return PFalse;
#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);
}
PBoolean 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, "PWLXXXXXX");
#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 PFalse;
path = templateStr;
} 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 PFalse;
}
#ifndef P_VXWORKS
return ConvertOSError(::fcntl(os_handle, F_SETFD, 1));
#else
return PTrue;
#endif
}
PBoolean PFile::SetLength(off_t len)
{
return ConvertOSError(ftruncate(GetHandle(), len));
}
PBoolean PFile::Rename(const PFilePath & oldname, const PString & newname, PBoolean force)
{
if (newname.Find('/') != P_MAX_INDEX) {
errno = EINVAL;
return PFalse;
}
if (rename(oldname, oldname.GetPath() + newname) == 0)
return PTrue;
if (!force || errno == ENOENT || !Exists(newname))
return PFalse;
if (!Remove(newname, PTrue))
return PFalse;
return rename(oldname, oldname.GetPath() + newname) == 0;
}
PBoolean PFile::Move(const PFilePath & oldname, const PFilePath & newname, PBoolean force)
{
PFilePath from = oldname.GetDirectory() + oldname.GetFileName();
PFilePath to = newname.GetDirectory() + newname.GetFileName();
if (rename(from, to) == 0)
return PTrue;
if (errno == EXDEV)
return Copy(from, to, force) && Remove(from);
if (force && errno == EEXIST)
if (Remove(to, PTrue))
if (rename(from, to) == 0)
return PTrue;
return PFalse;
}
PBoolean 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);
PBoolean exists = file.IsOpen();
if(exists == PTrue)
file.Close();
return exists;
#else
return access(name, 0) == 0;
#endif // P_VXWORKS
}
PBoolean 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);
PBoolean access = file.IsOpen();
if(access == PTrue)
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
}
PBoolean 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 PFalse;
#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 PTrue;
}
}
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 PTrue;
}
PBoolean 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 PFalse;
#else
return chmod ((const char *)name, mode) == 0;
#endif // P_VXWORKS
}
///////////////////////////////////////////////////////////////////////////////
// PTextFile
PBoolean PTextFile::WriteLine (const PString & line)
{
if (!Write((const char *)line, line.GetLength()))
return PFalse;
char ch = '\n';
return Write(&ch, 1);
}
PBoolean PTextFile::ReadLine (PString & line)
{
int len = 0;
int ch;
char * base, * ptr;
while (1) {
len += LINE_SIZE_STEP;
ptr = base = line.GetPointer(len) + len - LINE_SIZE_STEP;
while ((ptr - base) < LINE_SIZE_STEP-1) {
if ((ch = ReadChar()) < 0) {
ConvertOSError(errno);
return PFalse;
}
if (ch == '\n') {
*ptr = '\0';
line.MakeMinimumSize();
return PTrue;
}
*ptr++ = ch;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// PFilePath
PFilePath::PFilePath(const PString & str)
: PString(CanonicaliseFilename(str))
{
}
PFilePath::PFilePath(const char * cstr)
: PString(CanonicaliseFilename(cstr))
{
}
PFilePath::PFilePath(const char * prefix, const char * dir)
: PString()
{
if (prefix == NULL)
prefix = "tmp";
PDirectory s(dir);
if (dir == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -