eusstream.c
Go to the documentation of this file.
00001 /****************************************************************/
00002 /* eusstream.c
00003 /* euLisp stream i/o routines
00004 /*      (c)T.Matsui
00005 /*      1986-Mar
00006 /*      1987-Mar        extension of string output stream
00007 /*      1987-May        filestream, socketstream,...
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];              /*current character*/
00024 int written_count[MAXTHREAD];
00025 
00026 /****************************************************************/
00027 /* open and close stream primitives
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();       /*fnamep*/
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)) { /*message queu?*/
00059     fd=intval(s->c.fstream.fd);
00060     if (fd>=0) stat=close(fd);
00061     else stat= -1;
00062 /*    if (debug) fprintf(stderr,"closestream fd=%d stat=%d\n",fd,(stat?errno:0)); */
00063     pointer_update(s->c.stream.direction,NIL);
00064     return(stat);}
00065   return(0);}
00066 
00067 /****************************************************************/
00068 /* read primitive
00069 /****************************************************************/
00070 
00071 static int 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)) {    /*message queue*/
00081       lsave=s->c.stream.buffer->c.str.length;
00082       tryqread:
00083 /* news doesnot have message queu, what a bsd machine!*/
00084 #if !news
00085       c=msgrcv(intval(s->c.fstream.fd),         /*qid*/
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 /* if (c<0) goto tryfread; */
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);  /*string streams cannot fill*/
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 /*  if (s->c.stream.direction!=K_IN) return(ch=EOF); */
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 /* output primitives
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 //   fno=intval(s->c.fstream.fd);       // only when isfilestream(s). moved to inside of if(pisfilestream(s))
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);        /*no buffer: cannot write*/
00170   if (pisfilestream(s)) {
00171     fno=intval(s->c.fstream.fd); // moved by ikuo
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) {    /*extend string output stream*/
00194       if (blen>=1000000) error(E_LONGSTRING);
00195       extstr=makebuffer(cnt*2);
00196       memcpy(extstr->c.str.chars, bstr->c.str.chars, cnt);
00197       /* substituted bcopy(bstr->c.str.chars,extstr->c.str.chars,cnt);*/
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)    /* write string */
00219 register pointer s;     /*stream*/
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     /* substituted bcopy(&mes[i],&strbuf[bcount],count); */
00237     i+=count; len-=count; bcount+=count;
00238     s->c.stream.count=makeint(bcount);}
00239   written_count[thr_self()]+=i;
00240   }
00241 


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Jun 6 2019 18:05:53