ptlib.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:21k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * ptlib.cxx
  3.  *
  4.  * General implementation of classes for Microsoft operating systems.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: ptlib.cxx,v $
  30.  * Revision 1.52  2000/07/09 14:05:46  robertj
  31.  * Added file share options.
  32.  *
  33.  * Revision 1.51  2000/04/29 06:44:17  robertj
  34.  * Added some stuff to make sure symbols included in library.
  35.  *
  36.  * Revision 1.50  2000/02/19 23:46:09  robertj
  37.  * Fixed incorrect values for PFile::Access() function, thanks Stefan Ditscheid.
  38.  *
  39.  * Revision 1.49  1999/08/17 03:46:40  robertj
  40.  * Fixed usage of inlines in optimised version.
  41.  *
  42.  * Revision 1.48  1999/06/14 07:59:38  robertj
  43.  * Enhanced tracing again to add options to trace output (timestamps etc).
  44.  *
  45.  * Revision 1.47  1999/06/13 13:54:07  robertj
  46.  * Added PConsoleChannel class for access to stdin/stdout/stderr.
  47.  *
  48.  * Revision 1.46  1999/06/09 02:05:20  robertj
  49.  * Added ability to open file as standard input, output and error streams.
  50.  *
  51.  * Revision 1.45  1999/05/06 06:11:50  robertj
  52.  * Fixed date to be forgiving of rubbish at end of date string.
  53.  * Fixed PTime::GetHour() etc to not crash on time=-1.
  54.  *
  55.  * Revision 1.44  1998/11/30 07:30:31  robertj
  56.  * Fixed problems with PFilePath parsing functions.
  57.  *
  58.  * Revision 1.43  1998/11/26 10:34:19  robertj
  59.  * Fixed problem with PFileInfo::GetVolume() on UNC paths.
  60.  *
  61.  * Revision 1.42  1998/11/14 23:37:08  robertj
  62.  * Fixed file path directory extraction, not able to return root directory
  63.  *
  64.  * Revision 1.41  1998/10/19 00:20:38  robertj
  65.  * Moved error and trace stream functions to common code.
  66.  *
  67.  * Revision 1.40  1998/10/18 14:27:10  robertj
  68.  * Improved tracing functions.
  69.  *
  70.  * Revision 1.39  1998/10/13 14:13:17  robertj
  71.  * Complete rewrite of memory leak detection code.
  72.  *
  73.  * Revision 1.38  1998/09/24 03:30:53  robertj
  74.  * Added open software license.
  75.  *
  76.  * Revision 1.37  1998/09/14 12:55:06  robertj
  77.  * Changed memory debug to dump leaks not including static globals.
  78.  *
  79.  * Revision 1.36  1998/05/26 01:29:53  robertj
  80.  * Removed assert as this Close() function is now called all the time for Unix reasons.
  81.  *
  82.  * Revision 1.35  1998/05/21 04:27:31  robertj
  83.  * Compensated for MSC run time library bug.
  84.  *
  85.  * Revision 1.34  1998/04/01 01:54:45  robertj
  86.  * Added memory leak checking to debug version.
  87.  *
  88.  * Revision 1.33  1998/03/29 06:16:51  robertj
  89.  * Rearranged initialisation sequence so PProcess descendent constructors can do "things".
  90.  *
  91.  * Revision 1.32  1998/03/20 03:20:16  robertj
  92.  * Added MSVC RT debug support.
  93.  *
  94.  * Revision 1.31  1998/01/26 00:54:15  robertj
  95.  * 64 bit integer string conversions.
  96.  *
  97.  * Revision 1.30  1998/01/05 10:38:25  robertj
  98.  * Unix pthreads compatibility, added threadsafe time functions.
  99.  *
  100.  * Revision 1.29  1997/12/11 10:40:29  robertj
  101.  * Fixed bug in SetType() function of FilePath.
  102.  *
  103.  * Revision 1.28  1997/08/28 12:49:51  robertj
  104.  * Fixed bug where could not change directory to UNC.
  105.  *
  106.  * Revision 1.27  1997/04/27 05:50:26  robertj
  107.  * DLL support.
  108.  *
  109.  * Revision 1.26  1997/01/12 04:23:43  robertj
  110.  * Fixed PDirectory::IsRoot() so works with UNC's
  111.  *
  112.  * Revision 1.25  1996/08/17 10:00:37  robertj
  113.  * Changes for Windows DLL support.
  114.  *
  115.  * Revision 1.24  1996/08/08 10:09:23  robertj
  116.  * Directory structure changes for common files.
  117.  *
  118.  * Revision 1.23  1996/01/28 02:56:16  robertj
  119.  * Fixed bug in PFilePath functions for if path ends in a directory separator.
  120.  *
  121.  * Revision 1.22  1996/01/23 13:23:51  robertj
  122.  * Fixed bug in PFileInfo for if path ends in directory separator.
  123.  *
  124.  * Revision 1.21  1996/01/02 12:56:49  robertj
  125.  * Fixed copy of directories.
  126.  *
  127.  * Revision 1.20  1995/12/10 11:59:33  robertj
  128.  * Changes to main() startup mechanism to support Mac.
  129.  * Fixed bug in time interfval constant variable initialisation. Not guarenteed to work.
  130.  * Moved error code for specific WIN32 and MS-DOS versions.
  131.  *
  132.  * Revision 1.19  1995/10/14 15:12:29  robertj
  133.  * Added function to get parent directory.
  134.  *
  135.  * Revision 1.18  1995/07/31 12:18:11  robertj
  136.  * Removed PContainer from PChannel ancestor.
  137.  *
  138.  * Revision 1.17  1995/06/04 13:10:19  robertj
  139.  * Fixed rename bug.
  140.  *
  141.  * Revision 1.16  1995/06/04 12:48:06  robertj
  142.  * Changed unknown error string to hex.
  143.  * Added missing GetInfo function for directory entries
  144.  *
  145.  * Revision 1.15  1995/04/25 11:33:35  robertj
  146.  * Changes for DLL support.
  147.  *
  148.  * Revision 1.14  1995/04/22 00:53:49  robertj
  149.  * Added Move() function to PFile.
  150.  * Changed semantics of Rename() function in PFile.
  151.  * Changed file path string to use PFilePath object.
  152.  *
  153.  * Revision 1.13  1995/03/12 05:00:08  robertj
  154.  * Re-organisation of DOS/WIN16 and WIN32 platforms to maximise common code.
  155.  * Used built-in equate for WIN32 API (_WIN32).
  156.  *
  157.  * Revision 1.12  1995/02/27  10:37:06  robertj
  158.  * Added GetUserNmae().
  159.  * Removed superfluous Read() and Write() for text files.
  160.  *
  161.  * Revision 1.11  1995/01/06  10:41:43  robertj
  162.  * Moved identifiers into different scope.
  163.  * Changed file size to 64 bit integer.
  164.  *
  165.  * Revision 1.10  1994/12/21  11:36:07  robertj
  166.  * Fixed caseless string for file paths.
  167.  *
  168.  * Revision 1.9  1994/10/30  11:26:54  robertj
  169.  * Fixed set current directory function.
  170.  * Changed PFilePath to be case insignificant according to platform.
  171.  *
  172.  * Revision 1.8  1994/10/23  05:42:39  robertj
  173.  * PipeChannel headers.
  174.  * ConvertOSError function added.
  175.  * Numerous implementation enhancements.
  176.  *
  177.  * Revision 1.7  1994/08/04  13:24:27  robertj
  178.  * Added debug stream.
  179.  *
  180.  * Revision 1.6  1994/07/27  06:00:10  robertj
  181.  * Backup
  182.  *
  183.  * Revision 1.5  1994/07/21  12:35:18  robertj
  184.  * *** empty log message ***
  185.  *
  186.  * Revision 1.4  1994/07/17  11:01:04  robertj
  187.  * Ehancements, implementation, bug fixes etc.
  188.  *
  189.  * Revision 1.3  1994/07/02  03:18:09  robertj
  190.  * Multi-threading implementation.
  191.  *
  192.  * Revision 1.2  1994/06/25  12:13:01  robertj
  193.  * Synchronisation.
  194.  *
  195. // Revision 1.1  1994/04/01  14:39:35  robertj
  196. // Initial revision
  197. //
  198.  */
  199. #include <ptlib.h>
  200. #include <errno.h>
  201. #include <fcntl.h>
  202. #include <share.h>
  203. #include <sysstat.h>
  204. #include <crtdbg.h>
  205. #if !P_USE_INLINES
  206. #include <ptlib/osutil.inl>
  207. #include <ptlib/ptlib.inl>
  208. #endif
  209. ostream & operator<<(ostream & s, PInt64 v)
  210. {
  211.   char buffer[25];
  212.   if ((s.flags()&ios::hex) != 0)
  213.     return s << _ui64toa(v, buffer, 16);
  214.   if ((s.flags()&ios::oct) != 0)
  215.     return s << _ui64toa(v, buffer, 8);
  216.   if (v < 0) {
  217.     s << '-';
  218.     v = -v;
  219.   }
  220.   return s << _i64toa(v, buffer, 10);
  221. }
  222. ostream & operator<<(ostream & s, PUInt64 v)
  223. {
  224.   char buffer[25];
  225.   return s << _ui64toa(v, buffer, (s.flags()&ios::oct) ? 8 : ((s.flags()&ios::hex) ? 16 : 10));
  226. }
  227. PInt64 PString::AsInt64(unsigned base) const
  228. {
  229.   if (base == 10)
  230.     return _atoi64(theArray);
  231.   PAssert(base >= 2 && base <= 36, PInvalidParameter);
  232.   PInt64 total = 0;
  233.   const char * ptr = theArray;
  234.   while (isspace(*ptr))
  235.     ptr++;
  236.   BOOL negative = *ptr == '-';
  237.   if (*ptr == '-' || *ptr == '+')
  238.     ptr++;
  239.   for (;;) {
  240.     unsigned c = *ptr++;
  241.     if (c < '0')
  242.       break;
  243.     if (c <= '9')
  244.       c -= '0';
  245.     else
  246.       c = toupper(c) - 'A' + 10;
  247.     if (c >= base)
  248.       break;
  249.     total = base * total + c;
  250.     c = *ptr++;
  251.   }
  252.   if (negative)
  253.     return -total;
  254.   else
  255.     return total;
  256. }
  257. PUInt64 PString::AsUnsigned64(unsigned base) const
  258. {
  259.   PAssert(base >= 2 && base <= 36, PInvalidParameter);
  260.   PUInt64 total = 0;
  261.   const char * ptr = theArray;
  262.   while (isspace(*ptr))
  263.     ptr++;
  264.   for (;;) {
  265.     unsigned c = *ptr++;
  266.     if (c < '0')
  267.       break;
  268.     if (c <= '9')
  269.       c -= '0';
  270.     else
  271.       c = toupper(c) - 'A' + 10;
  272.     if (c >= base)
  273.       break;
  274.     total = base * total + c;
  275.     c = *ptr++;
  276.   }
  277.   return total;
  278. }
  279. ///////////////////////////////////////////////////////////////////////////////
  280. // PTime
  281. struct tm * PTime::os_localtime(const time_t * clock, struct tm * tb)
  282. {
  283.   struct tm * tp = ::localtime(clock);
  284.   if (tp != NULL)
  285.     return tp;
  286.   memset(tb, 0, sizeof(*tb));
  287.   return tb;
  288. }
  289. struct tm * PTime::os_gmtime(const time_t * clock, struct tm * tb)
  290. {
  291.   struct tm * tp = ::gmtime(clock);
  292.   if (tp != NULL)
  293.     return tp;
  294.   memset(tb, 0, sizeof(*tb));
  295.   return tb;
  296. }
  297. ///////////////////////////////////////////////////////////////////////////////
  298. // PChannel
  299. void PChannel::Construct()
  300. {
  301. }
  302. PString PChannel::GetName() const
  303. {
  304.   PAssertAlways(PUnimplementedFunction);
  305.   return PString();
  306. }
  307. BOOL PChannel::Read(void *, PINDEX)
  308. {
  309.   PAssertAlways(PUnimplementedFunction);
  310.   return FALSE;
  311. }
  312. BOOL PChannel::Write(const void *, PINDEX)
  313. {
  314.   PAssertAlways(PUnimplementedFunction);
  315.   return FALSE;
  316. }
  317. BOOL PChannel::Close()
  318. {
  319.   return FALSE;
  320. }
  321. ///////////////////////////////////////////////////////////////////////////////
  322. // Directories
  323. PDirectory PDirectory::GetParent() const
  324. {
  325.   if (IsRoot())
  326.     return *this;
  327.   
  328.   return *this + "..";
  329. }
  330. BOOL PDirectory::Change(const PString & p)
  331. {
  332.   PDirectory d = p;
  333.   if (d[0] != '\')
  334.     if (_chdrive(toupper(d[0])-'A'+1) != 0)
  335.       return FALSE;
  336.   return _chdir(d + ".") == 0;
  337. }
  338. BOOL PDirectory::Filtered()
  339. {
  340. #if defined(_WIN32)
  341.   char * name = fileinfo.cFileName;
  342. #else
  343.   char * name = fileinfo.name;
  344. #endif
  345.   if (strcmp(name, ".") == 0)
  346.     return TRUE;
  347.   if (strcmp(name, "..") == 0)
  348.     return TRUE;
  349.   if (scanMask == PFileInfo::AllPermissions)
  350.     return FALSE;
  351.   PFileInfo inf;
  352.   PAssert(PFile::GetInfo(*this+name, inf), POperatingSystemError);
  353.   return (inf.type&scanMask) == 0;
  354. }
  355. BOOL PDirectory::IsRoot() const
  356. {
  357.   if ((*this)[1] == ':')
  358.     return GetLength() == 3;
  359.   PINDEX pos = FindOneOf("/\", 2);
  360.   return pos == GetLength();
  361. }
  362. BOOL PDirectory::GetInfo(PFileInfo & info) const
  363. {
  364.   return PFile::GetInfo(*this + GetEntryName(), info);
  365. }
  366. ///////////////////////////////////////////////////////////////////////////////
  367. // File Path
  368. PFilePath::PFilePath(const PString & str)
  369.   : PCaselessString(PDirectory::CreateFullPath(str, FALSE))
  370. {
  371. }
  372. PFilePath::PFilePath(const char * cstr)
  373.   : PCaselessString(PDirectory::CreateFullPath(cstr, FALSE))
  374. {
  375. }
  376. PFilePath::PFilePath(const char * prefix, const char * dir)
  377. {
  378.   if (dir != NULL) {
  379.     PDirectory tmpdir(dir);
  380.     operator=(tmpdir);
  381.   }
  382.   else {
  383.     PConfig cfg(PConfig::Environment);
  384.     PString path = cfg.GetString("TMPDIR");
  385.     if (path.IsEmpty()) {
  386.       path = cfg.GetString("TMP");
  387.       if (path.IsEmpty())
  388.         path = cfg.GetString("TEMP");
  389.     }
  390.     if (path.IsEmpty() || path[path.GetLength()-1] != '\')
  391.       path += '\';
  392.     *this = path;
  393.   }
  394.   if (prefix != NULL)
  395.     *this += prefix;
  396.   else
  397.     *this += "PW";
  398.   *this += "XXXXXX";
  399.   PAssert(_mktemp(GetPointer()) != NULL, "Could not make temporary file");
  400. }
  401. PFilePath & PFilePath::operator=(const PString & str)
  402. {
  403.   PCaselessString::operator=(PDirectory::CreateFullPath(str, FALSE));
  404.   return *this;
  405. }
  406. static PINDEX GetVolumeSubStringLength(const PString & path)
  407. {
  408.   if (path[1] == ':')
  409.     return 2;
  410.   if (path[0] == '\' && path[1] == '\') {
  411.     PINDEX backslash = path.Find('\', 2);
  412.     if (backslash != P_MAX_INDEX) {
  413.       backslash = path.Find('\', backslash+1);
  414.       if (backslash != P_MAX_INDEX)
  415.         return backslash;
  416.     }
  417.   }
  418.   PINDEX backslash = path.Find('\');
  419.   if (backslash != P_MAX_INDEX)
  420.     return backslash;
  421.   return 0;
  422. }
  423. PCaselessString PFilePath::GetVolume() const
  424. {
  425.   return Left(GetVolumeSubStringLength(*this));
  426. }
  427. PDirectory PFilePath::GetDirectory() const
  428. {
  429.   PINDEX backslash = FindLast('\');
  430.   if (backslash != P_MAX_INDEX)
  431.     return Left(backslash+1);
  432.   return PCaselessString();
  433. }
  434. PCaselessString PFilePath::GetPath() const
  435. {
  436.   return operator()(GetVolumeSubStringLength(*this), FindLast('\', GetLength()-2));
  437. }
  438. PCaselessString PFilePath::GetFileName() const
  439. {
  440.   PINDEX backslash = FindLast('\', GetLength()-2);
  441.   if (backslash == P_MAX_INDEX)
  442.     backslash = 0;
  443.   else
  444.     backslash++;
  445.   return Mid(backslash);
  446. }
  447. PCaselessString PFilePath::GetTitle() const
  448. {
  449.   PINDEX backslash = FindLast('\', GetLength()-2);
  450.   if (backslash == P_MAX_INDEX)
  451.     backslash = 0;
  452.   else
  453.     backslash++;
  454.   return operator()(backslash, FindLast('.')-1);
  455. }
  456. PCaselessString PFilePath::GetType() const
  457. {
  458.   PINDEX dot = Find('.', FindLast('\'));
  459.   if (dot == P_MAX_INDEX)
  460.     return PCaselessString();
  461.   return operator()(dot, P_MAX_INDEX);
  462. }
  463. void PFilePath::SetType(const PCaselessString & type)
  464. {
  465.   PINDEX dot = Find('.', FindLast('\'));
  466.   if (dot != P_MAX_INDEX)
  467.     Splice(type, dot, GetLength()-dot);
  468.   else
  469.     *this += type;
  470. }
  471. ///////////////////////////////////////////////////////////////////////////////
  472. // PFile
  473. void PFile::SetFilePath(const PString & newName)
  474. {
  475.   if (!IsOpen())
  476.     path = newName;
  477. }
  478. BOOL PFile::Access(const PFilePath & name, OpenMode mode)
  479. {
  480.   int accmode;
  481.   switch (mode) {
  482.     case ReadOnly :
  483. #ifndef R_OK
  484. #define R_OK 4
  485. #endif
  486.       accmode = R_OK;
  487.       break;
  488.     case WriteOnly :
  489. #ifndef W_OK
  490. #define W_OK 2
  491. #endif
  492.       accmode = W_OK;
  493.       break;
  494.     default :
  495.       accmode = R_OK|W_OK;
  496.   }
  497.   return access(name, accmode) == 0;
  498. }
  499. BOOL PFile::Remove(const PFilePath & name, BOOL force)
  500. {
  501.   if (remove(name) == 0)
  502.     return TRUE;
  503.   if (!force || errno != EACCES)
  504.     return FALSE;
  505.   if (_chmod(name, _S_IWRITE) != 0)
  506.     return FALSE;
  507.   return remove(name) == 0;
  508. }
  509. BOOL PFile::Rename(const PFilePath & oldname, const PString & newname, BOOL force)
  510. {
  511.   if (newname.FindOneOf(":\/") != P_MAX_INDEX) {
  512.     errno = EINVAL;
  513.     return FALSE;
  514.   }
  515.   PString fullname = oldname.GetDirectory() + newname;
  516.   if (rename(oldname, fullname) == 0)
  517.     return TRUE;
  518.   if (!force || errno == ENOENT || !Exists(fullname))
  519.     return FALSE;
  520.   if (!Remove(fullname, TRUE))
  521.     return FALSE;
  522.   return rename(oldname, fullname) == 0;
  523. }
  524. BOOL PFile::Move(const PFilePath & oldname, const PFilePath & newname, BOOL force)
  525. {
  526.   if (rename(oldname, newname) == 0)
  527.     return TRUE;
  528.   if (errno == ENOENT)
  529.     return FALSE;
  530.   if (force && Exists(newname)) {
  531.     if (!Remove(newname, TRUE))
  532.       return FALSE;
  533.     if (rename(oldname, newname) == 0)
  534.       return TRUE;
  535.   }
  536.   return Copy(oldname, newname, force) && Remove(oldname);
  537. }
  538. BOOL PFile::GetInfo(const PFilePath & name, PFileInfo & info)
  539. {
  540.   PString fn = name;
  541.   PINDEX pos = fn.GetLength()-1;
  542.   while (PDirectory::IsSeparator(fn[pos]))
  543.     pos--;
  544.   fn.Delete(pos+1, P_MAX_INDEX);
  545.   struct stat s;
  546.   if (stat(fn, &s) != 0)
  547.     return FALSE;
  548.   info.created =  (s.st_ctime < 0) ? 0 : s.st_ctime;
  549.   info.modified = (s.st_mtime < 0) ? 0 : s.st_mtime;
  550.   info.accessed = (s.st_atime < 0) ? 0 : s.st_atime;
  551.   info.size = s.st_size;
  552.   info.permissions = 0;
  553.   if ((s.st_mode&S_IREAD) != 0)
  554.     info.permissions |=
  555.                 PFileInfo::UserRead|PFileInfo::GroupRead|PFileInfo::WorldRead;
  556.   if ((s.st_mode&S_IWRITE) != 0)
  557.     info.permissions |=
  558.              PFileInfo::UserWrite|PFileInfo::GroupWrite|PFileInfo::WorldWrite;
  559.   if ((s.st_mode&S_IEXEC) != 0)
  560.     info.permissions |=
  561.        PFileInfo::UserExecute|PFileInfo::GroupExecute|PFileInfo::WorldExecute;
  562.   switch (s.st_mode & S_IFMT) {
  563.     case S_IFREG :
  564.       info.type = PFileInfo::RegularFile;
  565.       break;
  566.     case S_IFDIR :
  567.       info.type = PFileInfo::SubDirectory;
  568.       break;
  569.     default:
  570.       info.type = PFileInfo::UnknownFileType;
  571.       break;
  572.   }
  573. #if defined(_WIN32)
  574.   info.hidden = (GetFileAttributes(name) & FILE_ATTRIBUTE_HIDDEN) != 0;
  575. #else
  576.   unsigned int attr;
  577.   _dos_getfileattr(name, &attr);
  578.   info.hidden = (attr & _A_HIDDEN) != 0;
  579. #endif
  580.   return TRUE;
  581. }
  582. BOOL PFile::SetPermissions(const PFilePath & name, int permissions)
  583. {
  584.   return _chmod(name, permissions&(_S_IWRITE|_S_IREAD)) == 0;
  585. }
  586. BOOL PFile::IsTextFile() const
  587. {
  588.   return FALSE;
  589. }
  590. BOOL PFile::Open(OpenMode mode, int opts)
  591. {
  592.   Close();
  593.   clear();
  594.   if (path.IsEmpty())
  595.     path = PFilePath("PWL", NULL);
  596.   int oflags = IsTextFile() ? _O_TEXT : _O_BINARY;
  597.   switch (mode) {
  598.     case ReadOnly :
  599.       oflags |= O_RDONLY;
  600.       if (opts == ModeDefault)
  601.         opts = MustExist;
  602.       break;
  603.     case WriteOnly :
  604.       oflags |= O_WRONLY;
  605.       if (opts == ModeDefault)
  606.         opts = Create|Truncate;
  607.       break;
  608.     case ReadWrite :
  609.       oflags |= O_RDWR;
  610.       if (opts == ModeDefault)
  611.         opts = Create;
  612.       break;
  613.     default :
  614.       PAssertAlways(PInvalidParameter);
  615.   }
  616.   if ((opts&Create) != 0)
  617.     oflags |= O_CREAT;
  618.   if ((opts&Exclusive) != 0)
  619.     oflags |= O_EXCL;
  620.   if ((opts&Truncate) != 0)
  621.     oflags |= O_TRUNC;
  622.   if ((opts&Temporary) != 0)
  623.     removeOnClose = TRUE;
  624.   int sflags = _SH_DENYNO;
  625.   if ((opts&DenySharedRead) == DenySharedRead)
  626.     sflags = _SH_DENYRD;
  627.   else if ((opts&DenySharedWrite) == DenySharedWrite)
  628.     sflags = _SH_DENYWR;
  629.   else if ((opts&(DenySharedRead|DenySharedWrite)) != 0)
  630.     sflags = _SH_DENYWR;
  631.   return ConvertOSError(os_handle = _sopen(path, oflags, sflags, S_IREAD|S_IWRITE));
  632. }
  633. BOOL PFile::SetLength(off_t len)
  634. {
  635.   return ConvertOSError(_chsize(GetHandle(), len));
  636. }
  637. ///////////////////////////////////////////////////////////////////////////////
  638. // PTextFile
  639. BOOL PTextFile::IsTextFile() const
  640. {
  641.   return TRUE;
  642. }
  643. BOOL PTextFile::ReadLine(PString & str)
  644. {
  645.   char * ptr = str.GetPointer(100);
  646.   PINDEX len = 0;
  647.   int c;
  648.   while ((c = ReadChar()) >= 0 && c != 'n') {
  649.     *ptr++ = (char)c;
  650.     if (++len >= str.GetSize())
  651.       ptr = str.GetPointer(len + 100) + len;
  652.   }
  653.   *ptr = '';
  654.   PAssert(str.MakeMinimumSize(), POutOfMemory);
  655.   return c >= 0 || len > 0;
  656. }
  657. BOOL PTextFile::WriteLine(const PString & str)
  658. {
  659.   return WriteString(str) && WriteChar('n');
  660. }
  661. ///////////////////////////////////////////////////////////////////////////////
  662. // PConsoleChannel
  663. PConsoleChannel::PConsoleChannel()
  664. {
  665. }
  666. PConsoleChannel::PConsoleChannel(ConsoleType type)
  667. {
  668.   Open(type);
  669. }
  670. BOOL PConsoleChannel::Open(ConsoleType type)
  671. {
  672.   switch (type) {
  673.     case StandardInput :
  674.       os_handle = 0;
  675.       return TRUE;
  676.     case StandardOutput :
  677.       os_handle = 1;
  678.       return TRUE;
  679.     case StandardError :
  680.       os_handle = 2;
  681.       return TRUE;
  682.   }
  683.   return FALSE;
  684. }
  685. PString PConsoleChannel::GetName() const
  686. {
  687.   return "\\.\Console";
  688. }
  689. BOOL PConsoleChannel::Read(void * buffer, PINDEX length)
  690. {
  691.   flush();
  692.   lastReadCount = _read(os_handle, buffer, length);
  693.   return ConvertOSError(lastReadCount) && lastReadCount > 0;
  694. }
  695. BOOL PConsoleChannel::Write(const void * buffer, PINDEX length)
  696. {
  697.   flush();
  698.   lastWriteCount = _write(os_handle, buffer, length);
  699.   return ConvertOSError(lastWriteCount) && lastWriteCount >= length;
  700. }
  701. BOOL PConsoleChannel::Close()
  702. {
  703.   os_handle = -1;
  704.   return TRUE;
  705. }
  706. ///////////////////////////////////////////////////////////////////////////////
  707. // PProcess
  708. void PProcess::Construct()
  709. {
  710.   PSetErrorStream(&cerr);
  711. #if !defined(_WIN32) && defined(_MSC_VER) && defined(_WINDOWS)
  712.   _wsetscreenbuf(1, _WINBUFINF);
  713.   _wsizeinfo ws;
  714.   ws._version = _QWINVER;
  715.   ws._type = _WINSIZEMAX;
  716.   _wsetsize(1, &ws);
  717. #endif
  718.   houseKeeper = NULL;
  719. }
  720. //////////////////////////////////////////////////////////////////////////////
  721. #define INCLUDE_STUFF1(cls) 
  722.   cls i##cls; 
  723.   i##cls = i##cls
  724. #define INCLUDE_STUFF2(cls) 
  725.   INCLUDE_STUFF1(cls); 
  726.   i##cls.GetPointer(); 
  727.   i##cls.Attach(0, 0); 
  728.   i##cls.SetAt(0, 0); 
  729.   i##cls.GetAt(0); 
  730.   i##cls[0]
  731. void PDummyFunctionToMakeSureSymbolsAreInDEFFile()
  732. {
  733.   INCLUDE_STUFF2(PCharArray);
  734.   INCLUDE_STUFF2(PShortArray);
  735.   INCLUDE_STUFF2(PIntArray);
  736.   INCLUDE_STUFF2(PLongArray);
  737.   INCLUDE_STUFF2(PBYTEArray);
  738.   INCLUDE_STUFF2(PWORDArray);
  739.   INCLUDE_STUFF2(PUnsignedArray);
  740.   INCLUDE_STUFF2(PDWORDArray);
  741.   INCLUDE_STUFF1(PStringSet);
  742.   INCLUDE_STUFF1(POrdinalToString);
  743.   INCLUDE_STUFF1(PStringToOrdinal);
  744.   INCLUDE_STUFF1(PStringToString);
  745. }
  746. // End Of File ///////////////////////////////////////////////////////////////