source: git/Singular/ssiLink.cc @ 8ed989

spielwiese
Last change on this file since 8ed989 was 8ed989, checked in by Hans Schoenemann <hannes@…>, 14 years ago
ssiLink git-svn-id: file:///usr/local/Singular/svn/trunk@13073 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 20.0 KB
RevLine 
[8ed989]1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    ssiLink.h
6 *  Purpose: declaration of sl_link routines for ssi
7 *  Version: $Id$
8 ***************************************************************/
9#  include <stdio.h>
10#  include <fcntl.h>
11#  include <errno.h>
12#  include <unistd.h>
13#include <sys/types.h>
14#include <signal.h>
15#include <sys/select.h>
16
17
18#include "mod2.h"
19
20#include "tok.h"
21#include "ipid.h"
22#include <omalloc.h>
23#include <kernel/ring.h>
24#include <kernel/matpol.h>
25#include <kernel/ideals.h>
26#include <kernel/polys.h>
27#include <kernel/longrat.h>
28#include <kernel/ideals.h>
29#include "subexpr.h"
30#include "silink.h"
31#include "lists.h"
32#include "ssiLink.h"
33
34typedef struct
35{
36  FILE *f_read;
37  FILE *f_write;
38  ring r;
39  pid_t pid; /* only valid for fork/tcp mode*/
40  int fd_read,fd_write; /* only valid for fork/tcp mode*/
41  char level;
42} ssiInfo;
43
44// the helper functions:
45void ssiSetCurrRing(const ring r)
46{
47  if (!rEqual(r,currRing,1))
48  {
49    char name[20];
50    int nr=0;
51    do
52    { sprintf(name,"ssiRing%d",nr); nr++; }
53    while(IDROOT->get(name, 0)!=NULL);
54    idhdl h=enterid(omStrDup(name),0,RING_CMD,&IDROOT,FALSE);
55    IDRING(h)=r;
56    r->ref++;
57    rSetHdl(h);
58  }
59}
60// the implementation of the functions:
61void ssiWriteInt(ssiInfo *d,const int i)
62{
63  fprintf(d->f_write,"%d",i);
64}
65
66void ssiWriteString(ssiInfo *d,const char *s)
67{
68  fprintf(d->f_write,"%d %s",strlen(s),s);
69}
70
71
72void ssiWriteBigInt(const ssiInfo *d, const number n)
73{
74  // syntax is as follows:
75  // case 2 Q:     3 4 <int>
76  //        or     3 3 <mpz_t nominator>
77  if(SR_HDL(n) & SR_INT)
78  {
79    fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
80  }
81  else if (n->s==3)
82  {
83    gmp_fprintf(d->f_write,"3 %Zd ",n->z);
84  }
85  else Werror("illiegal bigint");
86}
87
88void ssiWriteNumber(const ssiInfo *d, const number n)
89{
90  // syntax is as follows:
91  // case 1 Z/p:   3 <int>
92  // case 2 Q:     3 4 <int>
93  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
94  //        or     3 1  dto.
95  //        or     3 3 <mpz_t nominator>
96  if(rField_is_Zp(d->r))
97  {
98    fprintf(d->f_write,"%d ",(int)(long)n);
99  }
100  else if (rField_is_Q(d->r))
101  {
102    if(SR_HDL(n) & SR_INT)
103    {
104      fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
105    }
106    else if (n->s<2)
107    {
108      gmp_fprintf(d->f_write,"%d %Zd %Zd ",n->s,n->z,n->n);
109    }
110    else /*n->s==3*/
111    {
112      gmp_fprintf(d->f_write,"3 %Zd ",n->z);
113    }
114  }
115  else WerrorS("coeff field not implemented");
116}
117
118void ssiWriteRing(ssiInfo *d,const ring r)
119{
120  /* 5 <ch> <N> <l1> <s1>....<ln> <sN> */
121  if (d->r!=NULL) rKill(d->r);
122  d->r=r;
123  d->r->ref++;
124  fprintf(d->f_write,"%d %d ",r->ch,r->N);
125
126  int i;
127  for(i=0;i<r->N;i++)
128  {
129    fprintf(d->f_write,"%d %s ",strlen(r->names[i]),r->names[i]);
130  }
131  /* number of orderings:*/
132  i=0;
133  while (r->order[i]!=0) i++;
134  fprintf(d->f_write,"%d ",i);
135  /* each ordering block: */
136  i=0;
137  while(r->order[i]!=0)
138  {
139    fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
140    i++;
141  }
142}
143
144void ssiWritePoly(ssiInfo *d, int typ, poly p)
145{
146  fprintf(d->f_write,"%d ",pLength(p));//number of terms
147  int i;
148
149  while(p!=NULL)
150  {
151    ssiWriteNumber(d,pGetCoeff(p));
152    //nWrite(fich,pGetCoeff(p));
153    fprintf(d->f_write,"%ld ",p_GetComp(p,d->r));//component
154
155    for(int j=1;j<=rVar(d->r);j++)
156    {
157      fprintf(d->f_write,"%ld ",p_GetExp(p,j,d->r ));//x^j
158    }
159    pIter(p);
160  }
161}
162
163void ssiWriteIdeal(ssiInfo *d, int typ,ideal I)
164{
165   // syntax: 7 # of elements <poly 1> <poly2>.....
166   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....
167   matrix M=(matrix)I;
168   if (typ==MATRIX_CMD)
169        fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
170   else
171     fprintf(d->f_write,"%d ",IDELEMS(I));
172
173   int i;
174   int tt;
175   if (typ==MODUL_CMD) tt=VECTOR_CMD;
176   else                tt=POLY_CMD;
177
178   for(i=0;i<IDELEMS(I);i++)
179   {
180     ssiWritePoly(d,tt,I->m[i]);
181   }
182}
183void ssiWriteCommand(si_link l, command D)
184{
185  ssiInfo *d=(ssiInfo*)l->data;
186  // syntax: <num ops> <operation> <op1> <op2> ....
187  fprintf(d->f_write,"%d %d ",D->argc,D->op);
188  if (D->argc >0) ssiWrite(l, &(D->arg1));
189  if (D->argc >1) ssiWrite(l, &(D->arg2));
190  if (D->argc >2) ssiWrite(l, &(D->arg3));
191}
192
193void ssiWriteProc(ssiInfo *d,procinfov p)
194{
195  ssiWriteString(d,p->data.s.body);
196}
197
198void ssiWriteList(si_link l,lists dd)
199{
200  ssiInfo *d=(ssiInfo*)l->data;
201  fprintf(d->f_write,"%d ",dd->nr+1);
202  int i;
203  for(i=0;i<=dd->nr;i++)
204  {
205    ssiWrite(l,&(dd->m[i]));
206  }
207}
208
209char *ssiReadString(ssiInfo *d)
210{
211  char *buf;
212  int l;
213  fscanf(d->f_read,"%d ",&l);
214  buf=(char*)omAlloc(l+1);
215  fread(buf,1,l,d->f_read);
216  buf[l]='\0';
217  return buf;
218}
219
220int ssiReadInt(FILE *fich)
221{
222  int d;
223  fscanf(fich,"%d",&d);
224  return d;
225}
226
227number ssiReadBigInt(ssiInfo *d)
228{
229   int sub_type=-1;
230   fscanf(d->f_read,"%d",&sub_type);
231   switch(sub_type)
232   {
233   case 3:
234     {// read int or mpz_t or mpz_t, mpz_t
235       number n=nlRInit(0);
236       gmp_fscanf(d->f_read,"%Zd",n->z);
237       n->s=sub_type;
238       return n;
239     }
240   case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
241   default: Werror("error in reading number: invalid subtype %d",sub_type);
242            return NULL;
243   }
244}
245
246number ssiReadNumber(ssiInfo *d)
247{
248  if (rField_is_Q(d->r))
249  {
250     int sub_type=-1;
251     fscanf(d->f_read,"%d",&sub_type);
252     switch(sub_type)
253     {
254     case 0:
255     case 1:
256       {// read int or mpz_t or mpz_t, mpz_t
257        number n=nlRInit(0);
258        mpz_init(n->n);
259        gmp_fscanf(d->f_read,"%Zd %Zd",n->z,n->n);
260        n->s=sub_type;
261        return n;
262       }
263
264     case 3:
265       {// read int or mpz_t or mpz_t, mpz_t
266         number n=nlRInit(0);
267         gmp_fscanf(d->f_read,"%Zd",n->z);
268         n->s=sub_type;
269         return n;
270       }
271     case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
272     default: Werror("error in reading number: invalid subtype %d",sub_type);
273              return NULL;
274     }
275  }
276  else if (rField_is_Zp(d->r))
277  {
278    // read int
279    int dd;
280    fscanf(d->f_read,"%d",&dd);
281    return (number)dd;
282  }
283  else Werror("coeffs not implemented");
284}
285
286ring ssiReadRing(ssiInfo *d)
287{
288/* syntax is <ch> <N> <l1> <s1> ....<lN> <sN> */
289  int ch, N,i,l;
290  char **names;
291  fscanf(d->f_read,"%d %d ",&ch,&N);
292  names=(char**)omAlloc(N*sizeof(char*));
293  for(i=0;i<N;i++)
294  {
295    names[i]=ssiReadString(d);
296  }
297  // read the orderings:
298  int num_ord; // number of orderings
299  fscanf(d->f_read,"%d",&num_ord);
300  int *ord=(int *)omAlloc0((num_ord+1)*sizeof(int));
301  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
302  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
303  for(i=0;i<num_ord;i++)
304  {
305     fscanf(d->f_read,"%d %d %d",&ord[i],&block0[i],&block1[i]);
306  }
307  return rDefault(ch,N,names,num_ord,ord,block0,block1);
308}
309
310poly ssiReadPoly(ssiInfo *D)
311{
312// < # of terms> < term1> < .....
313  int n,i,l;
314  n=ssiReadInt(D->f_read);
315  //Print("poly: terms:%d\n",n);
316  poly p;
317  int j;
318  j=0;
319  poly ret=NULL;
320  for(l=0;l<n;l++) // read n terms
321  {
322// coef,comp.exp1,..exp N
323    p=p_Init(D->r);
324    pGetCoeff(p)=ssiReadNumber(D);
325    int d;
326    fscanf(D->f_read,"%d",&d);
327    p_SetComp(p,d,D->r);
328    for(i=1;i<=rVar(D->r);i++)
329    {
330      fscanf(D->f_read,"%d",&d);
331      p_SetExp(p,i,d,D->r);
332    }
333    p_Setm(p,D->r);
334    p_Test(p,D->r);
335    ret=p_Add_q(ret,p,D->r);
336 }
337 return ret;
338}
339
340ideal ssiReadIdeal(ssiInfo *d)
341{
342  int n,i;
343  ideal I;
344  fscanf(d->f_read,"%d",&n);
345  I=idInit(n,1);
346  for(i=0;i<IDELEMS(I);i++) // read n terms
347  {
348    I->m [i]=ssiReadPoly(d);
349  }
350  return I;
351}
352
353matrix ssiReadMatrix(ssiInfo *d)
354{
355  int n,m,i,j;
356  fscanf(d->f_read,"%d %d",&m,&n);
357  matrix M=mpNew(m,n);
358  poly p;
359  for(int i=1;i<=MATROWS(M);i++)
360    for(int j=1;j<=MATCOLS(M);j++)
361    {
362      p=ssiReadPoly(d);
363      MATELEM(M,i,j)=p;
364    }
365  return M;
366}
367
368command ssiReadCommand(si_link l)
369{
370  ssiInfo *d=(ssiInfo*)l->data;
371  // syntax: <num ops> <operation> <op1> <op2> ....
372  command D=(command)omAlloc0(sizeof(*D));
373  int argc,op;
374  fscanf(d->f_read,"%d %d",&argc,&op);
375  D->argc=argc; D->op=op;
376  leftv v;
377  if (argc >0)
378  {
379    v=ssiRead1(l);
380    memcpy(&(D->arg1),v,sizeof(*v));
381    omFreeBin(v,sleftv_bin);
382  }
383  if (D->argc >1)
384  {
385    v=ssiRead1(l);
386    memcpy(&(D->arg2),v,sizeof(*v));
387    omFreeBin(v,sleftv_bin);
388  }
389  if (D->argc >2)
390  {
391    v=ssiRead1(l);
392    memcpy(&(D->arg3),v,sizeof(*v));
393    omFreeBin(v,sleftv_bin);
394  }
395  return D;
396}
397
398procinfov ssiReadProc(ssiInfo *d)
399{
400  char *s=ssiReadString(d);
401  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
402  p->language=LANG_SINGULAR;
403  p->libname=omStrDup("");
404  p->procname=omStrDup("");
405  p->data.s.body=s;
406  return p;
407}
408lists ssiReadList(si_link l)
409{
410  ssiInfo *d=(ssiInfo*)l->data;
411  int nr;
412  fscanf(d->f_read,"%d",&nr);
413  lists L=(lists)omAlloc(sizeof(*L));
414  L->Init(nr);
415
416  int i;
417  leftv v;
418  for(i=0;i<nr;i++)
419  {
420    v=ssiRead1(l);
421    memcpy(&(L->m[i]),v,sizeof(*v));
422    omFreeBin(v,sleftv_bin);
423  }
424  return L;
425}
426
427//**************************************************************************/
428BOOLEAN ssiOpen(si_link l, short flag)
429{
430  const char *mode;
431  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
432  if (flag & SI_LINK_OPEN)
433  {
434    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
435      flag = SI_LINK_READ;
436    else flag = SI_LINK_WRITE;
437  }
438
439  if (flag == SI_LINK_READ) mode = "r";
440  else if (strcmp(l->mode, "w") == 0) mode = "w";
441  else if (strcmp(l->mode, "fork") == 0) mode = "fork";
442  else mode = "a";
443
444
445  if (l->name[0] == '\0')
446  {
447    if (strcmp(mode,"fork")==0)
448    {
449      int pc[2];
450      int cp[2];
451      pipe(pc);
452      pipe(cp);
453      pid_t pid=fork();
454      if (pid==0) /*child*/
455      {
456        close(pc[1]); close(cp[0]);
457        d->f_read=fdopen(pc[0],"r");
458        d->fd_read=pc[0];
459        d->f_write=fdopen(cp[1],"w");
460        d->fd_write=cp[1];
461        l->data=d;
462        omFree(l->mode);
463        l->mode = omStrDup(mode);
464        SI_LINK_SET_OPEN_P(l, flag);
465        myynest=0;
466        fe_fgets_stdin=fe_fgets_dummy;
467        loop
468        {
469          leftv h=ssiRead1(l); /*contains an exit.... */
470          if (feErrors != NULL && *feErrors != '\0')
471          {
472            // handle errors:
473            PrintS(feErrors); /* currently quite simple */
474            *feErrors = '\0';
475          }
476          ssiWrite(l,h);
477          h->CleanUp();
478          omFreeBin(h, sleftv_bin);
479        }
480        /* never reached*/
481      }
482      else if (pid>0)
483      {
484        d->pid=pid;
485        close(pc[0]); close(cp[1]);
486        d->f_read=fdopen(cp[0],"r");
487        d->f_write=fdopen(pc[1],"w");
488        l->flags|=SI_LINK_READ|SI_LINK_WRITE;
489      }
490      else
491      {
492        Werror("fork failed (%d)",errno);
493      }
494    }
495    // stdin or stdout
496    else if (flag == SI_LINK_READ)
497    {
498      d->f_read = stdin;
499      mode = "r";
500    }
501    else
502    {
503      d->f_write = stdout;
504      mode = "a";
505    }
506  }
507  else
508  {
509    // normal ascii link to a file
510    FILE *outfile;
511    char *filename=l->name;
512
513    if(filename[0]=='>')
514    {
515      if (filename[1]=='>')
516      {
517        filename+=2;
518        mode = "a";
519      }
520      else
521      {
522        filename++;
523        mode="w";
524      }
525    }
526    outfile=myfopen(filename,mode);
527    if (outfile!=NULL)
528      d->f_write = outfile;
529    else
530    {
531      omFree(d);
532      return TRUE;
533    }
534  }
535  l->data=d;
536
537  omFree(l->mode);
538  l->mode = omStrDup(mode);
539  SI_LINK_SET_OPEN_P(l, flag);
540  return FALSE;
541}
542
543//**************************************************************************/
544LINKAGE BOOLEAN ssiClose(si_link l)
545{
546  ssiInfo *d = (ssiInfo *)l->data;
547  if (d!=NULL)
548  {
549    if (d->pid!=0) { fprintf(d->f_write,"99\n");fflush(d->f_write); }
550    if (d->f_read!=NULL) fclose(d->f_read);
551    if (d->f_write!=NULL) fclose(d->f_write);
552    if (d->r!=NULL) rKill(d->r);
553    if (d->pid!=0) { kill(d->pid,15); kill(d->pid,9); }
554    omFreeSize((ADDRESS)d,(sizeof *d));
555  }
556  l->data=NULL;
557  SI_LINK_SET_CLOSE_P(l);
558  return FALSE;
559}
560
561//**************************************************************************/
562LINKAGE leftv ssiRead1(si_link l)
563{
564  ssiInfo *d = (ssiInfo *)l->data;
565  leftv res=(leftv)omAlloc0(sizeof(sleftv));
566  int t=0;
567  fscanf(d->f_read,"%d",&t);
568  //Print("got type %d\n",t);
569  switch(t)
570  {
571    case 1:res->rtyp=INT_CMD;
572           res->data=(char *)ssiReadInt(d->f_read);
573           break;
574    case 2:res->rtyp=STRING_CMD;
575           res->data=(char *)ssiReadString(d);
576           break;
577    case 3:res->rtyp=NUMBER_CMD;
578           res->data=(char *)ssiReadNumber(d);
579           break;
580    case 4:res->rtyp=BIGINT_CMD;
581           res->data=(char *)ssiReadBigInt(d);
582           break;
583    case 5:{
584             d->r=ssiReadRing(d);
585             d->r->ref++;
586             res->rtyp=RING_CMD;
587             res->data=(char*)d->r;
588             // we are in the top-level, so set the basering to d->r:
589             ssiSetCurrRing(d->r);
590           }
591           break;
592    case 6:res->rtyp=POLY_CMD;
593           if (d->r==NULL) goto no_ring;
594           res->data=(char*)ssiReadPoly(d);
595           break;
596    case 7:res->rtyp=IDEAL_CMD;
597           if (d->r==NULL) goto no_ring;
598           res->data=(char*)ssiReadIdeal(d);
599           break;
600    case 8:res->rtyp=MATRIX_CMD;
601           if (d->r==NULL) goto no_ring;
602           res->data=(char*)ssiReadMatrix(d);
603           break;
604    case 9:res->rtyp=VECTOR_CMD;
605           if (d->r==NULL) goto no_ring;
606           res->data=(char*)ssiReadPoly(d);
607           break;
608    case 10:res->rtyp=MODUL_CMD;
609           if (d->r==NULL) goto no_ring;
610           res->data=(char*)ssiReadIdeal(d);
611           break;
612    case 11:
613           {
614             res->rtyp=COMMAND;
615             res->data=ssiReadCommand(l);
616             int nok=res->Eval();
617             if (nok) WerrorS("error in eval");
618             break;
619           }
620    case 12:
621           {
622             res->rtyp=0;
623             res->name=(char *)ssiReadString(d);
624             int nok=res->Eval();
625             if (nok) WerrorS("error in name lookup");
626             break;
627           }
628    case 13: res->rtyp=PROC_CMD;
629             res->data=ssiReadProc(d);
630             break;
631    case 14: res->rtyp=LIST_CMD;
632             res->data=ssiReadList(l);
633             break;
634    case 99: ssiClose(l); exit(0);
635    case 0: if (feof(d->f_read))
636            {
637              ssiClose(l);
638              res->rtyp=DEF_CMD;
639              break;
640            }
641    default: WerrorS("not implemented");
642             omFreeSize(res,sizeof(sleftv));
643             res=NULL;
644             break;
645  }
646  return res;
647no_ring: WerrorS("no ring");
648  return NULL;
649}
650//**************************************************************************/
651LINKAGE BOOLEAN ssiWrite(si_link l, leftv data)
652{
653  if(!SI_LINK_W_OPEN_P(l)) slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE);
654  ssiInfo *d = (ssiInfo *)l->data;
655  d->level++;
656  //FILE *fich=d->f;
657  while (data!=NULL)
658  {
659    int tt=data->Typ();
660    void *dd=data->Data();
661
662    switch(tt /*data->Typ()*/)
663    {
664          case STRING_CMD: fprintf(d->f_write,"2 ");
665                           ssiWriteString(d,(char *)dd);
666                           break;
667          case INT_CMD: fprintf(d->f_write,"1 ");
668                        ssiWriteInt(d,(int)(long)dd);
669                        break;
670          case BIGINT_CMD:fprintf(d->f_write,"4 ");
671                        ssiWriteBigInt(d,(number)dd);
672                        break;
673          case NUMBER_CMD:
674                          if (d->r!=currRing)
675                          {
676                            fprintf(d->f_write,"5 ");
677                            ssiWriteRing(d,currRing);
678                            if (d->level<=1) fprintf(d->f_write,"\n");
679                          }
680                          fprintf(d->f_write,"3 ");
681                          ssiWriteNumber(d,(number)dd);
682                        break;
683          case RING_CMD:fprintf(d->f_write,"5 ");
684                        ssiWriteRing(d,(ring)dd);
685                        break;
686          case POLY_CMD:
687          case VECTOR_CMD:
688                        if (d->r!=currRing)
689                        {
690                          fprintf(d->f_write,"5 ");
691                          ssiWriteRing(d,currRing);
692                          if (d->level<=1) fprintf(d->f_write,"\n");
693                        }
694                        if(tt==POLY_CMD) fprintf(d->f_write,"6 ");
695                        else             fprintf(d->f_write,"9 ");
696                        ssiWritePoly(d,tt,(poly)dd);
697                        break;
698          case IDEAL_CMD:
699          case MODUL_CMD:
700          case MATRIX_CMD:
701                        if (d->r!=currRing)
702                        {
703                          fprintf(d->f_write,"5 ");
704                          ssiWriteRing(d,currRing);
705                          if (d->level<=1) fprintf(d->f_write,"\n");
706                        }
707                        if(tt==IDEAL_CMD)       fprintf(d->f_write,"7 ");
708                        else if(tt==MATRIX_CMD) fprintf(d->f_write,"8 ");
709                        else                    fprintf(d->f_write,"10 ");
710                        ssiWriteIdeal(d,tt,(ideal)dd);
711                        break;
712          case COMMAND:
713                   fprintf(d->f_write,"11 ");
714                   ssiWriteCommand(l,(command)dd);
715                   break;
716          case DEF_CMD: /* not evaluated stuff in quotes */
717                   fprintf(d->f_write,"12 ");
718                 ssiWriteString(d,data->Name());
719                   break;
720          case PROC_CMD:
721                   fprintf(d->f_write,"13 ");
722                 ssiWriteProc(d,(procinfov)dd);
723                 break;
724          case LIST_CMD:
725                        if (lRingDependend((lists)dd) && (d->r!=currRing))
726                        {
727                          fprintf(d->f_write,"5 ");
728                          ssiWriteRing(d,currRing);
729                          if (d->level<=1) fprintf(d->f_write,"\n");
730                        }
731                        fprintf(d->f_write,"14 ");
732                        ssiWriteList(l,(lists)dd);
733                        break;
734          default: Werror("not implemented (t:%d)",tt);
735                   d->level=0;
736                   return TRUE;
737    }
738    if (d->level<=1) { fprintf(d->f_write,"\n"); fflush(d->f_write); }
739    data=data->next;
740  }
741  d->level--;
742  return FALSE;
743}
744
745si_link_extension slInitSsiExtension(si_link_extension s)
746{
747  s->Open=(slOpenProc)ssiOpen;
748  s->Close=(slCloseProc)ssiClose;
749  s->Kill=(slKillProc)ssiClose;
750  s->Read=(slReadProc)ssiRead1;
751  s->Read2=(slRead2Proc)NULL;
752  s->Write=(slWriteProc)ssiWrite;
753
754  s->Status=slStatusSsi;
755  s->type="ssi";
756  return s;
757}
758const char* slStatusSsi(si_link l, const char* request)
759{
760  ssiInfo *d=(ssiInfo*)l->data;
761  if ((strcmp(l->mode,"fork")==0) && (strcmp(request, "read") == 0))
762  {
763    fd_set  mask, fdmask;
764    struct timeval wt;
765    loop
766    {
767      /* Don't block. Return socket status immediately. */
768      wt.tv_sec  = 0;
769      wt.tv_usec = 0;
770
771      FD_ZERO(&mask);
772      FD_SET(d->fd_read, &mask);
773    /* check with select: chars waiting: no -> not ready */
774      switch (select(d->fd_read+1, &mask, NULL, NULL, &wt))
775      {
776        case 0: /* not ready */ return "not ready";
777        case -1: /*error*/      return "error";
778        case 1: /*ready ? */    break;
779      }
780    /* yes: read 1 char*/
781    /* if \n, check again with select else ungetc(c), ready*/
782      int c=fgetc(d->f_read);
783      switch(c)
784      {
785        case -1: return "eof";
786        case ' ':
787        case '\n': break;
788        case '1':
789        case '2':
790        case '3':
791        case '4':
792        case '5':
793        case '6':
794        case '7':
795        case '8':
796        case '9': ungetc(c,d->f_read);
797                  return "ready";
798        default: Werror("unknown char in ssiLink(%d)",c);
799                 return "error";
800      }
801    }
802  }
803  else if (strcmp(request, "read") == 0)
804  {
805    if (SI_LINK_R_OPEN_P(l) && (!feof(d->f_read))) return "ready";
806    else return "not ready";
807  }
808  else if (strcmp(request, "write") == 0)
809  {
810    if (SI_LINK_W_OPEN_P(l)) return "ready";
811    else return "not ready";
812  }
813  else return "unknown status request";
814}
815
816// ----------------------------------------------------------------
817// format
818// 1 int %d
819// 2 string <len> %s
820// 3 number
821// 4 bigint 4 %d or 3 <mpz_t>
822// 5 ring
823// 6 poly
824// 7 ideal
825// 8 matrix
826// 9 vector
827// 10 module
828// 11 command
829// 12 def <len> %s
830// 13 proc <len> %s
831// 14 list %d <elem1> ....
832//
Note: See TracBrowser for help on using the repository browser.