Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/nsprpub/pr/src/io/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 16 kB image not shown  

Quelle  priometh.c   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "primpl.h"

#include <string.h>

/*****************************************************************************/
/************************** Invalid I/O method object ************************/
/*****************************************************************************/
PRIOMethods _pr_faulty_methods = {(PRDescType)0,
                                  (PRCloseFN)_PR_InvalidStatus,
                                  (PRReadFN)_PR_InvalidInt,
                                  (PRWriteFN)_PR_InvalidInt,
                                  (PRAvailableFN)_PR_InvalidInt,
                                  (PRAvailable64FN)_PR_InvalidInt64,
                                  (PRFsyncFN)_PR_InvalidStatus,
                                  (PRSeekFN)_PR_InvalidInt,
                                  (PRSeek64FN)_PR_InvalidInt64,
                                  (PRFileInfoFN)_PR_InvalidStatus,
                                  (PRFileInfo64FN)_PR_InvalidStatus,
                                  (PRWritevFN)_PR_InvalidInt,
                                  (PRConnectFN)_PR_InvalidStatus,
                                  (PRAcceptFN)_PR_InvalidDesc,
                                  (PRBindFN)_PR_InvalidStatus,
                                  (PRListenFN)_PR_InvalidStatus,
                                  (PRShutdownFN)_PR_InvalidStatus,
                                  (PRRecvFN)_PR_InvalidInt,
                                  (PRSendFN)_PR_InvalidInt,
                                  (PRRecvfromFN)_PR_InvalidInt,
                                  (PRSendtoFN)_PR_InvalidInt,
                                  (PRPollFN)_PR_InvalidInt16,
                                  (PRAcceptreadFN)_PR_InvalidInt,
                                  (PRTransmitfileFN)_PR_InvalidInt,
                                  (PRGetsocknameFN)_PR_InvalidStatus,
                                  (PRGetpeernameFN)_PR_InvalidStatus,
                                  (PRReservedFN)_PR_InvalidInt,
                                  (PRReservedFN)_PR_InvalidInt,
                                  (PRGetsocketoptionFN)_PR_InvalidStatus,
                                  (PRSetsocketoptionFN)_PR_InvalidStatus,
                                  (PRSendfileFN)_PR_InvalidInt,
                                  (PRConnectcontinueFN)_PR_InvalidStatus,
                                  (PRReservedFN)_PR_InvalidInt,
                                  (PRReservedFN)_PR_InvalidInt,
                                  (PRReservedFN)_PR_InvalidInt,
                                  (PRReservedFN)_PR_InvalidInt};

PRIntn _PR_InvalidInt(void) {
  PR_NOT_REACHED("I/O method is invalid");
  PR_SetError(PR_INVALID_METHOD_ERROR, 0);
  return -1;
/* _PR_InvalidInt */

PRInt16 _PR_InvalidInt16(void) {
  PR_NOT_REACHED("I/O method is invalid");
  PR_SetError(PR_INVALID_METHOD_ERROR, 0);
  return -1;
/* _PR_InvalidInt */

PRInt64 _PR_InvalidInt64(void) {
  PRInt64 rv;
  LL_I2L(rv, -1);
  PR_NOT_REACHED("I/O method is invalid");
  PR_SetError(PR_INVALID_METHOD_ERROR, 0);
  return rv;
/* _PR_InvalidInt */

/*
 * An invalid method that returns PRStatus
 */


PRStatus _PR_InvalidStatus(void) {
  PR_NOT_REACHED("I/O method is invalid");
  PR_SetError(PR_INVALID_METHOD_ERROR, 0);
  return PR_FAILURE;
/* _PR_InvalidDesc */

/*
 * An invalid method that returns a pointer
 */


PRFileDesc* _PR_InvalidDesc(void) {
  PR_NOT_REACHED("I/O method is invalid");
  PR_SetError(PR_INVALID_METHOD_ERROR, 0);
  return NULL;
/* _PR_InvalidDesc */

PR_IMPLEMENT(PRDescType) PR_GetDescType(PRFileDesc* file) {
  return file->methods->file_type;
}

PR_IMPLEMENT(PRStatus) PR_Close(PRFileDesc* fd) {
  return (fd->methods->close)(fd);
}

PR_IMPLEMENT(PRInt32) PR_Read(PRFileDesc* fd, void* buf, PRInt32 amount) {
  return ((fd->methods->read)(fd, buf, amount));
}

PR_IMPLEMENT(PRInt32)
PR_Write(PRFileDesc* fd, const void* buf, PRInt32 amount) {
  return ((fd->methods->write)(fd, buf, amount));
}

PR_IMPLEMENT(PRInt32)
PR_Seek(PRFileDesc* fd, PRInt32 offset, PRSeekWhence whence) {
  return ((fd->methods->seek)(fd, offset, whence));
}

PR_IMPLEMENT(PRInt64)
PR_Seek64(PRFileDesc* fd, PRInt64 offset, PRSeekWhence whence) {
  return ((fd->methods->seek64)(fd, offset, whence));
}

PR_IMPLEMENT(PRInt32) PR_Available(PRFileDesc* fd) {
  return ((fd->methods->available)(fd));
}

PR_IMPLEMENT(PRInt64) PR_Available64(PRFileDesc* fd) {
  return ((fd->methods->available64)(fd));
}

PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo(PRFileDesc* fd, PRFileInfo* info) {
  return ((fd->methods->fileInfo)(fd, info));
}

PR_IMPLEMENT(PRStatus)
PR_GetOpenFileInfo64(PRFileDesc* fd, PRFileInfo64* info) {
  return ((fd->methods->fileInfo64)(fd, info));
}

PR_IMPLEMENT(PRStatus) PR_Sync(PRFileDesc* fd) {
  return ((fd->methods->fsync)(fd));
}

PR_IMPLEMENT(PRStatus)
PR_Connect(PRFileDesc* fd, const PRNetAddr* addr, PRIntervalTime timeout) {
  return ((fd->methods->connect)(fd, addr, timeout));
}

PR_IMPLEMENT(PRStatus) PR_ConnectContinue(PRFileDesc* fd, PRInt16 out_flags) {
  return ((fd->methods->connectcontinue)(fd, out_flags));
}

PR_IMPLEMENT(PRFileDesc*)
PR_Accept(PRFileDesc* fd, PRNetAddr* addr, PRIntervalTime timeout) {
  return ((fd->methods->accept)(fd, addr, timeout));
}

PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc* fd, const PRNetAddr* addr) {
  return ((fd->methods->bind)(fd, addr));
}

PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc* fd, PRShutdownHow how) {
  return ((fd->methods->shutdown)(fd, how));
}

PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc* fd, PRIntn backlog) {
  return ((fd->methods->listen)(fd, backlog));
}

PR_IMPLEMENT(PRInt32)
PR_Recv(PRFileDesc* fd, void* buf, PRInt32 amount, PRIntn flags,
        PRIntervalTime timeout) {
  return ((fd->methods->recv)(fd, buf, amount, flags, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_Send(PRFileDesc* fd, const void* buf, PRInt32 amount, PRIntn flags,
        PRIntervalTime timeout) {
  return ((fd->methods->send)(fd, buf, amount, flags, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_Writev(PRFileDesc* fd, const PRIOVec* iov, PRInt32 iov_size,
          PRIntervalTime timeout) {
  if (iov_size > PR_MAX_IOVECTOR_SIZE) {
    PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
    return -1;
  }
  return ((fd->methods->writev)(fd, iov, iov_size, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_RecvFrom(PRFileDesc* fd, void* buf, PRInt32 amount, PRIntn flags,
            PRNetAddr* addr, PRIntervalTime timeout) {
  return ((fd->methods->recvfrom)(fd, buf, amount, flags, addr, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_SendTo(PRFileDesc* fd, const void* buf, PRInt32 amount, PRIntn flags,
          const PRNetAddr* addr, PRIntervalTime timeout) {
  return ((fd->methods->sendto)(fd, buf, amount, flags, addr, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_TransmitFile(PRFileDesc* sd, PRFileDesc* fd, const void* hdr, PRInt32 hlen,
                PRTransmitFileFlags flags, PRIntervalTime timeout) {
  return ((sd->methods->transmitfile)(sd, fd, hdr, hlen, flags, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_AcceptRead(PRFileDesc* sd, PRFileDesc** nd, PRNetAddr** raddr, void* buf,
              PRInt32 amount, PRIntervalTime timeout) {
  return ((sd->methods->acceptread)(sd, nd, raddr, buf, amount, timeout));
}

PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc* fd, PRNetAddr* addr) {
  return ((fd->methods->getsockname)(fd, addr));
}

PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc* fd, PRNetAddr* addr) {
  return ((fd->methods->getpeername)(fd, addr));
}

PR_IMPLEMENT(PRStatus)
PR_GetSocketOption(PRFileDesc* fd, PRSocketOptionData* data) {
  return ((fd->methods->getsocketoption)(fd, data));
}

PR_IMPLEMENT(PRStatus)
PR_SetSocketOption(PRFileDesc* fd, const PRSocketOptionData* data) {
  return ((fd->methods->setsocketoption)(fd, data));
}

PR_IMPLEMENT(PRInt32)
PR_SendFile(PRFileDesc* sd, PRSendFileData* sfd, PRTransmitFileFlags flags,
            PRIntervalTime timeout) {
  return ((sd->methods->sendfile)(sd, sfd, flags, timeout));
}

PR_IMPLEMENT(PRInt32)
PR_EmulateAcceptRead(PRFileDesc* sd, PRFileDesc** nd, PRNetAddr** raddr,
                     void* buf, PRInt32 amount, PRIntervalTime timeout) {
  PRInt32 rv = -1;
  PRNetAddr remote;
  PRFileDesc* accepted = NULL;

  /*
  ** The timeout does not apply to the accept portion of the
  ** operation - it waits indefinitely.
  */

  accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT);
  if (NULL == accepted) {
    return rv;
  }

  rv = PR_Recv(accepted, buf, amount, 0, timeout);
  if (rv >= 0) {
    /* copy the new info out where caller can see it */
#define AMASK ((PRPtrdiff)7) /* mask for alignment of PRNetAddr */
    PRPtrdiff aligned = (PRPtrdiff)buf + amount + AMASK;
    *raddr = (PRNetAddr*)(aligned & ~AMASK);
    memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote));
    *nd = accepted;
    return rv;
  }

  PR_Close(accepted);
  return rv;
}

/*
 * PR_EmulateSendFile
 *
 *    Send file sfd->fd across socket sd. If header/trailer are specified
 *    they are sent before and after the file, respectively.
 *
 *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
 *
 *    return number of bytes sent or -1 on error
 *
 */


#if defined(XP_UNIX) || defined(WIN32)

/*
 * An implementation based on memory-mapped files
 */


#  define SENDFILE_MMAP_CHUNK (256 * 1024)

PR_IMPLEMENT(PRInt32)
PR_EmulateSendFile(PRFileDesc* sd, PRSendFileData* sfd,
                   PRTransmitFileFlags flags, PRIntervalTime timeout) {
  PRInt32 rv, count = 0;
  PRInt32 len, file_bytes, index = 0;
  PRFileInfo info;
  PRIOVec iov[3];
  PRFileMap* mapHandle = NULL;
  void* addr = (void*)0; /* initialized to some arbitrary value. Keeps compiler
                            warnings down. */

  PRUint32 file_mmap_offset, alignment;
  PRInt64 zero64;
  PROffset64 file_mmap_offset64;
  PRUint32 addr_offset, mmap_len;

  /* Get file size */
  if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) {
    count = -1;
    goto done;
  }
  if (sfd->file_nbytes && (info.size < (sfd->file_offset + sfd->file_nbytes))) {
    /*
     * there are fewer bytes in file to send than specified
     */

    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    count = -1;
    goto done;
  }
  if (sfd->file_nbytes) {
    file_bytes = sfd->file_nbytes;
  } else {
    file_bytes = info.size - sfd->file_offset;
  }

  alignment = PR_GetMemMapAlignment();

  /* number of initial bytes to skip in mmap'd segment */
  addr_offset = sfd->file_offset % alignment;

  /* find previous mmap alignment boundary */
  file_mmap_offset = sfd->file_offset - addr_offset;

  /*
   * If the file is large, mmap and send the file in chunks so as
   * to not consume too much virtual address space
   */

  mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK);
  len = mmap_len - addr_offset;

  /*
   * Map in (part of) file. Take care of zero-length files.
   */

  if (len) {
    LL_I2L(zero64, 0);
    mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY);
    if (!mapHandle) {
      count = -1;
      goto done;
    }
    LL_I2L(file_mmap_offset64, file_mmap_offset);
    addr = PR_MemMap(mapHandle, file_mmap_offset64, mmap_len);
    if (!addr) {
      count = -1;
      goto done;
    }
  }
  /*
   * send headers first, followed by the file
   */

  if (sfd->hlen) {
    iov[index].iov_base = (char*)sfd->header;
    iov[index].iov_len = sfd->hlen;
    index++;
  }
  if (len) {
    iov[index].iov_base = (char*)addr + addr_offset;
    iov[index].iov_len = len;
    index++;
  }
  if ((file_bytes == len) && (sfd->tlen)) {
    /*
     * all file data is mapped in; send the trailer too
     */

    iov[index].iov_base = (char*)sfd->trailer;
    iov[index].iov_len = sfd->tlen;
    index++;
  }
  rv = PR_Writev(sd, iov, index, timeout);
  if (len) {
    PR_MemUnmap(addr, mmap_len);
  }
  if (rv < 0) {
    count = -1;
    goto done;
  }

  PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0));

  file_bytes -= len;
  count += rv;
  if (!file_bytes) { /* header, file and trailer are sent */
    goto done;
  }

  /*
   * send remaining bytes of the file, if any
   */

  len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
  while (len > 0) {
    /*
     * Map in (part of) file
     */

    file_mmap_offset = sfd->file_offset + count - sfd->hlen;
    PR_ASSERT((file_mmap_offset % alignment) == 0);

    LL_I2L(file_mmap_offset64, file_mmap_offset);
    addr = PR_MemMap(mapHandle, file_mmap_offset64, len);
    if (!addr) {
      count = -1;
      goto done;
    }
    rv = PR_Send(sd, addr, len, 0, timeout);
    PR_MemUnmap(addr, len);
    if (rv < 0) {
      count = -1;
      goto done;
    }

    PR_ASSERT(rv == len);
    file_bytes -= rv;
    count += rv;
    len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
  }
  PR_ASSERT(0 == file_bytes);
  if (sfd->tlen) {
    rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);
    if (rv >= 0) {
      PR_ASSERT(rv == sfd->tlen);
      count += rv;
    } else {
      count = -1;
    }
  }
done:
  if (mapHandle) {
    PR_CloseFileMap(mapHandle);
  }
  if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) {
    PR_Close(sd);
  }
  return count;
}

#else

PR_IMPLEMENT(PRInt32)
PR_EmulateSendFile(PRFileDesc* sd, PRSendFileData* sfd,
                   PRTransmitFileFlags flags, PRIntervalTime timeout) {
  PRInt32 rv, count = 0;
  PRInt32 rlen;
  const void* buffer;
  PRInt32 buflen;
  PRInt32 sendbytes, readbytes;
  char* buf;

#  define _SENDFILE_BUFSIZE (16 * 1024)

  buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE);
  if (buf == NULL) {
    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    return -1;
  }

  /*
   * send header first
   */

  buflen = sfd->hlen;
  buffer = sfd->header;
  while (buflen) {
    rv = PR_Send(sd, buffer, buflen, 0, timeout);
    if (rv < 0) {
      /* PR_Send() has invoked PR_SetError(). */
      rv = -1;
      goto done;
    } else {
      count += rv;
      buffer = (const void*)((const char*)buffer + rv);
      buflen -= rv;
    }
  }

  /*
   * send file next
   */

  if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) {
    rv = -1;
    goto done;
  }
  sendbytes = sfd->file_nbytes;
  if (sendbytes == 0) {
    /* send entire file */
    while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) {
      while (rlen) {
        char* bufptr = buf;

        rv = PR_Send(sd, bufptr, rlen, 0, timeout);
        if (rv < 0) {
          /* PR_Send() has invoked PR_SetError(). */
          rv = -1;
          goto done;
        } else {
          count += rv;
          bufptr = ((char*)bufptr + rv);
          rlen -= rv;
        }
      }
    }
    if (rlen < 0) {
      /* PR_Read() has invoked PR_SetError(). */
      rv = -1;
      goto done;
    }
  } else {
    readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
    while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) {
      while (rlen) {
        char* bufptr = buf;

        rv = PR_Send(sd, bufptr, rlen, 0, timeout);
        if (rv < 0) {
          /* PR_Send() has invoked PR_SetError(). */
          rv = -1;
          goto done;
        } else {
          count += rv;
          sendbytes -= rv;
          bufptr = ((char*)bufptr + rv);
          rlen -= rv;
        }
      }
      readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
    }
    if (rlen < 0) {
      /* PR_Read() has invoked PR_SetError(). */
      rv = -1;
      goto done;
    } else if (sendbytes != 0) {
      /*
       * there are fewer bytes in file to send than specified
       */

      PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
      rv = -1;
      goto done;
    }
  }

  /*
   * send trailer last
   */

  buflen = sfd->tlen;
  buffer = sfd->trailer;
  while (buflen) {
    rv = PR_Send(sd, buffer, buflen, 0, timeout);
    if (rv < 0) {
      /* PR_Send() has invoked PR_SetError(). */
      rv = -1;
      goto done;
    } else {
      count += rv;
      buffer = (const void*)((const char*)buffer + rv);
      buflen -= rv;
    }
  }
  rv = count;

done:
  if (buf) {
    PR_DELETE(buf);
  }
  if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) {
    PR_Close(sd);
  }
  return rv;
}

#endif

/* priometh.c */

Messung V0.5
C=94 H=70 G=82

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.