/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2010 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 *
* http://www.opensource.org/licenses/cpl1.0.txt *
* (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"
/* Invoke event handlers for a stream
**
** Written by Kiem-Phong Vo.
*/
#if __STD_C
static int _sfraiseall(int type, Void_t* data)
#else
static int _sfraiseall(type, data)
int type; /* type of event */
Void_t* data; /* associated data */
#endif
{
Sfio_t *f;
Sfpool_t *p, *next;
int n, rv;
rv = 0;
for(p = &_Sfpool; p; p = next)
{
for(next = p->next; next; next = next->next)
if(next->n_sf > 0)
break;
for(n = 0; n < p->n_sf; ++n)
{ f = p->sf[n];
if(sfraise(f, type, data) < 0)
rv -= 1;
}
}
return rv;
}
#if __STD_C
int sfraise(Sfio_t* f, int type, Void_t* data)
#else
int sfraise(f, type, data)
Sfio_t* f; /* stream */
int type; /* type of event */
Void_t* data; /* associated data */
#endif
{
reg Sfdisc_t *disc, *next, *d;
reg int local, rv;
SFMTXDECL(f);
if(!f)
return _sfraiseall(type,data);
SFMTXENTER(f, -1);
GETLOCAL(f,local);
if(!SFKILLED(f) &&
!(local &&
(type == SF_NEW || type == SF_CLOSING ||
type == SF_FINAL || type == SF_ATEXIT)) &&
SFMODE(f,local) != (f->mode&SF_RDWR) && _sfmode(f,0,local) < 0)
SFMTXRETURN(f, -1);
SFLOCK(f,local);
for(disc = f->disc; disc; )
{ next = disc->disc;
if(type == SF_FINAL)
f->disc = next;
if(disc->exceptf)
{ SFOPEN(f,0);
if((rv = (*disc->exceptf)(f,type,data,disc)) != 0 )
SFMTXRETURN(f, rv);
SFLOCK(f,0);
}
if((disc = next) )
{ /* make sure that "next" hasn't been popped */
for(d = f->disc; d; d = d->disc)
if(d == disc)
break;
if(!d)
disc = f->disc;
}
}
SFOPEN(f,local);
SFMTXRETURN(f, 0);
}