sfpkrd.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#include "sfhdr.h"
#if !_PACKAGE_ast
#ifndef FIONREAD
#if _sys_ioctl
#endif
#endif
#endif
**
** Written by Kiem-Phong Vo.
*/
#define STREAM_PEEK 001
#define SOCKET_PEEK 002
#if __STD_C
#else
int fd; /* file descriptor */
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
{
#if !_stream_peek
t &= ~STREAM_PEEK;
#endif
#if !_socket_peek
t &= ~SOCKET_PEEK;
#endif
{
r = -1;
#if _stream_peek
{
#ifdef __sun
/*
* I_PEEK on stdin can hang rsh+ksh on solaris
*/
static int stream_peek;
if (stream_peek == 0) /* this will be done just once */
{ char *e;
stream_peek = (
getenv("LOGNAME") == 0 &&
getenv("MAIL") == 0 &&
) ? -1 : 1;
}
if(stream_peek < 0)
t &= ~STREAM_PEEK;
else
#endif
return -1;
t &= ~STREAM_PEEK;
}
else
{ t &= ~SOCKET_PEEK;
{ if(action <= 0) /* read past eof */
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. */
/* 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)
{
return -1;
{ errno = 0;
continue;
}
else r = -2;
}
}
#endif /*_lib_poll*/
#if _lib_select
if(r == -2)
{
#if _hpux_threads && vt_threaded
#define fd_set int
#endif
if(tm < 0)
else
}
if(r < 0)
return -1;
{ errno = 0;
continue;
}
else r = -2;
}
}
#endif /*_lib_select*/
if(r == -2)
{
#ifdef FIONREAD /* quick and dirty check for availability */
while(nsec > 0 && r < 0)
{ long avail = -1;
return -1;
{ errno = 0;
continue;
}
else /* ioctl failed completely */
{ r = -2;
break;
}
}
if(r < 0 && nsec-- > 0)
sleep(1);
}
#endif
#endif
}
if(r > 0) /* there is data now */
else r = -1;
}
else if(tm >= 0) /* timeout exceeded */
return -1;
else r = -1;
break;
}
#if _socket_peek
if(t&SOCKET_PEEK)
{
static int recv_peek_pipe;
if (recv_peek_pipe == 0) /* this will be done just once */
{ int fds[2], r;
char tst[2];
/* open a pipe and write to it */
recv_peek_pipe = 1;
recv_peek_pipe = -1;
recv_peek_pipe = -1;
/* try recv() to see if it gets anything */
recv_peek_pipe = -1;
recv_peek_pipe = -1;
/* make sure that recv() did not consume data */
recv_peek_pipe = -1;
recv_peek_pipe = -1;
}
if(recv_peek_pipe < 0)
{ r = -1;
t &= ~SOCKET_PEEK;
}
}
#endif
return -1;
errno = 0;
else t &= ~SOCKET_PEEK;
}
if(r >= 0)
{ t &= ~STREAM_PEEK;
if(r > 0)
break;
else /* read past eof */
{ if(action <= 0)
return r;
}
}
}
#endif
}
if(r < 0)
return -1;
else /* get here means: tm < 0 && action <= 0 && rc >= 0 */
{ /* number of records read at a time */
action = n;
r = 0;
{ r += t;
action -= 1;
break;
}
return r == 0 ? t : r;
}
}
/* successful peek, find the record end */
if(rc >= 0)
if((t -= 1) == 0)
break;
}
/* advance */
if(action <= 0)
return r;
}