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

« back to all changes in this revision

Viewing changes to tools/sfio/sfreserve.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
/*      Reserve a segment of data or buffer.
 
4
**
 
5
**      Written by Kiem-Phong Vo.
 
6
*/
 
7
 
 
8
#if __STD_C
 
9
Void_t* sfreserve(reg Sfio_t* f, ssize_t size, int type)
 
10
#else
 
11
Void_t* sfreserve(f,size,type)
 
12
reg Sfio_t*     f;      /* file to peek */
 
13
ssize_t         size;   /* size of peek */
 
14
int             type;   /* LOCKR: lock stream, LASTR: last record */
 
15
#endif
 
16
{
 
17
        reg ssize_t     n, sz;
 
18
        reg Sfrsrv_t*   rsrv;
 
19
        reg Void_t*     data;
 
20
        reg int         mode;
 
21
 
 
22
        SFMTXSTART(f,NIL(Void_t*));
 
23
 
 
24
        /* initialize io states */
 
25
        rsrv = NIL(Sfrsrv_t*);
 
26
        _Sfi = f->val = -1;
 
27
 
 
28
        /* return the last record */
 
29
        if(type == SF_LASTR )
 
30
        {       if((rsrv = f->rsrv) && (n = -rsrv->slen) > 0)
 
31
                {       rsrv->slen = 0;
 
32
                        _Sfi = f->val = n;
 
33
                        SFMTXRETURN(f, (Void_t*)rsrv->data);
 
34
                }
 
35
                else    SFMTXRETURN(f, NIL(Void_t*));
 
36
        }
 
37
 
 
38
        if(type > 0 && !(type == SF_LOCKR || type == 1) )
 
39
                SFMTXRETURN(f, NIL(Void_t*));
 
40
 
 
41
        if((sz = size) == 0 && type != 0)
 
42
        {       /* only return the current status and possibly lock stream */
 
43
                if((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0)
 
44
                        SFMTXRETURN(f, NIL(Void_t*));
 
45
 
 
46
                SFLOCK(f,0);
 
47
                if((n = f->endb - f->next) < 0)
 
48
                        n = 0;
 
49
 
 
50
                if(!f->data && type > 0)
 
51
                        rsrv = _sfrsrv(f,0);
 
52
 
 
53
                goto done;
 
54
        }
 
55
        if(sz < 0)
 
56
                sz = -sz;
 
57
 
 
58
        /* iterate until get to a stream that has data or buffer space */
 
59
        for(;;)
 
60
        {       /* prefer read mode so that data is always valid */
 
61
                if(!(mode = (f->flags&SF_READ)) )
 
62
                        mode = SF_WRITE;
 
63
                if((int)f->mode != mode && _sfmode(f,mode,0) < 0)
 
64
                {       n = -1;
 
65
                        goto done;
 
66
                }
 
67
 
 
68
                SFLOCK(f,0);
 
69
 
 
70
                if((n = f->endb - f->next) < 0) /* possible for string+rw */
 
71
                        n = 0;
 
72
 
 
73
                if(n > 0 && n >= sz)    /* all done */
 
74
                        break;
 
75
 
 
76
                /* do a buffer refill or flush */
 
77
                if(f->mode&SF_WRITE)
 
78
                        (void)SFFLSBUF(f, -1);
 
79
                else if(type > 0 && f->extent < 0 && (f->flags&SF_SHARE) )
 
80
                {       if(n == 0) /* peek-read only if there is no buffered data */
 
81
                        {       f->mode |= SF_RV;
 
82
                                (void)SFFILBUF(f, sz == 0 ? -1 : (sz-n) );
 
83
                        }
 
84
                        if((n = f->endb - f->next) < sz)
 
85
                        {       if(f->mode&SF_PKRD)
 
86
                                {       f->endb = f->endr = f->next;
 
87
                                        f->mode &= ~SF_PKRD;
 
88
                                }
 
89
                                goto done;
 
90
                        }
 
91
                }
 
92
                else    (void)SFFILBUF(f, sz == 0 ? -1 : (sz-n) );
 
93
 
 
94
                /* now have data */
 
95
                if((n = f->endb - f->next) > 0)
 
96
                        break;
 
97
                else if(n < 0)
 
98
                        n = 0;
 
99
 
 
100
                /* this test fails only if unstacked to an opposite stream */
 
101
                if((f->mode&mode) != 0)
 
102
                        break;
 
103
        }
 
104
 
 
105
        if(n > 0 && n < sz && (f->mode&mode) != 0 )
 
106
        {       /* try to accomodate request size */    
 
107
                if(f->flags&SF_STRING)
 
108
                {       if((f->mode&SF_WRITE) && (f->flags&SF_MALLOC) )
 
109
                        {       (void)SFWR(f,f->next,sz,f->disc);
 
110
                                n = f->endb - f->next;
 
111
                        }
 
112
                }
 
113
                else if(f->mode&SF_WRITE)
 
114
                {       if(type > 0 && (rsrv = _sfrsrv(f,sz)) )
 
115
                                n = sz;
 
116
                }
 
117
                else /*if(f->mode&SF_READ)*/
 
118
                {       if(type <= 0 && (rsrv = _sfrsrv(f,sz)) &&
 
119
                           (n = SFREAD(f,(Void_t*)rsrv->data,sz)) < sz)
 
120
                                rsrv->slen = -n;
 
121
                }
 
122
        }
 
123
 
 
124
done:
 
125
        /* return true buffer size */
 
126
        _Sfi = f->val = n;
 
127
 
 
128
        SFOPEN(f,0);
 
129
 
 
130
        if((sz > 0 && n < sz) || (n == 0 && type <= 0) )
 
131
                SFMTXRETURN(f, NIL(Void_t*));
 
132
 
 
133
        if((data = rsrv ? (Void_t*)rsrv->data : (Void_t*)f->next) )
 
134
        {       if(type > 0)
 
135
                {       f->mode |= SF_PEEK;
 
136
                        f->endr = f->endw = f->data;
 
137
                }
 
138
                else if(data == (Void_t*)f->next)
 
139
                        f->next += (size >= 0 ? size : n);
 
140
        }
 
141
 
 
142
        SFMTXRETURN(f, data);
 
143
}