⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osutil.cxx

📁 基于VXWORKS H323通信技术源代码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* 
 * osutil.cxx
 *
 * Operating System classes implementation
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: osutil.cxx,v $
 * Revision 1.48  1999/08/17 07:37:36  robertj
 * Fixed inlines so are inlined for optimised version
 *
 * Revision 1.47  1999/06/28 09:28:02  robertj
 * Portability issues, especially n BeOS (thanks Yuri!)
 *
 * Revision 1.46  1999/06/26 08:21:12  robertj
 * Fixed bug in PFilePath::SetType finding dots outside of file name in path.
 *
 * Revision 1.45  1999/06/14 08:39:57  robertj
 * Added PConsoleChannel class for access to stdin/stdout/stderr
 *
 * Revision 1.44  1999/06/09 04:08:46  robertj
 * Added support for opening stdin/stdout/stderr as PFile objects.
 *
 * Revision 1.43  1999/02/22 13:26:53  robertj
 * BeOS port changes.
 *
 * Revision 1.42  1998/12/12 01:06:24  robertj
 * Fixed off by one error in month on FreeBSD platform
 *
 * Revision 1.41  1998/11/30 21:51:43  robertj
 * New directory structure.
 *
 * Revision 1.40  1998/11/26 11:54:16  robertj
 * Fixed error return on PFile::GetInfo
 *
 * Revision 1.39  1998/11/24 09:39:09  robertj
 * FreeBSD port.
 *
 * Revision 1.38  1998/11/10 13:00:52  robertj
 * Fixed strange problems with readdir_r usage.
 *
 * Revision 1.37  1998/11/06 04:44:46  robertj
 * Solaris compatibility
 *
 * Revision 1.36  1998/11/05 12:03:13  robertj
 * Fixed solaris compatibility and Linux warning on readdir_r function.
 *
 * Revision 1.35  1998/11/05 09:05:55  craigs
 * Changed directory routines to use reenttrant functions, and added PDirectory::GetParent
 *
 * Revision 1.34  1998/09/24 07:39:49  robertj
 * Removed file that only had #pragma implmentation for PTextFile and nothing else.
 *
 * Revision 1.33  1998/09/24 04:12:12  robertj
 * Added open software license.
 *
 */

#define _OSUTIL_CXX

#pragma implementation "timer.h"
#pragma implementation "pdirect.h"
#pragma implementation "file.h"
#pragma implementation "textfile.h"
#pragma implementation "conchan.h"
#pragma implementation "ptime.h"
#pragma implementation "timeint.h"
#pragma implementation "filepath.h"
#pragma implementation "lists.h"
#pragma implementation "pstring.h"
#pragma implementation "dict.h"
#pragma implementation "array.h"
#pragma implementation "object.h"
#pragma implementation "contain.h"

#if defined(P_LINUX)
#define _REENTRANT
#elif defined(P_SOLARIS) 
#define _POSIX_PTHREAD_SEMANTICS
#endif

#include <ptlib.h>


#include <fcntl.h>
#include <time.h>
#if !defined(P_VXWORKS)	// added by Jurjan
#include <sys/time.h>
#endif
#include <ctype.h>

#if defined(P_LINUX)

#include <mntent.h>
#include <sys/vfs.h>

#define P_HAS_READDIR_R

#if (__GNUC_MINOR__ < 7)
#include <localeinfo.h>
#else
#define P_USE_LANGINFO
#endif

#elif defined(P_FREEBSD) 
#define P_USE_STRFTIME

#include <sys/param.h>
#include <sys/mount.h>

#elif defined(P_HPUX9) 
#define P_USE_LANGINFO

#elif defined(P_SOLARIS) 
#define P_HAS_READDIR_R
#define P_USE_LANGINFO
#include <sys/timeb.h>
#include <sys/statvfs.h>
#include <sys/mnttab.h>

#elif defined(P_SUN4)
#include <sys/timeb.h>

#elif defined (P_VXWORKS)  // added by Jurjan
#include <time.h>
#include <sys/stat.h>
#include <private/stdioP.h>
#include <u_Lib.h>
#define P_USE_STRFTIME
#endif

#ifdef P_USE_LANGINFO
#include <langinfo.h>
#endif

#define	LINE_SIZE_STEP	100

#define	DEFAULT_FILE_MODE	(S_IRUSR|S_IWUSR|S_IROTH|S_IRGRP)

#if !P_USE_INLINES
#include <ptlib/osutil.inl>
#include <ptlib/ptlib.inl>
#endif

#ifdef P_SUN4
extern "C" {
int on_exit(void (*f)(void), caddr_t);
int atexit(void (*f)(void))
{
  return on_exit(f, 0);
}
static char *tzname[2] = { "STD", "DST" };
};
#endif

#define new PNEW


static PString CanonicaliseDirectory (const PString & path)

{
  PString canonical_path;
  PString slash("/");

  // if the path does not start with a slash, then the current directory
  // must be prepended
  if (path.IsEmpty() || path[0] != '/')  {
    char *p = getcwd(canonical_path.GetPointer(P_MAX_PATH), P_MAX_PATH);
    PAssertOS (p != NULL);
  }

  // if the path doesn't end in a slash, add one
  if (canonical_path[canonical_path.GetLength()-1] != '/')
    canonical_path += slash;

  const char * ptr = path;
  const char * end;

  for (;;) {
    // ignore slashes
    while (*ptr == '/' && *ptr != '\0')
      ptr++;

    // finished if end of string
    if (*ptr == '\0')
      break;

    // collect non-slash characters
    end = ptr;
    while (*end != '/' && *end != '\0')
      end++;

    // make a string out of the element
    PString element(ptr, end - ptr);
    
    if (element == "..") {
      PINDEX last_char = canonical_path.GetLength()-1;
      if (last_char > 0)
        canonical_path = canonical_path.Left(canonical_path.FindLast('/', last_char-1)+1);
    } else if (element == "." || element == "") {
    } else {
      canonical_path += element;
      canonical_path += slash;
    }
    ptr = end;
  }

  return canonical_path;
}

static PString CanonicaliseFilename(const PString & filename)

{
  PINDEX p;
  PString dirname;

  // if there is a slash in the string, extract the dirname
  if ((p = filename.FindLast('/')) != P_MAX_INDEX) {
    dirname = filename(0,p);
    while (filename[p] == '/')
      p++;
  } else
    p = 0;

  return CanonicaliseDirectory(dirname) + filename(p, P_MAX_INDEX);
}


PInt64 PString::AsInt64(unsigned base) const
{
#if defined(P_SOLARIS) || defined(__BEOS__)
  char * dummy;
  return strtoll(theArray, &dummy, base);
#elif defined (P_VXWORKS)
  char * dummy;
  return strtol(theArray, &dummy, base);
#else
  return strtoq(theArray, &dummy, base);
#endif
}

PUInt64 PString::AsUnsigned64(unsigned base) const
{
#if defined(P_SOLARIS) || defined(__BEOS__)
  char * dummy;
  return strtoull(theArray, &dummy, base);
#elif defined (P_VXWORKS)
  char * dummy;
  return strtoul(theArray, &dummy, base);
#else
  return strtouq(theArray, &dummy, base);
#endif
}


///////////////////////////////////////////////////////////////////////////////
//
// timer


PTimeInterval PTimer::Tick()
{
	#if defined(P_VXWORKS)		// added by Jurjan
		struct timespec ts;
		clock_gettime(0, &ts);
//		printf("total: %ld\n", ((ts.tv_sec * 10000) + (ts.tv_nsec/100000L)));
  	return (int)(ts.tv_sec * 10000) + (ts.tv_nsec/100000L);

//			return ts.tv_nsec;
	#else
		struct timeval tv;
		::gettimeofday (&tv, NULL);
		return (PInt64)(tv.tv_sec) * 1000 + tv.tv_usec/1000L;
	#endif
}



///////////////////////////////////////////////////////////////////////////////
//
// PDirectory
//

void PDirectory::CopyContents(const PDirectory & d)
{
  if (d.entryInfo == NULL)
    entryInfo = NULL;
  else {
    entryInfo  = new PFileInfo;
    *entryInfo = *d.entryInfo;
  }
  directory   = NULL;
  entryBuffer = NULL;
}

void PDirectory::Close()
{
  if (directory != NULL) {
    PAssert(closedir(directory) == 0, POperatingSystemError);
    directory = NULL;
  }

  if (entryBuffer != NULL) {
    free(entryBuffer);
    entryBuffer = NULL;
  }

  if (entryInfo != NULL) {
    delete entryInfo;
    entryInfo = NULL;
  }
}

void PDirectory::Construct ()

{
  directory   = NULL;
  entryBuffer = NULL;
  entryInfo   = NULL;

  PString::operator =(CanonicaliseDirectory(*this));
}

BOOL PDirectory::Open(int ScanMask)

{
  if (directory != NULL)
    Close();

  scanMask = ScanMask;

  if ((directory = opendir(theArray)) == NULL)
    return FALSE;

  entryBuffer = (struct dirent *)malloc(sizeof(struct dirent) + P_MAX_PATH);
  entryInfo   = new PFileInfo;

  if (Next())
    return TRUE;

  Close();
  return FALSE;
}


BOOL PDirectory::Next()
{
  if (directory == NULL)
    return FALSE;

  do {
    do {
      struct dirent * entryPtr;
      entryBuffer->d_name[0] = '\0';
#ifdef P_HAS_READDIR_R
      if (::readdir_r(directory, entryBuffer, &entryPtr) != 0)
        return FALSE;
      if (entryPtr != entryBuffer)
        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);

    PAssert(PFile::GetInfo(*this+entryBuffer->d_name, *entryInfo), POperatingSystemError);
    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
{
  info = *entryInfo;
  return TRUE;
}

BOOL PDirectory::Create(const PString & p, int perm)
{
	#if defined(P_VXWORKS)	// added by Jurjan
	  PAssert(!p.IsEmpty(), "attempt to create dir with empty name");
	  PString str = p.Left(p.GetLength()-1);
	  return mkdir((char *)(const char *)str) == OK;
	#else
	  PAssert(!p.IsEmpty(), "attempt to create dir with empty name");
	  PString str = p.Left(p.GetLength()-1);
	  return mkdir(str, perm) == 0;
	#endif
}

BOOL PDirectory::Remove(const PString & p)
{
	#if defined(P_VXWORKS)	// added by Jurjan
	  PAssert(!p.IsEmpty(), "attempt to remove dir with empty name");
	  PString str = p.Left(p.GetLength()-1);
	  return rmdir((char *)(const char *)str) == 0;
	#else
	  PAssert(!p.IsEmpty(), "attempt to remove dir with empty name");
	  PString str = p.Left(p.GetLength()-1);
	  return rmdir(str) == 0;
	#endif
}

PString PDirectory::GetVolume() const
{
  PString volume;

//  struct stat status;

  #if defined(P_VXWORKS)	// added by Jurjan
   //  if (stat((char *)(const char *)operator+("."), &status) != -1) {
   //  dev_t my_dev = status.st_dev;
  #else
     if (stat(operator+("."), &status) != -1) {
     dev_t my_dev = status.st_dev;
  #endif


#if defined(P_LINUX) 

    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)

    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_VXWORKS)
	PAssertAlways("GetVolume() not implemented on VxWorks");
	return "";
#else
#warning Platform requires implemetation of GetVolume()
#endif

  return volume;
}

BOOL PDirectory::GetVolumeSpace(PInt64 & total, PInt64 & free, DWORD & clusterSize) const
{
#if defined(P_LINUX) || defined(P_FREEBSD)

  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_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_VXWORKS)
	PAssertAlways("GetVolumeSpace nor implemeted on VxWorks");
	return FALSE;
#else
#warning Platform requires implemetation of GetVolumeSpace()
  return FALSE;

#endif
}

PDirectory PDirectory::GetParent() const
{
  if (IsRoot())
    return *this;
  
  return *this + "..";
}

///////////////////////////////////////////////////////////////////////////////
//
// 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();

#ifndef P_VXWORKS
  if (path.IsEmpty()) {
    char * tmp = tempnam(NULL, "PWL"); 
    PAssert(tmp != NULL, POperatingSystemError);
    path = PString(tmp);
    runtime_free(tmp);
  }

  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;

  removeOnClose = opt & Temporary;

  if (!ConvertOSError(os_handle = ::open(path, oflags, DEFAULT_FILE_MODE)))
    return FALSE;

  #if defined(P_VXWORKS)
	  return ConvertOSError(::u_fcntl(os_handle, F_SETFD, 1));
  #else
	  return ConvertOSError(::fcntl(os_handle, F_SETFD, 1));
  #endif

#else	// vxworks
	PAssertAlways("osutil:  Access");
	return FALSE;
#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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -