Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/sfio/sfexcept.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#include "sfhdr.h"
23
24
/* Function to handle io exceptions.
25
** Written by Kiem-Phong Vo
26
*/
27
28
#if __STD_C
29
int _sfexcept(Sfio_t* f, int type, ssize_t io, Sfdisc_t* disc)
30
#else
31
int _sfexcept(f,type,io,disc)
32
Sfio_t* f; /* stream where the exception happened */
33
int type; /* io type that was performed */
34
ssize_t io; /* the io return value that indicated exception */
35
Sfdisc_t* disc; /* discipline in use */
36
#endif
37
{
38
reg int ev, local, lock;
39
reg ssize_t size;
40
reg uchar* data;
41
SFMTXDECL(f); /* declare a local stream variable for multithreading */
42
43
SFMTXENTER(f,-1);
44
45
GETLOCAL(f,local);
46
lock = f->mode&SF_LOCK;
47
48
if(local && io <= 0)
49
f->flags |= io < 0 ? SF_ERROR : SF_EOF;
50
51
if(disc && disc->exceptf)
52
{ /* let the stream be generally accessible for this duration */
53
if(local && lock)
54
SFOPEN(f,0);
55
56
/* so that exception handler knows what we are asking for */
57
_Sfi = f->val = io;
58
ev = (*(disc->exceptf))(f,type,&io,disc);
59
60
/* relock if necessary */
61
if(local && lock)
62
SFLOCK(f,0);
63
64
if(io > 0 && !(f->flags&SF_STRING) )
65
SFMTXRETURN(f, ev);
66
if(ev < 0)
67
SFMTXRETURN(f, SF_EDONE);
68
if(ev > 0)
69
SFMTXRETURN(f, SF_EDISC);
70
}
71
72
if(f->flags&SF_STRING)
73
{ if(type == SF_READ)
74
goto chk_stack;
75
else if(type != SF_WRITE && type != SF_SEEK)
76
SFMTXRETURN(f, SF_EDONE);
77
if(local && io >= 0)
78
{ if(f->size >= 0 && !(f->flags&SF_MALLOC))
79
goto chk_stack;
80
/* extend buffer */
81
if((size = f->size) < 0)
82
size = 0;
83
if((io -= size) <= 0)
84
io = SF_GRAIN;
85
size = ((size+io+SF_GRAIN-1)/SF_GRAIN)*SF_GRAIN;
86
if(f->size > 0)
87
data = (uchar*)realloc((char*)f->data,size);
88
else data = (uchar*)malloc(size);
89
if(!data)
90
goto chk_stack;
91
f->endb = data + size;
92
f->next = data + (f->next - f->data);
93
f->endr = f->endw = f->data = data;
94
f->size = size;
95
}
96
SFMTXRETURN(f, SF_EDISC);
97
}
98
99
if(errno == EINTR)
100
{ if(_Sfexiting || (f->bits&SF_ENDING) || /* stop being a hero */
101
(f->flags&SF_IOINTR) ) /* application requests to return */
102
SFMTXRETURN(f, SF_EDONE);
103
104
/* a normal interrupt, we can continue */
105
errno = 0;
106
f->flags &= ~(SF_EOF|SF_ERROR);
107
SFMTXRETURN(f, SF_ECONT);
108
}
109
110
chk_stack:
111
if(local && f->push &&
112
((type == SF_READ && f->next >= f->endb) ||
113
(type == SF_WRITE && f->next <= f->data)))
114
{ /* pop the stack */
115
reg Sfio_t *pf;
116
117
if(lock)
118
SFOPEN(f,0);
119
120
/* pop and close */
121
pf = (*_Sfstack)(f,NIL(Sfio_t*));
122
if((ev = sfclose(pf)) < 0) /* can't close, restack */
123
(*_Sfstack)(f,pf);
124
125
if(lock)
126
SFLOCK(f,0);
127
128
ev = ev < 0 ? SF_EDONE : SF_ESTACK;
129
}
130
else ev = SF_EDONE;
131
132
SFMTXRETURN(f, ev);
133
}
134
135