/***********************************************************************
* *
* 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"
/* Functions to set a given stream to some desired mode
**
** Written by Kiem-Phong Vo.
**
** Modifications:
** 06/27/1990 (first version)
** 01/06/1991
** 07/08/1991
** 06/18/1992
** 02/02/1993
** 05/25/1993
** 02/07/1994
** 05/21/1996
** 08/01/1997
** 08/01/1998 (extended formatting)
** 09/09/1999 (thread-safe)
** 02/01/2001 (adaptive buffering)
** 09/06/2002 (SF_IOINTR flag)
** 11/15/2002 (%#c for sfvprintf)
** 05/31/2003 (sfsetbuf(f,f,align_size) to set alignment for data)
** (%I1d is fixed to handle "signed char" correctly)
** 01/01/2004 Porting issues to various platforms resolved.
** 09/15/2008 Add sfwalk().
*/
/* the below is for protecting the application from SIGPIPE */
#if _PACKAGE_ast
#include <sig.h>
#include <wait.h>
#else
#include <signal.h>
#endif
/* done at exiting time */
#if __STD_C
static void _sfcleanup(void)
#else
static void _sfcleanup()
#endif
{
reg int n;
/* set this so that no more buffering is allowed for write streams */
_Sfexiting = 1001;
{ for(n = 0; n < p->n_sf; ++n)
continue;
SFLOCK(f,0);
SFMTXLOCK(f);
/* let application know that we are leaving */
continue;
/* from now on, write streams are unbuffered */
if(f->data &&
SFMTXUNLOCK(f);
SFOPEN(f,0);
}
}
}
/* put into discrete pool */
#if __STD_C
#else
int _sfsetpool(f)
Sfio_t* f;
#endif
{
if(!_Sfcleanup)
{ _Sfcleanup = _sfcleanup;
(void)atexit(_sfcleanup);
}
if(!(p = f->pool) )
POOLMTXENTER(p);
rv = -1;
{ if(p->s_sf == 0) /* initialize pool array */
}
else /* allocate a larger array */
goto done;
/* move old array to new one */
p->s_sf = n;
}
}
/* always add at end of array because if this was done during some sort
of walk thru all streams, we'll want the new stream to be seen.
*/
rv = 0;
done:
POOLMTXRETURN(p, rv);
}
#if __STD_C
#else
#endif
{
/* make buffer if nothing yet */
size = -1;
else
{ if(rsrv)
}
}
}
}
#ifdef SIGPIPE
#if __STD_C
#else
int sig;
#endif
{
}
#endif
#if __STD_C
#else
int fd;
int pid;
int stdio; /* stdio popen() does not reset SIGPIPE handler */
#endif
{
if(f->proc)
return 0;
return -1;
#ifdef SIGPIPE /* protect from broken pipe signal */
if(p->sigp)
_Sfsigp += 1;
(void)vtmtxunlock(_Sfmutex);
}
#endif
return 0;
}
#if __STD_C
#else
int _sfpclose(f)
#endif
{
Sfproc_t* p;
if(!(p = f->proc))
return -1;
if(p->rdata)
if(p->pid < 0)
status = 0;
else
{ /* close the associated stream */
if(p->file >= 0)
/* wait for process termination */
#if _PACKAGE_ast
#endif
status = -1;
;
#if _PACKAGE_ast
sigcritical(0);
#endif
#ifdef SIGPIPE
_Sfsigp = 0;
}
(void)vtmtxunlock(_Sfmutex);
#endif
}
free(p);
return status;
}
#if __STD_C
#else
Sfio_t* f;
int type;
#endif
{
Sfproc_t* p;
if(!(p = f->proc) )
return -1;
{ /* save unread data */
{ if(p->rdata)
else
{ p->size = 0;
return -1;
}
}
if(p->ndata > 0)
}
else
{ /* restore read data */
if(p->ndata > 0)
p->ndata = 0;
}
}
/* switch file descriptor */
if(p->pid >= 0)
}
return 0;
}
#if __STD_C
#else
#endif
{
reg int n;
SFONCE(); /* initialize mutexes */
}
}
{ local = 1;
goto err_notify;
}
for(;;)
return rv;
{ if(rv == 0)
{ local = 1;
goto err_notify;
}
else continue;
}
else break;
}
}
#ifdef MAP_TYPE
{ /* turn off mmap to avoid page faulting */
f->tiny[0] = 0;
}
else
#endif
if(f->getr)
f->getr = 0;
}
}
(*_Sfstdsync)(f);
{ local = 1;
goto err_notify;
}
{ /* move to head of pool */
{ local = 1;
goto err_notify;
}
}
/* buffer initialization */
{
if(!f->pool && _sfsetpool(f) < 0)
{ rv = -1;
goto done;
}
if(wanted == 0)
goto done;
goto err_notify;
f->size : 0;
f->here = 0;
}
else
{ n = f->flags;
}
}
goto done;
switch(SFMODE(f,1))
{
case SF_WRITE: /* switching to SF_READ */
break;
goto err_notify;
{ SFSTRSIZE(f);
break;
}
/* reset buffer */
goto err_notify;
if(f->size == 0)
{ /* unbuffered */
}
/* restore saved read data for coprocess */
goto err_notify;
break;
{ /* just reset the pointers */
/* see if must go with new physical location */
{
#ifdef MAP_TYPE
}
#endif
}
else
goto err_notify;
}
break;
}
/* fall thru */
case SF_READ: /* switching to SF_WRITE */
break;
goto err_notify;
break;
}
/* save unread data before switching mode */
goto err_notify;
/* reset buffer and seek pointer */
{ /* reset file pointer */
goto err_notify;
}
}
#ifdef MAP_TYPE
{ if(f->data)
}
#endif
f->size = 0;
}
break;
default: /* unknown case */
/* set errno for operations that access wrong stream type */
if(_Sfnotify) /* notify application of the error */
rv = -1;
break;
}
done:
return rv;
}