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

📄 sfpkrd.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       */#include	"sfhdr.h"#if !_PACKAGE_ast#ifndef FIONREAD#if _sys_ioctl#include	<sys/ioctl.h>#endif#endif#endif/*	Read/Peek a record from an unseekable device****	Written by Kiem-Phong Vo.*/#define STREAM_PEEK	001#define SOCKET_PEEK	002#if __STD_Cssize_t sfpkrd(int fd, Void_t* argbuf, size_t n, int rc, long tm, int action)#elsessize_t sfpkrd(fd, argbuf, n, rc, tm, action)int	fd;	/* file descriptor */Void_t*	argbuf;	/* buffer to read data */size_t	n;	/* buffer size */int	rc;	/* record character */long	tm;	/* time-out */int	action;	/* >0: peeking, if rc>=0, get action records,		   <0: no peeking, if rc>=0, get -action records,		   =0: no peeking, if rc>=0, must get a single record		*/#endif{	reg ssize_t	r;	reg int		ntry, t;	reg char	*buf = (char*)argbuf, *endbuf;	if(rc < 0 && tm < 0 && action <= 0)		return sysreadf(fd,buf,n);	t = (action > 0 || rc >= 0) ? (STREAM_PEEK|SOCKET_PEEK) : 0;#if !_stream_peek	t &= ~STREAM_PEEK;#endif#if !_socket_peek	t &= ~SOCKET_PEEK;#endif	for(ntry = 0; ntry < 2; ++ntry)	{		r = -1;#if _stream_peek		if((t&STREAM_PEEK) && (ntry == 1 || tm < 0) )		{			struct strpeek	pbuf;			pbuf.flags = 0;			pbuf.ctlbuf.maxlen = -1;			pbuf.ctlbuf.len = 0;			pbuf.ctlbuf.buf = NIL(char*);			pbuf.databuf.maxlen = n;			pbuf.databuf.buf = buf;			pbuf.databuf.len = 0;			if((r = ioctl(fd,I_PEEK,&pbuf)) < 0)			{	if(errno == EINTR)					return -1;				t &= ~STREAM_PEEK;			}			else			{	t &= ~SOCKET_PEEK;				if(r > 0 && (r = pbuf.databuf.len) <= 0)				{	if(action <= 0)	/* read past eof */						r = sysreadf(fd,buf,1);					return r;				}				if(r == 0)					r = -1;				else if(r > 0)					break;			}		}#endif /* stream_peek */		if(ntry == 1)			break;		/* poll or select to see if data is present.  */		while(tm >= 0 || action > 0 ||			/* block until there is data before peeking again */			((t&STREAM_PEEK) && rc >= 0) ||			/* let select be interrupted instead of recv which autoresumes */			(t&SOCKET_PEEK) )		{	r = -2;#if _lib_poll			if(r == -2)			{				struct pollfd	po;				po.fd = fd;				po.events = POLLIN;				po.revents = 0;				if((r = SFPOLL(&po,1,tm)) < 0)				{	if(errno == EINTR)						return -1;					else if(errno == EAGAIN)					{	errno = 0;						continue;					}					else	r = -2;				}				else	r = (po.revents&POLLIN) ? 1 : -1;			}#endif /*_lib_poll*/#if _lib_select			if(r == -2)			{#if _hpux_threads && vt_threaded#define fd_set	int#endif				fd_set		rd;				struct timeval	tmb, *tmp;				FD_ZERO(&rd);				FD_SET(fd,&rd);				if(tm < 0)					tmp = NIL(struct timeval*);				else				{	tmp = &tmb;					tmb.tv_sec = tm/SECOND;					tmb.tv_usec = (tm%SECOND)*SECOND;				}				r = select(fd+1,&rd,NIL(fd_set*),NIL(fd_set*),tmp);				if(r < 0)				{	if(errno == EINTR)						return -1;					else if(errno == EAGAIN)					{	errno = 0;						continue;					}					else	r = -2;				}				else	r = FD_ISSET(fd,&rd) ? 1 : -1;			}#endif /*_lib_select*/			if(r == -2)			{#if !_lib_poll && !_lib_select	/* both poll and select cann't be used */#ifdef FIONREAD			/* quick and dirty check for availability */				long	nsec = tm < 0 ? 0 : (tm+999)/1000;				while(nsec > 0 && r < 0)				{	long	avail = -1;					if((r = ioctl(fd,FIONREAD,&avail)) < 0)					{	if(errno == EINTR)							return -1;						else if(errno == EAGAIN)						{	errno = 0;							continue;						}						else	/* ioctl failed completely */						{	r = -2;							break;						}					}					else	r = avail <= 0 ? -1 : (ssize_t)avail;					if(r < 0 && nsec-- > 0)						sleep(1);				}#endif#endif			}			if(r > 0)		/* there is data now */			{	if(action <= 0 && rc < 0)					return sysreadf(fd,buf,n);				else	r = -1;			}			else if(tm >= 0)	/* timeout exceeded */				return -1;			else	r = -1;			break;		}#if _socket_peek		if(t&SOCKET_PEEK)		{			while((r = recv(fd,(char*)buf,n,MSG_PEEK)) < 0)			{	if(errno == EINTR)					return -1;				else if(errno == EAGAIN)				{	errno = 0;					continue;				}				t &= ~SOCKET_PEEK;				break;			}			if(r >= 0)			{	t &= ~STREAM_PEEK;				if(r > 0)					break;				else	/* read past eof */				{	if(action <= 0)						r = sysreadf(fd,buf,1);					return r;				}			}		}#endif	}	if(r < 0)	{	if(tm >= 0 || action > 0)			return -1;		else /* get here means: tm < 0 && action <= 0 && rc >= 0 */		{	/* number of records read at a time */			if((action = action ? -action : 1) > (int)n)				action = n;			r = 0;			while((t = sysreadf(fd,buf,action)) > 0)			{	r += t;				for(endbuf = buf+t; buf < endbuf;)					if(*buf++ == rc)						action -= 1;				if(action == 0 || (int)(n-r) < action)					break;			}			return r == 0 ? t : r;		}	}	/* successful peek, find the record end */	if(rc >= 0)	{	reg char*	sp;			t = action == 0 ? 1 : action < 0 ? -action : action;		for(endbuf = (sp = buf)+r; sp < endbuf; )			if(*sp++ == rc)				if((t -= 1) == 0)					break;		r = sp - buf;	}	/* advance */	if(action <= 0)		r = sysreadf(fd,buf,r);	return r;}

⌨️ 快捷键说明

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