xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/disc/sfdctee.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
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 <gsf@research.att.com>                  *
18  *                  David Korn <dgk@research.att.com>                   *
19  *                   Phong Vo <kpv@research.att.com>                    *
20  *                                                                      *
21  ***********************************************************************/
22  #include	"sfdchdr.h"
23  
24  /*	A discipline to tee the output to a stream to another stream.
25  **	This is similar to what the "tee" program does. As implemented
26  **	this discipline only works with file streams.
27  **
28  **	Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
29  */
30  
31  /* the discipline structure for tee-ing */
32  typedef struct _tee_s
33  {	Sfdisc_t	disc;	/* the sfio discipline structure */
34  	Sfio_t*		tee;	/* the stream to tee to */
35  	int		status;	/* if tee stream is still ok */
36  } Tee_t;
37  
38  /*	write to the teed stream.  */
39  #if __STD_C
teewrite(Sfio_t * f,const Void_t * buf,size_t size,Sfdisc_t * disc)40  static ssize_t teewrite(Sfio_t* f, const Void_t* buf, size_t size, Sfdisc_t* disc)
41  #else
42  static ssize_t teewrite(f,buf,size,disc)
43  Sfio_t* 	f;	/* the stream being written to */
44  Void_t*		buf;	/* the buffer of data being output */
45  size_t		size;	/* the data size */
46  Sfdisc_t*	disc;	/* the tee discipline */
47  #endif
48  {
49  	reg Tee_t*	te = (Tee_t*)disc;
50  
51  	/* tee data if still ok */
52  	if(te->status == 0 && sfwrite(te->tee,buf,size) != (ssize_t)size)
53  		te->status = -1;
54  
55  	/* do the actual write */
56  	return sfwr(f,buf,size,disc);
57  }
58  
59  /* on close, remove the discipline */
60  #if __STD_C
teeexcept(Sfio_t * f,int type,Void_t * data,Sfdisc_t * disc)61  static int teeexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
62  #else
63  static int teeexcept(f,type,data,disc)
64  Sfio_t*		f;
65  int		type;
66  Void_t*		data;
67  Sfdisc_t*	disc;
68  #endif
69  {
70  	if(type == SF_FINAL || type == SF_DPOP)
71  		free(disc);
72  
73  	return 0;
74  }
75  
76  #if __STD_C
sfdctee(Sfio_t * f,Sfio_t * tee)77  int sfdctee(Sfio_t* f, Sfio_t* tee)
78  #else
79  int sfdctee(f, tee)
80  Sfio_t*	f;	/* stream to tee from	*/
81  Sfio_t*	tee;	/* stream to tee to	*/
82  #endif
83  {
84  	reg Tee_t*	te;
85  
86  	if(!(te = (Tee_t*)malloc(sizeof(Tee_t))) )
87  		return -1;
88  
89  	te->disc.readf = NIL(Sfread_f);
90  	te->disc.seekf = NIL(Sfseek_f);
91  	te->disc.writef = teewrite;
92  	te->disc.exceptf = teeexcept;
93  	te->tee = tee;
94  	te->status = 0;
95  
96  	if(sfdisc(f,(Sfdisc_t*)te) != (Sfdisc_t*)te)
97  	{	free(te);
98  		return -1;
99  	}
100  
101  	return 0;
102  }
103