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

📄 siosup.c

📁 牛顿插值方法求解多项式的系数
💻 C
📖 第 1 页 / 共 2 页
字号:
      return( FALSE ) ;   else      return( TRUE ) ;}#endif   /* HAVE_BSDTTY */#endif   /* ! HAVE_ISATTY *//* * Initialize stream I/O for a file descriptor. * * Arguments: *      fd:            file descriptor *      dp:            descriptor pointer *      stream_type:    either __SIO_INPUT_STREAM or __SIO_OUTPUT_STREAM * * Returns *      0          if successful *     SIO_ERR   if the file descriptor is not valid (sets errno) *   exits      if stream_type is not __SIO_INPUT_STREAM or __SIO_OUTPUT_STREAM */int __sio_init( __sio_descriptor_t *dp, int fd, enum __sio_stream stream_type ){   struct stat st ;   memset(dp, 0, sizeof(__sio_descriptor_t));   if ( fd >= __sio_n_descriptors )   {      errno = EBADF ;      return( SIO_ERR ) ;   }   if ( fstat( fd, &st ) == -1 )      return( SIO_ERR ) ;      switch ( stream_type )   {      case __SIO_INPUT_STREAM:         if ( init_input_stream( IDP( dp ), fd, &st ) == FAILURE )            return( SIO_ERR ) ;         break ;      case __SIO_OUTPUT_STREAM:         if ( init_output_stream( ODP( dp ), fd, &st ) == FAILURE )            return( SIO_ERR ) ;         break ;               default:         terminate( "SIO __sio_init: bad stream type (internal error).\n" ) ;         /* NOTREACHED */   }   dp->stream_type = stream_type ;   dp->initialized = TRUE ;#ifdef HAVE_FINALIZATION_FUNCTION   if ( ! finalizer_installed )   {      if ( ! SIO_FINALIZE( sio_cleanup ) )      {         char *s = "SIO __sio_init: finalizer installation failed\n" ;         (void) write( 2, s, strlen( s ) ) ;      }      else         finalizer_installed = TRUE ;   }#endif /* HAVE_FINALIZATION_FUNCTION */   return( 0 ) ;}/* * __sio_writef writes the data in the buffer to the file descriptor. * * It tries to write as much data as possible until either all data * are written or an error occurs. EINTR is the only error that is * ignored. * In case an error occurs but some data were written, that number * is returned instead of SIO_ERR. * * Fields modified: *      When successful: start, nextb *      When not successful: start * * Return value: *      Number of bytes written *      SIO_ERR, if write(2) fails and no data were written */ int __sio_writef( __sio_od_t *odp, int fd ){   int b_in_buffer ;   int cc_total = 0 ;   /*    * Make sure we don't exceed the buffer limits    *   Maybe we should log this ?         XXX    */   if ( odp->nextb > odp->buf_end )      odp->nextb = odp->buf_end ;   b_in_buffer = odp->nextb - odp->start ;   if ( b_in_buffer == 0 )      return( 0 ) ;      for ( ;; )   {      int cc ;      cc = write( fd, odp->start, b_in_buffer ) ;      if ( cc == b_in_buffer )      {         odp->start = odp->nextb = odp->buf ;         cc_total += cc ;         break ;      }      else if ( cc == -1 )      {         if ( errno == EINTR )            continue ;         else            /*             * If some bytes were written, return that number, otherwise             * return SIO_ERR             */            return( ( cc_total != 0 ) ? cc_total : SIO_ERR ) ;      }      else         /* some bytes were written */      {         odp->start += cc ;         /* advance start of buffer */         b_in_buffer -= cc ;         /* decrease number bytes left in buffer */         cc_total += cc ;            /* count the bytes that were written */      }   }   return( cc_total ) ;}/* * __sio_readf reads data from the file descriptor into the buffer. * Unlike __sio_writef it does NOT try to read as much data as will fit * in the buffer. It ignores EINTR. * * Returns: # of bytes read or SIO_ERR * * Fields set: *       If it does not return SIO_ERR, it sets start, nextb, end *         If it returns SIO_ERR, it does not change anything */static int __sio_readf( __sio_id_t *idp, int fd ){   int cc ;   /*    * First check for a tied fd and flush the stream if necessary    *    *       XXX   the return value of __sio_writef is not checked.    *               Is that right ?    */   if ( idp->tied_fd != SIO_NO_TIED_FD )      (void) __sio_writef( &__SIO_OD( idp->tied_fd ), idp->tied_fd ) ;#ifdef HAVE_MMAP   if ( idp->memory_mapped )   {      mapd_s *mdp = MDP( fd ) ;      /*       * The functions initial_map and map_unit may fail.       * In either case, we switch to buffered I/O.       * If initial_map fails, we have read no data, so we       * should perform a read(2).       * If map_unit fails (for the next unit), we still have       * the data in the current unit, so we can return.       */      if ( FIRST_TIME( idp ) )      {         cc = initial_map( mdp, fd ) ;         if ( cc > 0 )            idp->buf = mdp->first_unit.addr ;         else         {            if ( __sio_switch( idp, fd ) == FAILURE )               return( SIO_ERR ) ;            cc = -1 ;         }      }      else      {         struct map_unit *mu_cur, *mu_next ;         if ( idp->buf == mdp->first_unit.addr )         {            mu_cur = &mdp->first_unit ;            mu_next = &mdp->second_unit ;         }         else         {            mu_cur = &mdp->second_unit ;            mu_next = &mdp->first_unit ;         }         if ( mu_next->addr != NULL )         {            idp->buf = mu_next->addr ;            cc = mu_next->valid_bytes ;            /*             * XXX:  Here we may return SIO_ERR even though there             *         are data in the current unit because the switch             *         fails (possibly because malloc failed).             */            if ( map_unit( mdp, fd, mu_cur ) == FAILURE &&                              __sio_switch( idp, fd ) == FAILURE )               return( SIO_ERR ) ;         }         else            cc = 0 ;      }      if ( cc >= 0 )      {         idp->end = idp->buf + cc ;         idp->start = idp->nextb = idp->buf ;         return( cc ) ;      }   }#endif /* HAVE_MMAP */   for ( ;; )   {      cc = read( fd, idp->buf, (int) idp->buffer_size ) ;      if ( cc == -1 )         if ( errno == EINTR )            continue ;         else            return( SIO_ERR ) ;      else         break ;   }   idp->end = idp->buf + cc ;   idp->start = idp->nextb = idp->buf ;   return( cc ) ;}/* * __sio_extend_buffer is used by Srdline to extend the buffer * If successful, it returns the number of bytes that have been read. * If it fails (because of end-of-file or I/O error), it returns 0 or -1. * * Fields modified: *    idp->start points to the start of the buffer area (which is in the *    auxiliary buffer) *      Also, if successful, idp->nextb is set to idp->buf, idp->end is modified. */int __sio_extend_buffer( __sio_id_t *idp, int fd, int b_left ){   int b_read ;   /*    * copy to auxiliary buffer    */   if ( b_left )      sio_memcopy( idp->nextb, idp->buf - b_left, b_left ) ;   b_read = __sio_readf( idp, fd ) ;   idp->start = idp->buf - b_left ;   return( b_read ) ;}/* * __sio_more tries to read more data from the given file descriptor iff * there is free space in the buffer. * __sio_more is used only by Srdline and only AFTER __sio_extend_buffer * has been called. This implies that  *      a) this is not a memory mapped file *      b) __sio_readf has been called (so we don't need to check for tied fd's * * Fields modified (only if successful): *         idp->end * * Return value: the number of bytes read. */int __sio_more( __sio_id_t *idp, int fd ){   int b_left = &idp->buf[ idp->buffer_size ] - idp->end ;   int cc ;   if ( b_left <= 0 )      return( 0 ) ;      for ( ;; )   {      cc = read( fd, idp->end, b_left ) ;      if ( cc >= 0 )      {         idp->end += cc ;         return( cc ) ;      }      else         if ( errno == EINTR )            continue ;         else            return( SIO_ERR ) ;   }}/* * Finalize a buffer by unmapping the file or freeing the malloc'ed memory. * This function is only called by Sclose. We always free memory even if * SIO_ERR is returned as long as the descriptor was initialized. */int Sdone( int fd ){   __sio_descriptor_t *dp ;   int ret_val = 0;   if ( fd < 0 || fd >= __sio_n_descriptors )   {      errno = EBADF ;      return( SIO_ERR ) ;   }   dp = &__sio_descriptors[ fd ] ;   if ( ! DESCRIPTOR_INITIALIZED( dp ) )   {      errno = EBADF ;      return( SIO_ERR ) ;   }   switch ( dp->stream_type )   {      case __SIO_INPUT_STREAM:         {            __sio_id_t *idp = IDP( dp ) ;#ifdef HAVE_MMAP            if ( idp->memory_mapped )            {               mapd_s *mdp = MDP( fd ) ;               if ( mdp->first_unit.addr != CHAR_NULL )                  (void) SIO_MUNMAP( mdp->first_unit.addr,                                          mdp->first_unit.mapped_bytes ) ;               if ( mdp->second_unit.addr != CHAR_NULL )                  (void) SIO_MUNMAP( mdp->second_unit.addr,                                          mdp->second_unit.mapped_bytes ) ;               idp->memory_mapped = FALSE ;            }            else#endif   /* HAVE_MMAP */               free( idp->buf - idp->buffer_size ) ;               idp->nextb = idp->end = NULL ;         }         break ;            case __SIO_OUTPUT_STREAM:         {            __sio_od_t *odp = ODP( dp ) ;            if ( Sflush( fd ) == SIO_ERR )               ret_val = SIO_ERR;            free( odp->buf ) ;            odp->nextb = odp->buf_end = NULL ;         }         break ;            default:         terminate( "SIO Sdone: bad stream type\n" ) ;   }   memset( dp, 0, sizeof(__sio_descriptor_t) );   dp->initialized = FALSE ;   return ret_val;}static char *sioexpand( char *area, unsigned old_size, unsigned new_size, int is_static ){   char *new_area ;   if ( is_static )   {      if ( ( new_area = malloc( new_size ) ) == NULL )         return( NULL ) ;      sio_memcopy( area, new_area, old_size ) ;   }   else      if ( ( new_area = realloc( area, new_size ) ) == NULL )         return( NULL ) ;         return( new_area ) ;}/* * Expand the descriptor array (and if we use memory mapping the * memory mapping descriptors). We first expand the memory mapping * descriptors. * There is no problem if the expansion of the SIO descriptors fails * (i.e. there is no need to undo anything). */int Smorefds(int fd){   char *p ;   int is_static ;   unsigned new_size, old_size ;   int n_fds = 4; /* Let's bump 4 at a time for hysteresis */   /* If the fd is out of range of the proposed size, make n_fds big enough */   if (fd >= (__sio_n_descriptors+n_fds))      n_fds += fd - __sio_n_descriptors;#ifdef HAVE_MMAP   old_size = __sio_n_descriptors * sizeof( mapd_s ) ;   new_size = n_fds * sizeof( mapd_s ) ;   new_size += old_size;   is_static = ( mmap_descriptors == NULL ) ;   p = sioexpand( (char *)mmap_descriptors, old_size, new_size, is_static ) ;   if ( p == NULL )      return( SIO_ERR ) ;   memset(p+old_size, 0, new_size-old_size);   mmap_descriptors = (mapd_s *) p ;#endif   /* HAVE_MMAP */      old_size = __sio_n_descriptors * sizeof( __sio_descriptor_t ) ;   new_size = n_fds * sizeof( __sio_descriptor_t ) ;   new_size += old_size;   is_static =  ( __sio_descriptors == NULL ) ;   p = sioexpand( (char *)__sio_descriptors, old_size, new_size, is_static ) ;   if ( p == NULL )      return( SIO_ERR ) ;   memset(p+old_size, 0, new_size-old_size);   __sio_descriptors = (__sio_descriptor_t *) p ;   __sio_n_descriptors += n_fds ;   return( 0 ) ;}void terminate(const char *msg){      syslog(LOG_CRIT, "%s", msg);      (void) abort() ;      _exit( 1 ) ;      /* NOT REACHED */}

⌨️ 快捷键说明

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