ref: d81447526cde6fa98dfa792a65f71acb78ef1398
dir: /streams.c/
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"
typedef struct Stream Stream;
struct Stream
{
ulong fd;
int type;
int mode;
int nalias;
Rune **aliases;
Stream *next;
};
enum {
TextStream,
BinaryStream,
};
enum {
ReadStream,
WriteStream,
AppendStream
};
static Stream *streams;
static Stream *currentinput;
static Stream *currentoutput;
Stream *openstreamfd(int, int, int);
Stream *getstreambyfd(int);
Stream *getstreambyalias(Rune *);
Stream *getstream(Term *);
void
initstreams(void)
{
currentinput = openstreamfd(0, TextStream, ReadStream);
currentoutput = openstreamfd(1, TextStream, WriteStream);
}
int
openstream(Rune *sourcesink, Rune *mode, Term *options, Term **stream)
{
USED(options);
int omode;
int smode;
if(runestrcmp(mode, L"read") == 0){
omode = OREAD;
smode = ReadStream;
}else if(runestrcmp(mode, L"write") == 0){
omode = OWRITE;
smode = WriteStream;
}else if(runestrcmp(mode, L"append") == 0){
omode = OWRITE; /* Is this correct? */
smode = AppendStream;
}else{
*stream = existenceerror(L"source_sink", mkatom(sourcesink));
return 1;
}
char *filename = smprint("%S", sourcesink);
int fd = open(filename, omode);
if(fd < 0){
*stream = permissionerror(L"open", L"source_sink", mkatom(sourcesink));
return 1;
}
Stream *s = openstreamfd(fd, TextStream, smode);
*stream = mknumber(NumberInt, s->fd, 0);
return 0;
}
void
closestream(Term *t)
{
Stream *s = getstream(t);
if(s == nil)
return;
Stream *tmp;
Stream *prev = nil;
for(tmp = streams; tmp != nil; tmp = tmp->next){
if(tmp == s){
if(prev == nil)
streams = tmp->next;
else
prev->next = tmp->next;
break;
}
if(prev == nil)
prev = tmp;
}
}
Term *
currentinputstream(void)
{
return mknumber(NumberInt, currentinput->fd, 0);
}
Term *
currentoutputstream(void)
{
return mknumber(NumberInt, currentoutput->fd, 0);
}
void
setcurrentinputstream(Term *t)
{
Stream *s = getstream(t);
if(s)
currentinput = s;
}
void
setcurrentoutputstream(Term *t)
{
Stream *s = getstream(t);
if(s)
currentoutput = s;
}
int
isopenstream(Term *t)
{
Stream *s = getstream(t);
if(s)
return 1;
else
return 0;
}
int
isinputstream(Term *t)
{
Stream *s = getstream(t);
if(s && s->mode == ReadStream)
return 1;
else
return 0;
}
int
isoutputstream(Term *t)
{
Stream *s = getstream(t);
if(s && (s->mode == WriteStream || s->mode == AppendStream))
return 1;
else
return 0;
}
Stream *
openstreamfd(int fd, int type, int mode)
{
Stream *s = malloc(sizeof(Stream));
s->fd = fd;
s->type = type;
s->mode = mode;
s->nalias = 0;
s->aliases = nil;
s->next = streams;
streams = s;
return s;
}
Stream *
getstreambyfd(int fd)
{
Stream *s;
for(s = streams; s != nil; s = s->next)
if(s->fd == fd)
return s;
return nil;
}
Stream *
getstreambyalias(Rune *alias)
{
Stream *s;
for(s = streams; s != nil; s = s->next){
int i;
for(i = 0; i < s->nalias; i++){
if(runestrcmp(alias, s->aliases[i]) == 0)
return s;
}
}
return nil;
}
Stream *
getstream(Term *t)
{
Stream *s = nil;
if(t->tag == NumberTerm && t->numbertype == NumberInt)
s = getstreambyfd(t->ival);
else if(t->tag == AtomTerm)
s = getstreambyalias(t->text);
return s;
}