mirror of https://github.com/diegocr/libnix.git
75 lines
1.7 KiB
C
75 lines
1.7 KiB
C
#include <dos/dos.h>
|
|
#include <proto/dos.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
|
|
extern void __seterrno(void);
|
|
|
|
FILE *freopen(const char *filename,const char *mode,FILE *stream)
|
|
{ int error=__fflush(stream);
|
|
|
|
if(!__valid_fp(stream))
|
|
{ errno=EINVAL;
|
|
return NULL;
|
|
}
|
|
|
|
if(stream->file>STDERR_FILENO)
|
|
{ close(stream->file);
|
|
if(stream->name!=NULL) /* file is temporary */
|
|
{ BPTR cd=CurrentDir(stream->tmpdir); /* cd t: */
|
|
if(!DeleteFile(stream->name)) /* delete file */
|
|
{ __seterrno();
|
|
error=1; }
|
|
free(stream->name); /* free filename */
|
|
stream->name=NULL;
|
|
UnLock(CurrentDir(cd)); /* cd back, unlock t: */
|
|
}
|
|
stream->file=0;
|
|
}
|
|
|
|
if(error)
|
|
return NULL;
|
|
|
|
if(filename!=NULL)
|
|
{ long file,flags=O_RDONLY;
|
|
char ch;
|
|
if(mode==NULL)
|
|
return NULL;
|
|
if(ch=*mode++,ch!='r')
|
|
if(flags=O_WRONLY|O_CREAT|O_TRUNC,ch!='w')
|
|
if(flags=O_WRONLY|O_CREAT|O_APPEND,ch!='a')
|
|
return NULL;
|
|
if((ch=*mode++))
|
|
{ if(ch=='+')
|
|
{ if((ch=*mode++) && (ch!='b'||*mode))
|
|
return NULL;
|
|
flags=(flags&~O_ACCMODE)|O_RDWR; }
|
|
else if(ch!='b')
|
|
return NULL;
|
|
else if((ch=*mode++))
|
|
{ if(ch!='+'||*mode)
|
|
return NULL;
|
|
flags=(flags&~O_ACCMODE)|O_RDWR; }
|
|
}
|
|
|
|
if((file=open(filename,flags,0777))<0)
|
|
return NULL;
|
|
|
|
if(flags&O_APPEND)
|
|
(void)lseek(file,0,SEEK_END);
|
|
|
|
/* clear a lot of flags */
|
|
stream->flags&=~(__SWO|__SERR|__SEOF|__SWR|__SRD|__SNBF|__SLBF);
|
|
if(flags&O_WRONLY)
|
|
stream->flags|=__SWO; /* set write-only flag */
|
|
if(isatty(file))
|
|
stream->flags|=__SLBF; /* set linebuffered flag */
|
|
stream->file=file;
|
|
}
|
|
|
|
return stream;
|
|
}
|