xref: /plan9-contrib/sys/src/ape/lib/ap/stdio/freopen.c (revision 3ff48bf5ed603850fcd251ddf13025d23d693782)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * pANS stdio -- freopen
33e12c5d1SDavid du Colombier  */
43e12c5d1SDavid du Colombier #include "iolib.h"
53e12c5d1SDavid du Colombier /*
63e12c5d1SDavid du Colombier  * Open the named file with the given mode, using the given FILE
73e12c5d1SDavid du Colombier  * Legal modes are given below, `additional characters may follow these sequences':
83e12c5d1SDavid du Colombier  * r rb		open to read
93e12c5d1SDavid du Colombier  * w wb		open to write, truncating
103e12c5d1SDavid du Colombier  * a ab		open to write positioned at eof, creating if non-existant
113e12c5d1SDavid du Colombier  * r+ r+b rb+	open to read and write, creating if non-existant
123e12c5d1SDavid du Colombier  * w+ w+b wb+	open to read and write, truncating
133e12c5d1SDavid du Colombier  * a+ a+b ab+	open to read and write, positioned at eof, creating if non-existant.
143e12c5d1SDavid du Colombier  */
15*3ff48bf5SDavid du Colombier FILE *freopen(const char *name, const char *mode, FILE *f){
16*3ff48bf5SDavid du Colombier 	int m;
17*3ff48bf5SDavid du Colombier 
18*3ff48bf5SDavid du Colombier 	if(f->state!=CLOSED){
19*3ff48bf5SDavid du Colombier 		fclose(f);
20*3ff48bf5SDavid du Colombier 		f->state=OPEN;
213e12c5d1SDavid du Colombier 	}
22*3ff48bf5SDavid du Colombier 
23*3ff48bf5SDavid du Colombier 	m = *mode++;
24*3ff48bf5SDavid du Colombier 	if(m == 0)
25*3ff48bf5SDavid du Colombier 		return NULL;
26*3ff48bf5SDavid du Colombier 	if(*mode == 'b')
27*3ff48bf5SDavid du Colombier 		mode++;
28*3ff48bf5SDavid du Colombier 	switch(m){
29*3ff48bf5SDavid du Colombier 	default:
30*3ff48bf5SDavid du Colombier 		return NULL;
313e12c5d1SDavid du Colombier 	case 'r':
32*3ff48bf5SDavid du Colombier 		m = O_RDONLY;
33*3ff48bf5SDavid du Colombier 		if(*mode == '+') m = O_RDWR;
34*3ff48bf5SDavid du Colombier 		f->fd=open(name, m);
353e12c5d1SDavid du Colombier 		break;
363e12c5d1SDavid du Colombier 	case 'w':
37*3ff48bf5SDavid du Colombier 		m = O_WRONLY;
38*3ff48bf5SDavid du Colombier 		if(*mode == '+') m = O_RDWR;
39*3ff48bf5SDavid du Colombier 		f->fd=creat(name, 0666);
403e12c5d1SDavid du Colombier 		break;
413e12c5d1SDavid du Colombier 	case 'a':
42*3ff48bf5SDavid du Colombier 		m = O_WRONLY;
43*3ff48bf5SDavid du Colombier 		if(*mode == '+') m = O_RDWR;
44*3ff48bf5SDavid du Colombier 		f->fd=open(name, m);
45*3ff48bf5SDavid du Colombier 		if(f->fd<0)
46*3ff48bf5SDavid du Colombier 			f->fd=creat(name, 0666);
473e12c5d1SDavid du Colombier 		lseek(f->fd, 0L, 2);
483e12c5d1SDavid du Colombier 		break;
493e12c5d1SDavid du Colombier 	}
50*3ff48bf5SDavid du Colombier 
51*3ff48bf5SDavid du Colombier 	if(f->fd==-1)
52*3ff48bf5SDavid du Colombier 		return NULL;
533e12c5d1SDavid du Colombier 	f->flags=(mode[0]=='a')? APPEND : 0;
543e12c5d1SDavid du Colombier 	f->state=OPEN;
553e12c5d1SDavid du Colombier 	f->buf=0;
563e12c5d1SDavid du Colombier 	f->rp=0;
573e12c5d1SDavid du Colombier 	f->wp=0;
583e12c5d1SDavid du Colombier 	f->lp=0;
593e12c5d1SDavid du Colombier 	return f;
603e12c5d1SDavid du Colombier }
61