~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/sfio/sfexcept.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "sfhdr.h"
 
2
 
 
3
/*      Function to handle io exceptions.
 
4
**      Written by Kiem-Phong Vo
 
5
*/
 
6
 
 
7
#if __STD_C
 
8
int _sfexcept(Sfio_t* f, int type, ssize_t io, Sfdisc_t* disc)
 
9
#else
 
10
int _sfexcept(f,type,io,disc)
 
11
Sfio_t*         f;      /* stream where the exception happened */
 
12
int             type;   /* io type that was performed */
 
13
ssize_t         io;     /* the io return value that indicated exception */
 
14
Sfdisc_t*       disc;   /* discipline in use */
 
15
#endif
 
16
{
 
17
        reg int         ev, local, lock;
 
18
        reg ssize_t     size;
 
19
        reg uchar*      data;
 
20
 
 
21
        SFMTXSTART(f,-1);
 
22
 
 
23
        GETLOCAL(f,local);
 
24
        lock = f->mode&SF_LOCK;
 
25
 
 
26
        if(local && io <= 0)
 
27
                f->flags |= io < 0 ? SF_ERROR : SF_EOF;
 
28
 
 
29
        if(disc && disc->exceptf)
 
30
        {       /* let the stream be generally accessible for this duration */
 
31
                if(local && lock)
 
32
                        SFOPEN(f,0);
 
33
 
 
34
                /* so that exception handler knows what we are asking for */
 
35
                _Sfi = f->val = io;
 
36
                ev = (*(disc->exceptf))(f,type,&io,disc);
 
37
 
 
38
                /* relock if necessary */
 
39
                if(local && lock)
 
40
                        SFLOCK(f,0);
 
41
 
 
42
                if(io > 0 && !(f->flags&SF_STRING) )
 
43
                        SFMTXRETURN(f, ev);
 
44
                if(ev < 0)
 
45
                        SFMTXRETURN(f, SF_EDONE);
 
46
                if(ev > 0)
 
47
                        SFMTXRETURN(f, SF_EDISC);
 
48
        }
 
49
 
 
50
        if(f->flags&SF_STRING)
 
51
        {       if(type == SF_READ)
 
52
                        goto chk_stack;
 
53
                else if(type != SF_WRITE && type != SF_SEEK)
 
54
                        SFMTXRETURN(f, SF_EDONE);
 
55
                if(local && io >= 0)
 
56
                {       if(f->size >= 0 && !(f->flags&SF_MALLOC))
 
57
                                goto chk_stack;
 
58
                        /* extend buffer */
 
59
                        if((size = f->size) < 0)
 
60
                                size = 0;
 
61
                        if((io -= size) <= 0)
 
62
                                io = SF_GRAIN;
 
63
                        size = ((size+io+SF_GRAIN-1)/SF_GRAIN)*SF_GRAIN;
 
64
                        if(f->size > 0)
 
65
                                data = (uchar*)realloc((char*)f->data,size);
 
66
                        else    data = (uchar*)malloc(size);
 
67
                        if(!data)
 
68
                                goto chk_stack;
 
69
                        f->endb = data + size;
 
70
                        f->next = data + (f->next - f->data);
 
71
                        f->endr = f->endw = f->data = data;
 
72
                        f->size = size;
 
73
                }
 
74
                SFMTXRETURN(f, SF_EDISC);
 
75
        }
 
76
 
 
77
        if(errno == EINTR)
 
78
        {       if(_Sfexiting || (f->bits&SF_ENDING))   /* stop being a hero */
 
79
                        SFMTXRETURN(f, SF_EDONE);
 
80
 
 
81
                /* a normal interrupt, we can continue */
 
82
                errno = 0;
 
83
                f->flags &= ~(SF_EOF|SF_ERROR);
 
84
                SFMTXRETURN(f, SF_ECONT);
 
85
        }
 
86
 
 
87
chk_stack:
 
88
        if(local && f->push &&
 
89
           ((type == SF_READ  && f->next >= f->endb) ||
 
90
            (type == SF_WRITE && f->next <= f->data)))
 
91
        {       /* pop the stack */
 
92
                reg Sfio_t      *pf;
 
93
 
 
94
                if(lock)
 
95
                        SFOPEN(f,0);
 
96
 
 
97
                /* pop and close */
 
98
                pf = (*_Sfstack)(f,NIL(Sfio_t*));
 
99
                if((ev = sfclose(pf)) < 0) /* can't close, restack */
 
100
                        (*_Sfstack)(f,pf);
 
101
 
 
102
                if(lock)
 
103
                        SFLOCK(f,0);
 
104
 
 
105
                ev = ev < 0 ? SF_EDONE : SF_ESTACK;
 
106
        }
 
107
        else    ev = SF_EDONE;
 
108
 
 
109
        SFMTXRETURN(f, ev);
 
110
}