00001
00002
00003
00004
00005
00006
00007
00008
00009 static char *rcsid="@(#)$Id$";
00010
00011 #include <ctype.h>
00012 #include <fcntl.h>
00013 #include <signal.h>
00014 #include <sys/types.h>
00015 #if system5
00016 #include <sys/ipc.h>
00017 #include <sys/msg.h>
00018 #endif
00019 #include "eus.h"
00020 #include <sys/msg.h>
00021
00022 extern int errno;
00023 int ch[MAXTHREAD];
00024 int written_count[MAXTHREAD];
00025
00026
00027
00028
00029
00030 pointer openfile(ctx,fname,dir,acsmode,size)
00031 register context *ctx;
00032 char *fname;
00033 int dir,acsmode,size;
00034 { int fd,flag;
00035 pointer s,si,so,fnamep;
00036 extern pointer mkiostream();
00037 fd=open(fname, dir, acsmode);
00038 if (fd<0) return(NULL);
00039 fnamep=makestring(fname,strlen(fname));
00040 vpush(fnamep);
00041 if (dir & O_RDWR) {
00042 si=mkfilestream(ctx,K_IN,makebuffer(size),fd,fnamep);
00043 vpush(si);
00044 so=mkfilestream(ctx,K_OUT,makebuffer(size),fd,fnamep);
00045 s=mkiostream(ctx,vpop(),so);}
00046 else if ((dir & 3)==0) {
00047 s=mkfilestream(ctx,K_IN,makebuffer(size),fd,fnamep);}
00048 else if (dir & O_WRONLY) {
00049 s=mkfilestream(ctx,K_OUT,makebuffer(size),fd,fnamep);}
00050 vpop();
00051 return(s);}
00052
00053 int closestream(s)
00054 pointer s;
00055 { int fd,stat;
00056 if (s->c.stream.direction==K_OUT) flushstream(s);
00057 else if (!isstream(s)) error(E_STREAM);
00058 if (pisfilestream(s) && !isint(s->c.fstream.fname)) {
00059 fd=intval(s->c.fstream.fd);
00060 if (fd>=0) stat=close(fd);
00061 else stat= -1;
00062
00063 pointer_update(s->c.stream.direction,NIL);
00064 return(stat);}
00065 return(0);}
00066
00067
00068
00069
00070
00071 static fillstream(s)
00072 register pointer s;
00073 { register int c;
00074 pointer lsave;
00075 register byte *strbuf;
00076 context *ctx=euscontexts[thr_self()];
00077
00078 strbuf=(s->c.stream.buffer)->c.str.chars;
00079 if (pisfilestream(s)) {
00080 if (isint(s->c.fstream.fname)) {
00081 lsave=s->c.stream.buffer->c.str.length;
00082 tryqread:
00083
00084 #if !news
00085 c=msgrcv(intval(s->c.fstream.fd),
00086 strbuf-4,intval(lsave),0,0);
00087 #endif
00088 #if system5 || Solaris2
00089 if (c<0) { breakck; goto tryqread;}
00090 #endif
00091 #if sun3 || sun4 || vax || apollo || news || sanyo || mips || i386 || alpha || x86_64 || ARM
00092 breakck;
00093 #endif
00094 s->c.stream.buffer->c.str.length=lsave;
00095 if (c==0) return(EOF);
00096 else return(0);}
00097 else {
00098 tryfread:
00099 GC_REGION(c=read(intval(s->c.fstream.fd), strbuf,
00100 intval((s->c.stream.buffer)->c.str.length)););
00101 if (debug) {
00102 printf(";; read; stat=%d errno=%d, intsig=%d\n", c, errno, ctx->intsig);}
00103 breakck;
00104 #if !Cygwin
00105 if (c<0) goto tryfread;
00106 #endif
00107 if (c<=0) return(EOF);
00108 s->c.stream.tail=makeint(c);
00109 return(0);} }
00110 else if (s->cix==streamcp.cix) return(EOF);
00111 else if (csend(euscontexts[thr_self()], s, K_FILL, 0)==NIL) return(EOF);
00112 else return(0);}
00113
00114 int readch(s)
00115 register pointer s;
00116 { register pointer b;
00117 register byte *strbuf;
00118 register int c;
00119
00120 b=s->c.stream.buffer;
00121 if (elmtypeof(b)==ELM_FOREIGN) strbuf=(byte *)(b->c.ivec.iv[0]);
00122 else strbuf=b->c.str.chars;
00123 c=intval(s->c.stream.count);
00124 if (c>=intval(s->c.stream.tail)) {
00125 if (fillstream(s)==EOF){
00126 #if 0
00127 fprintf(stderr, "EOF ");
00128 #endif
00129 return(ch[thr_self()]=EOF);}
00130 c=0;}
00131 ch[thr_self()]=strbuf[c++];
00132 s->c.stream.count=makeint(c);
00133 #if 0
00134 fprintf(stderr, "%x",ch[thr_self()]);
00135 #endif
00136 return(ch[thr_self()]);}
00137
00138 int unreadch(s,ch)
00139 register pointer s;
00140 int ch;
00141 { register pointer b;
00142 register byte *sb;
00143 register int c;
00144 if (ch==EOF) return(ch);
00145 c=intval(s->c.stream.count);
00146 if (c) {
00147 b=s->c.stream.buffer;
00148 if (elmtypeof(b)==ELM_FOREIGN) sb=(byte *)(b->c.ivec.iv[0]);
00149 else sb=b->c.str.chars;
00150 sb[--c]=ch;
00151 s->c.stream.count=makeint(c);}
00152 }
00153
00154
00155
00156
00157
00158
00159 int flushstream(s)
00160 register pointer s;
00161 { register int fno,stat,cnt,blen;
00162 register pointer lsave,bstr,extstr;
00163 context *ctx=euscontexts[thr_self()];
00164
00165
00166 bstr=s->c.stream.buffer;
00167 cnt=intval(s->c.stream.count);
00168 blen=intval(bstr->c.str.length);
00169 if (cnt<=0) return(0);
00170 if (pisfilestream(s)) {
00171 fno=intval(s->c.fstream.fd);
00172 if (isint(s->c.fstream.fname)) {
00173 lsave=bstr->c.str.length;
00174 bstr->c.str.length=(pointer)mypid;
00175 #if !news
00176 stat=msgsnd(fno,bstr->c.str.chars-4,cnt,0);
00177 #endif
00178 breakck;
00179 bstr->c.str.length=lsave;}
00180 else {
00181 tryfwrite:
00182 stat=write(fno,bstr->c.str.chars,cnt);
00183 #if system5
00184 if (stat<0) { breakck; goto tryfwrite;}
00185 #endif
00186 #if sun3 || sun4 || apollo || vax || news || sanyo || mips || alpha
00187 breakck;
00188 #endif
00189 }
00190 if (stat>=0) { s->c.stream.count=makeint(0); return(0);}
00191 else return(-1);}
00192 else if (s->cix==streamcp.cix) {
00193 if (blen==cnt) {
00194 if (blen>=1000000) error(E_LONGSTRING);
00195 extstr=makebuffer(cnt*2);
00196 memcpy(extstr->c.str.chars, bstr->c.str.chars, cnt);
00197
00198 pointer_update(s->c.stream.buffer,extstr);
00199 s->c.stream.tail=makeint(cnt*2-1);}
00200 return(0); }
00201 else if (csend(euscontexts[thr_self()], s,K_FLUSH,0)==NIL) return(-1); else return(0);
00202 }
00203
00204 int writech(s,ch)
00205 register pointer s;
00206 register byte ch;
00207 { register int c,slen;
00208 register byte *strbuf;
00209 c=intval(s->c.stream.count);
00210 strbuf=(s->c.stream.buffer)->c.str.chars;
00211 slen=intval((s->c.stream.buffer)->c.str.length);
00212 if (c>=slen) {
00213 if (flushstream(s)<0) return(-1);
00214 c=intval(s->c.stream.count);
00215 strbuf=(s->c.stream.buffer)->c.str.chars;}
00216 strbuf[c++]=ch; s->c.stream.count=makeint(c); written_count[thr_self()]++; }
00217
00218 int writestr(s,mes,len)
00219 register pointer s;
00220 register byte *mes;
00221 register int len;
00222 { register int bcount,bsize,i=0,count;
00223 register byte *strbuf;
00224
00225 bcount=intval(s->c.stream.count);
00226 strbuf=(s->c.stream.buffer)->c.str.chars;
00227 bsize=intval((s->c.stream.buffer)->c.str.length);
00228 while (len>0) {
00229 if (bcount>=bsize) {
00230 if (flushstream(s)<0) return(-1);
00231 bsize=intval((s->c.stream.buffer)->c.str.length);
00232 bcount=intval(s->c.stream.count);
00233 strbuf=(s->c.stream.buffer)->c.str.chars;}
00234 count=min(len,bsize-bcount);
00235 memcpy(&strbuf[bcount], &mes[i], count);
00236
00237 i+=count; len-=count; bcount+=count;
00238 s->c.stream.count=makeint(bcount);}
00239 written_count[thr_self()]+=i;
00240 }
00241