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

« back to all changes in this revision

Viewing changes to tools/sfio/sfread.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
/*      Read n bytes from a stream into a buffer
 
4
**
 
5
**      Written by Kiem-Phong Vo.
 
6
*/
 
7
 
 
8
#if __STD_C
 
9
ssize_t sfread(reg Sfio_t* f, Void_t* buf, reg size_t n)
 
10
#else
 
11
ssize_t sfread(f,buf,n)
 
12
reg Sfio_t*     f;      /* read from this stream.       */
 
13
Void_t*         buf;    /* buffer to read into          */
 
14
reg size_t      n;      /* number of bytes to be read.  */
 
15
#endif
 
16
{
 
17
        reg uchar       *s, *begs;
 
18
        reg ssize_t     r;
 
19
        reg int         local, justseek;
 
20
 
 
21
        SFMTXSTART(f, (ssize_t)(-1));
 
22
 
 
23
        GETLOCAL(f,local);
 
24
        justseek = f->bits&SF_JUSTSEEK; f->bits &= ~SF_JUSTSEEK;
 
25
 
 
26
        if(!buf)
 
27
                SFMTXRETURN(f, (ssize_t)(-1) );
 
28
 
 
29
        /* release peek lock */
 
30
        if(f->mode&SF_PEEK)
 
31
        {       if(!(f->mode&SF_READ) )
 
32
                        SFMTXRETURN(f, (ssize_t)(-1));
 
33
 
 
34
                if(f->mode&SF_GETR)
 
35
                {       if(((uchar*)buf + f->val) != f->next &&
 
36
                           (!f->rsrv || f->rsrv->data != (uchar*)buf) )
 
37
                                SFMTXRETURN(f, (ssize_t)(-1));
 
38
                        f->mode &= ~SF_PEEK;
 
39
                        SFMTXRETURN(f, 0);
 
40
                }
 
41
                else
 
42
                {       if((uchar*)buf != f->next)
 
43
                                SFMTXRETURN(f, (ssize_t)(-1));
 
44
                        f->mode &= ~SF_PEEK;
 
45
                        if(f->mode&SF_PKRD)
 
46
                        {       /* actually read the data now */
 
47
                                f->mode &= ~SF_PKRD;
 
48
                                if(n > 0)
 
49
                                        n = (r = read(f->file,f->data,n)) < 0 ? 0 : r;
 
50
                                f->endb = f->data+n;
 
51
                                f->here += n;
 
52
                        }
 
53
                        f->next += n;
 
54
                        f->endr = f->endb;
 
55
                        SFMTXRETURN(f, n);
 
56
                }
 
57
        }
 
58
 
 
59
        s = begs = (uchar*)buf;
 
60
        for(;; f->mode &= ~SF_LOCK)
 
61
        {       /* check stream mode */
 
62
                if(SFMODE(f,local) != SF_READ && _sfmode(f,SF_READ,local) < 0)
 
63
                {       n = s > begs ? s-begs : (size_t)(-1);
 
64
                        SFMTXRETURN(f, (ssize_t)n);
 
65
                }
 
66
 
 
67
                SFLOCK(f,local);
 
68
 
 
69
                if((r = f->endb - f->next) > 0) /* has buffered data */
 
70
                {       if(r > (ssize_t)n)
 
71
                                r = (ssize_t)n;
 
72
                        if(s != f->next)
 
73
                                memcpy(s, f->next, r);
 
74
                        f->next += r;
 
75
                        s += r;
 
76
                        n -= r;
 
77
                }
 
78
 
 
79
                if(n <= 0)      /* all done */
 
80
                        break;
 
81
 
 
82
                if(!(f->flags&SF_STRING) && !(f->bits&SF_MMAP) )
 
83
                {       f->next = f->endb = f->data;
 
84
 
 
85
                        /* exact IO is desirable for these cases */
 
86
                        if(SFDIRECT(f,n) ||
 
87
                           ((f->flags&SF_SHARE) && f->extent < 0) )
 
88
                                r = (ssize_t)n;
 
89
                        else if(justseek && n <= f->iosz && f->iosz <= f->size)
 
90
                                r = f->iosz;    /* limit buffering */
 
91
                        else    r = f->size;    /* full buffering */
 
92
 
 
93
                        /* if read almost full size, then just do it direct */
 
94
                        if(r > (ssize_t)n && (r - r/8) <= (ssize_t)n)
 
95
                                r = (ssize_t)n;
 
96
 
 
97
                        /* read directly to user's buffer */
 
98
                        if(r == (ssize_t)n && (r = SFRD(f,s,r,f->disc)) >= 0)
 
99
                        {       s += r;
 
100
                                n -= r;
 
101
                                if(r == 0 || n == 0) /* eof or eob */ 
 
102
                                        break;
 
103
                        }
 
104
                        else    goto do_filbuf;
 
105
                }
 
106
                else
 
107
                { do_filbuf:
 
108
                        if(justseek)
 
109
                                f->bits |= SF_JUSTSEEK;
 
110
                        if(SFFILBUF(f,-1) <= 0)
 
111
                                break;
 
112
                }
 
113
        }
 
114
 
 
115
        SFOPEN(f,local);
 
116
        r = s-begs;
 
117
        SFMTXRETURN(f, r);
 
118
}