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

📄 channel.cxx

📁 基于VXWORKS H323通信技术源代码
💻 CXX
字号:
/*  
 * channel.cxx
 *
 * I/O channel 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: channel.cxx,v $
 * Revision 1.25  1999/03/02 05:41:59  robertj
 * More BeOS changes
 *
 * Revision 1.24  1999/02/22 13:26:53  robertj
 * BeOS port changes.
 *
 * Revision 1.23  1998/11/30 21:51:30  robertj
 * New directory structure.
 *
 * Revision 1.22  1998/10/16 02:03:18  robertj
 * Fixed error message output to include number on unknown errors.
 *
 * Revision 1.21  1998/10/16 01:15:38  craigs
 * Added Yield to help with cooperative multithreading.
 *
 * Revision 1.20  1998/10/11 02:23:16  craigs
 * Fixed problem with socket writes not correctly detecting EOF
 *
 * Revision 1.19  1998/09/24 04:12:09  robertj
 * Added open software license.
 *
 * Revision 1.18  1998/08/27 01:06:30  robertj
 * Fixed very strange link error with GNU C library v6.
 *
 * Revision 1.17  1998/05/25 10:03:26  robertj
 * Fixed problem with socket/channel close and blocked threads.
 *
 * Revision 1.16  1998/03/26 05:01:12  robertj
 * Added PMutex and PSyncPoint classes.
 *
 * Revision 1.15  1998/01/03 22:35:04  craigs
 * Added PThread support
 *
 * Revision 1.14  1997/02/14 09:18:36  craigs
 * Changed for PProcess::Current being a reference rather that a ptr
 *
 * Revision 1.13  1996/11/03 04:35:32  craigs
 * Added PSocket::Read to fix recv/read problem
 *
 * Revision 1.12  1996/09/21 05:38:28  craigs
 * Added indchan pragma
 *
 * Revision 1.11  1996/08/03 12:04:28  craigs
 * Fixed problem with PChannel::Write terminating early
 * Changed for new PChannel error reporting functions
 *
 * Revision 1.10  1996/05/25 06:06:33  craigs
 * Sun4 fixes and updated for gcc 2.7.2
 *
 * Revision 1.9  1996/05/03 13:11:35  craigs
 * More Sun4 fixes
 *
 * Revision 1.8  1996/05/02 12:01:23  craigs
 * More Sun4 fixes
 *
 * Revision 1.7  1996/04/15 10:49:11  craigs
 * Last build prior to release of MibMaster v1.0
 *
 * Revision 1.6  1996/01/26 11:09:42  craigs
 * Fixed problem with blocking accepts and incorrect socket errors
 *
 * Revision 1.5  1995/10/15 12:56:54  craigs
 * Multiple updates - split channel implementation into multiple files
 *
 * Revision 1.4  1995/07/09 00:35:43  craigs
 * Latest and greatest omnibus change
 *
 * Revision 1.3  1995/02/15 20:28:14  craigs
 * Removed sleep after pipe channel open
 *
// Revision 1.2  1995/01/23  22:58:01  craigs
// Changes for HPUX and Sun 4
//
 */

#pragma implementation "channel.h"
#pragma implementation "indchan.h"

#include <ptlib.h>
#include <sys/ioctl.h>


#include "../common/pchannel.cxx"


PMutex PX_iostreamMutex;

ios::ios(const ios &)
{
  PAssertAlways("Cannot copy ios");
}

///////////////////////////////////////////////////////////////////////////////
//
// PChannel::PXSetIOBlock
//   These functions are used to perform IO blocks.
//   If the return value is FALSE, then the select call either
//   returned an error or a timeout occurred. The member variable lastError
//   can be used to determine which error occurred
//

BOOL PChannel::PXSetIOBlock (int type, const PTimeInterval & timeout)
{
  return PXSetIOBlock(type, os_handle, timeout);
}

BOOL PChannel::PXSetIOBlock (int type, int blockHandle, const PTimeInterval & timeout)
{
  if (blockHandle < 0) {
    lastError = NotOpen;
    return FALSE;
  }

  int stat = PThread::Current()->PXBlockOnIO(blockHandle, type, timeout);
  // if select returned < 0, then covert errno into lastError and return FALSE
  if (stat < 0)
    return ConvertOSError(stat);

  // if the select succeeded, then return TRUE
  if (stat > 0) 
    return TRUE;

  // otherwise, a timeout occurred so return FALSE
  lastError = Timeout;
  return FALSE;
}


BOOL PChannel::Read(void * buf, PINDEX len)
{
  if (os_handle < 0) {
    lastError = NotOpen;
    return FALSE;
  }

  if (!PXSetIOBlock(PXReadBlock, readTimeout)) 
    return FALSE;

  if (ConvertOSError(lastReadCount = ::read(os_handle, (char *)buf, len)))
    return lastReadCount > 0;

  lastReadCount = 0;
  return FALSE;
}


BOOL PChannel::Write(const void * buf, PINDEX len)
{
  // if the os_handle isn't open, no can do
  if (os_handle < 0) {
    lastError = NotOpen;
    return FALSE;
  }

  // flush the buffer before doing a write
  PX_iostreamMutex.Wait();
  flush();
  PX_iostreamMutex.Signal();

  lastWriteCount = 0;
  
  while (len > 0) {

    int sendResult = ::write(os_handle,
                  ((char *)	buf)+lastWriteCount, len);  // removed const:   Jurjan
    if (sendResult > 0)
      PThread::Yield();
    else {
      if (errno != EWOULDBLOCK)
        return ConvertOSError(sendResult);

      if (!PXSetIOBlock(PXWriteBlock, writeTimeout))
        return FALSE;

      sendResult = ::write(os_handle,
                    ((char *)buf)+lastWriteCount, len);	// removed const:   Jurjan

    }

    if (!ConvertOSError(sendResult))
      return FALSE;

    lastWriteCount += sendResult;
    len -= sendResult;
  }

  return TRUE;
}

BOOL PChannel::Close()
{
  if (os_handle < 0) {
    lastError = NotOpen;
    return FALSE;
  }
  
  return ConvertOSError(PXClose());
}

BOOL PChannel::PXClose()
{
  if (os_handle < 0)
    return -1;

  // make sure we don't have any problems
  PX_iostreamMutex.Wait();
  flush();
  int handle = os_handle;
  os_handle = -1;
  PX_iostreamMutex.Signal();

#if !defined(P_PTHREADS) && !defined(BE_THREADS) && !defined(VX_TASKS)	// added by Jurjan
  // abort any I/O block using this os_handle
  PProcess::Current().PXAbortIOBlock(handle);

#ifndef __BEOS__
  DWORD cmd = 0;
  ::ioctl(handle, FIONBIO, &cmd);
#endif
#endif

  int stat;
  do {
    stat = ::close(handle);
  } while (stat == -1 && errno == EINTR);

  return stat;
}

PString PChannel::GetErrorText(Errors, int osError = 0)
{
  if (osError == 0)
    return PString();

  const char * err = strerror(osError);
  if (err != NULL)
    return err;

  return psprintf("Unknown error %d", osError);
}

PString PChannel::GetErrorText() const
{
  return GetErrorText(lastError, osError);
}

BOOL PChannel::ConvertOSError(int err)
{
  return ConvertOSError(err, lastError, osError);
}

BOOL PChannel::ConvertOSError(int err, Errors & lastError, int & osError)

{
  osError = (err >= 0) ? 0 : errno;

  switch (osError) {
    case 0 :
      lastError = NoError;
      return TRUE;

    case EMSGSIZE:
      lastError = BufferTooSmall;
      break;

    case EINTR:
      lastError = Interrupted;
      break;

    case EEXIST:
      lastError = FileExists;
      break;

    case EISDIR:
    case EROFS:
    case EACCES:
    case EPERM:
      lastError = AccessDenied;
      break;

#ifndef __BEOS__
    case ETXTBSY:
      lastError = DeviceInUse;
      break;
#endif

    case EFAULT:
    case ELOOP:
    case EBADF:
    case EINVAL:
      lastError = BadParameter;
      break;

    case ENOENT :
    case ENAMETOOLONG:
    case ENOTDIR:
      lastError = NotFound;
      break;

    case EMFILE:
    case ENFILE:
    case ENOMEM :
      lastError = NoMemory;
      break;

    case ENOSPC:
      lastError = DiskFull;
      break;

    default :
      lastError = Miscellaneous;
      break;
  }
  return FALSE;
}


///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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