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

« back to all changes in this revision

Viewing changes to tools/sfio/Sfio_dc/sfdcfilter.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        "sfdchdr.h"
 
2
 
 
3
/*      Discipline to invoke UNIX processes as data filters.
 
4
**      These processes must be able to fit in pipelines.
 
5
**
 
6
**      Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
 
7
*/
 
8
 
 
9
#if !defined(FNDELAY) && defined(O_NDELAY)
 
10
#define FNDELAY O_NDELAY
 
11
#endif
 
12
 
 
13
typedef struct _filter_s
 
14
{       Sfdisc_t        disc;           /* discipline structure */
 
15
        Sfio_t*         filter;         /* the filter stream */
 
16
        char            raw[1024];      /* raw data buffer */
 
17
        char*           next;           /* remainder of data unwritten to pipe */
 
18
        char*           endb;           /* end of data */
 
19
} Filter_t;
 
20
 
 
21
/* read data from the filter */
 
22
#if __STD_C
 
23
static ssize_t filterread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
 
24
#else
 
25
static ssize_t filterread(f, buf, n, disc)
 
26
Sfio_t*         f;      /* stream reading from */
 
27
Void_t*         buf;    /* buffer to read into */
 
28
size_t          n;      /* number of bytes requested */
 
29
Sfdisc_t*       disc;   /* discipline */
 
30
#endif
 
31
{
 
32
        Filter_t*       fi;
 
33
        ssize_t         r, w;
 
34
 
 
35
        fi = (Filter_t*)disc;
 
36
        for(;;)
 
37
        {       if(!fi->next)
 
38
                        fi->next = fi->endb = fi->raw;
 
39
                else
 
40
                {       /* try to get data from filter, if any */
 
41
                        errno = 0;
 
42
                        if((r = sfread(fi->filter,buf,n)) > 0)
 
43
                                return r;
 
44
                        if(errno != EWOULDBLOCK)
 
45
                                return 0;
 
46
                }
 
47
 
 
48
                /* get some raw data to stuff down the pipe */
 
49
                if(fi->next >= fi->endb)
 
50
                {       if((r = sfrd(f,fi->raw,sizeof(fi->raw),disc)) > 0)
 
51
                        {       fi->next = fi->raw;
 
52
                                fi->endb = fi->raw+r;
 
53
                        }
 
54
                        else
 
55
                        {       /* eof, close write end of pipes */
 
56
                                sfset(fi->filter,SF_READ,0);
 
57
                                close(sffileno(fi->filter));
 
58
                                sfset(fi->filter,SF_READ,1);
 
59
                        }
 
60
                }
 
61
 
 
62
                if((w = fi->endb - fi->next) > 0)
 
63
                {       errno = 0;
 
64
                        if((w = sfwrite(fi->filter,fi->next,w)) > 0)
 
65
                                fi->next += w;
 
66
                        else if(errno != EWOULDBLOCK)
 
67
                                return 0;
 
68
                        /* pipe is full, sleep for a while, then continue */
 
69
                        else    sleep(1);
 
70
                }
 
71
        }
 
72
}
 
73
 
 
74
#if __STD_C
 
75
static ssize_t filterwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
 
76
#else
 
77
static ssize_t filterwrite(f, buf, n, disc)
 
78
Sfio_t*         f;      /* stream reading from */
 
79
Void_t*         buf;    /* buffer to read into */
 
80
size_t          n;      /* number of bytes requested */
 
81
Sfdisc_t*       disc;   /* discipline */
 
82
#endif
 
83
{
 
84
        return -1;
 
85
}
 
86
 
 
87
/* for the duration of this discipline, the stream is unseekable */
 
88
#if __STD_C
 
89
static Sfoff_t filterseek(Sfio_t* f, Sfoff_t addr, int offset, Sfdisc_t* disc)
 
90
#else
 
91
static Sfoff_t filterseek(f, addr, offset, disc)
 
92
Sfio_t*         f;
 
93
Sfoff_t         addr;
 
94
int             offset;
 
95
Sfdisc_t*       disc;
 
96
#endif
 
97
{       f = NIL(Sfio_t*);
 
98
        addr = 0;
 
99
        offset = 0;
 
100
        disc = NIL(Sfdisc_t*);
 
101
        return (Sfoff_t)(-1);
 
102
}
 
103
 
 
104
/* on close, remove the discipline */
 
105
#if __STD_C
 
106
static filterexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
 
107
#else
 
108
static filterexcept(f,type,data,disc)
 
109
Sfio_t*         f;
 
110
int             type;
 
111
Void_t*         data;
 
112
Sfdisc_t*       disc;
 
113
#endif
 
114
{
 
115
        if(type == SF_FINAL || type == SF_DPOP)
 
116
        {       sfclose(((Filter_t*)disc)->filter);
 
117
                free(disc);
 
118
        }
 
119
 
 
120
        return 0;
 
121
}
 
122
 
 
123
#if __STD_C
 
124
int sfdcfilter(Sfio_t* f, const char* cmd)
 
125
#else
 
126
int sfdcfilter(f, cmd)
 
127
Sfio_t* f;      /* stream to filter data        */
 
128
char*   cmd;    /* program to run as a filter   */
 
129
#endif
 
130
{
 
131
        reg Filter_t*   fi;
 
132
        reg Sfio_t*     filter;
 
133
 
 
134
        /* open filter for read&write */
 
135
        if(!(filter = sfpopen(NIL(Sfio_t*),cmd,"r+")) )
 
136
                return -1;
 
137
 
 
138
        /* unbuffered so that write data will get to the pipe right away */
 
139
        sfsetbuf(filter,NIL(Void_t*),0);
 
140
 
 
141
        /* make the write descriptor nonblocking */
 
142
        sfset(filter,SF_READ,0);
 
143
        fcntl(sffileno(filter),F_SETFL,FNDELAY);
 
144
        sfset(filter,SF_READ,1);
 
145
 
 
146
        /* same for the read descriptor */
 
147
        sfset(filter,SF_WRITE,0);
 
148
        fcntl(sffileno(filter),F_SETFL,FNDELAY);
 
149
        sfset(filter,SF_WRITE,1);
 
150
 
 
151
        if(!(fi = (Filter_t*)malloc(sizeof(Filter_t))) )
 
152
        {       sfclose(filter);
 
153
                return -1;
 
154
        }
 
155
 
 
156
        fi->disc.readf = filterread;
 
157
        fi->disc.writef = filterwrite;
 
158
        fi->disc.seekf = filterseek;
 
159
        fi->disc.exceptf = filterexcept;
 
160
        fi->filter = filter;
 
161
        fi->next = fi->endb = NIL(char*);
 
162
 
 
163
        if(sfdisc(f,(Sfdisc_t*)fi) != (Sfdisc_t*)fi)
 
164
        {       sfclose(filter);
 
165
                free(fi);
 
166
                return -1;
 
167
        }
 
168
 
 
169
        return 0;
 
170
}