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

📄 siosup.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 2 页
字号:
			terminate( "SIO __sio_init: bad stream type (internal error).\n" ) ;			/* NOTREACHED */	}	dp->stream_type = stream_type ;	dp->initialized = TRUE ;#ifdef HAS_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 /* HAS_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( odp, fd )	register __sio_od_t *odp ;	int fd ;{	register int b_in_buffer ;	register int cc_total = 0 ;#ifdef EVENTS	EVENT( fd, EV_SIO_WRITEF ) ;#endif	/*	 * 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 ( ;; )	{		register 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 */int __sio_readf( idp, fd )	register __sio_id_t *idp ;	int fd ;{	register int cc ;#ifdef EVENTS	EVENT( fd, EV_SIO_READF ) ;#endif	/*	 * 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 HAS_MMAP	if ( idp->memory_mapped )	{		register 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		{			register 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 /* HAS_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( idp, fd, b_left )	register __sio_id_t *idp ;	int fd ;	register int b_left ;{	register int b_read ;#ifdef EVENTS	EVENT( fd, EV_SIO_EXTEND_BUFFER ) ;#endif	/*	 * 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( idp, fd )	register __sio_id_t *idp ;	int fd ;{	register int b_left = &idp->buf[ idp->buffer_size ] - idp->end ;	register int cc ;#ifdef EVENTS	EVENT( fd, EV_SIO_MORE ) ;#endif	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 */int Sdone( fd )	int fd ;{	register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;#ifdef EVENTS	EVENT( fd, EV_SDONE ) ;#endif	if ( ! DESCRIPTOR_INITIALIZED( dp ) )	{		errno = EBADF ;		return( SIO_ERR ) ;	}	switch ( dp->stream_type )	{		case __SIO_INPUT_STREAM:			{				register __sio_id_t *idp = IDP( dp ) ;#ifdef HAS_MMAP				if ( idp->memory_mapped )				{					register 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	/* HAS_MMAP */					free( idp->buf - idp->buffer_size ) ;					idp->nextb = idp->end = NULL ;			}			break ;				case __SIO_OUTPUT_STREAM:			{				register __sio_od_t *odp = ODP( dp ) ;				if ( Sflush( fd ) == SIO_ERR )					return( SIO_ERR ) ;				free( odp->buf ) ;				odp->nextb = odp->buf_end = NULL ;			}			break ;				default:			terminate( "SIO Sdone: bad stream type\n" ) ;	}	dp->initialized = FALSE ;	return( 0 ) ;}PRIVATE char *expand( area, old_size, new_size, is_static )	char *area ;	unsigned old_size, 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 ) ;}#include <sys/time.h>#include <sys/resource.h>PRIVATE int get_fd_limit(){#ifdef RLIMIT_NOFILE	struct rlimit rl ;	(void) getrlimit( RLIMIT_NOFILE, &rl ) ;	return( rl.rlim_cur ) ;#else	return( N_SIO_DESCRIPTORS ) ;#endif}/* * 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(){	char *p ;	int is_static ;	unsigned new_size, old_size ;	int n_fds = get_fd_limit() ;	if ( n_fds <= n_descriptors )		return( 0 ) ;#ifdef EVENTS	old_size = n_descriptors * sizeof( events_s ) ;	new_size = n_fds * sizeof( events_s ) ;	is_static = ( __sio_events == static___sio_events ) ;	p = expand( (char *)__sio_events, old_size, new_size, is_static ) ;	if ( p == NULL )		return( SIO_ERR ) ;	__sio_events = (events_s *) p ;	/*	 * Clear the codes field of the extra events structs.	 * We have to do this because a non-null codes field implies that	 * events recording is on for that fd	 */	{		int i ;		for ( i = n_descriptors ; i < n_fds ; i++ )			__sio_events[i].codes = NULL ;	}#endif	/* EVENTS */#ifdef HAS_MMAP	old_size = n_descriptors * sizeof( mapd_s ) ;	new_size = n_fds * sizeof( mapd_s ) ;	is_static = ( mmap_descriptors == static_mapd_array ) ;	p = expand( (char *)mmap_descriptors, old_size, new_size, is_static ) ;	if ( p == NULL )		return( SIO_ERR ) ;	mmap_descriptors = (mapd_s *) p ;#endif	/* HAS_MMAP */		old_size = n_descriptors * sizeof( __sio_descriptor_t ) ;	new_size = n_fds * sizeof( __sio_descriptor_t ) ;	is_static =  ( __sio_descriptors == static_descriptor_array ) ;	p = expand( (char *)__sio_descriptors, old_size, new_size, is_static ) ;	if ( p == NULL )		return( SIO_ERR ) ;	__sio_descriptors = (__sio_descriptor_t *) p ;	n_descriptors = n_fds ;	return( 0 ) ;}#ifdef EVENTS/* * Enable recording of events for the specified file descriptor */int __sio_enable_events( fd )	int fd ;{	char *p = malloc( EVENT_ENTRIES * sizeof( short ) ) ;	if ( p == NULL )		return( SIO_ERR ) ;	__sio_events[ fd ].codes = (short *) p ;	return( 0 ) ;}/* * Disable recording of events for the specified file descriptor */void __sio_disable_events( fd )	int fd ;{	if ( __sio_events[ fd ].codes != NULL )	{		free( (char *) __sio_events[ fd ].codes ) ;		__sio_events[ fd ].codes = NULL ;	}}/* * Move stored events to buf */int __sio_get_events( fd, buf, size )	int fd ;	char *buf ;	int size ;{	events_s *evp = &__sio_events[ fd ] ;	int bufentries ;	int range1, range2 ;	int diff ;	char *p ;	int cc ;	int cc_total ;	int move_entries ;	if ( evp->codes == NULL )		return( 0 ) ;		diff = evp->next - evp->start ;	if ( diff == 0 )		return( 0 ) ;	if ( diff > 0 )	{		range1 = diff ;		range2 = 0 ;	}	else	{		range1 = EVENT_ENTRIES - evp->start ;		range2 = evp->next ;	}	bufentries = size / sizeof( short ) ;	p = buf ;	cc_total = 0 ;	move_entries = MIN( range1, bufentries ) ;	cc = move_entries * sizeof( short ) ;	sio_memcopy( (char *) &evp->codes[ evp->start ], p, cc ) ;	cc_total += cc ;	p += cc ;	bufentries -= range1 ;	ADD( evp->start, move_entries ) ;	if ( bufentries == 0 || range2 == 0 )		return( cc_total ) ;	move_entries = MIN( range2, bufentries ) ;	cc = move_entries * sizeof( short ) ;	sio_memcopy(  (char *) &evp->codes[ evp->start ], p, cc ) ;	cc_total += cc ;	ADD( evp->start, move_entries ) ;	return( cc_total ) ;}#endif 	/* EVENTS *//* * Simple function that prints the string s at stderr and then calls * exit */PRIVATE void terminate( s )	char *s ;{	(void) write( 2, s, strlen( s ) ) ;	(void) abort() ;	exit( 1 ) ;				/* in case abort fails */}

⌨️ 快捷键说明

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