/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* 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"
/* Add a new discipline to the discipline stack. Each discipline
** provides alternative I/O functions that are analogues of the
** system calls.
**
** When the application fills or flushes the stream buffer, data
** will be processed through discipline functions. A case deserving
** consideration is stacking a discipline onto a read stream. Each
** discipline operation implies buffer synchronization so the stream
** buffer should be empty. However, a read stream representing an
** unseekable device (eg, a pipe) may not be synchronizable. In that
** case, any buffered data must then be fed to the new discipline
** to preserve data processing semantics. This is done by creating
** a temporary discipline to cache such buffered data and feed
** them to the new discipline when its readf() asks for new data.
** Care must then be taken to remove this temporary discipline
** when it runs out of cached data.
**
** Written by Kiem-Phong Vo
*/
typedef struct _dccache_s
} Dccache_t;
#if __STD_C
#else
Sfio_t* f;
int type;
#endif
{
return 0;
}
#if __STD_C
#else
Sfio_t* f;
#endif
{
if(!f) /* bad stream */
return -1;
/* make sure that this is on the discipline stack */
break;
if(!prev)
return -1;
if(size <= 0) /* nothing to do */
return size;
/* read from available data */
}
return sz;
}
#if __STD_C
#else
Sfio_t* f;
#endif
{
ssize_t n;
SFMTXDECL(f);
SFMTXRETURN(f,f->disc);
{ /* make sure in read mode to check for read-ahead data */
}
else
}
SFLOCK(f,0);
/* disallow popping while there is cached data */
goto done;
/* synchronize before switching to a new discipline */
{ (void)SFSYNC(f); /* do a silent buffer synch */
}
/* if there is buffered data, ask app before proceeding */
{ int rv = 0;
{ SFOPEN(f,0);
SFLOCK(f,0);
}
{ SFOPEN(f,0);
SFLOCK(f,0);
}
if(rv < 0)
goto done;
}
/* trick the new discipline into processing already buffered data */
goto done;
/* move buffered data into the temp discipline */
}
}
/* save old readf, writef, and seekf to see if stream need reinit */
}
if(disc == SF_POPDISC)
{ /* popping, warn the being popped discipline */
if(!(d = f->disc) )
goto done;
if(d->exceptf)
{ SFOPEN(f,0);
goto done;
SFLOCK(f,0);
}
rdisc = d;
}
else
{ /* pushing, warn being pushed discipline */
do
{ /* loop to handle the case where d may pop itself */
d = f->disc;
if(d && d->exceptf)
{ SFOPEN(f,0);
goto done;
SFLOCK(f,0);
}
} while(d != f->disc);
/* make sure we are not creating an infinite loop */
for(; d; d = d->disc)
if(d == disc)
goto done;
/* set new disc */
if(dcca) /* insert the discipline with cached data */
}
}
{ /* this stream may have to be reinitialized */
if(!reinit) \
reinit = 1; \
}
if(reinit)
{ SETLOCAL(f);
else
}
}
}
done :
SFOPEN(f,0);
SFMTXRETURN(f, rdisc);
}