source: git/Singular/links/ssiLink.cc @ 179233

spielwiese
Last change on this file since 179233 was 179233, checked in by Hans Schoenemann <hannes@…>, 7 years ago
typo
  • Property mode set to 100644
File size: 54.7 KB
Line 
1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    ssiLink.h
6 *  Purpose: declaration of sl_link routines for ssi
7 ***************************************************************/
8#define TRANSEXT_PRIVATES 1 /* allow access to transext internals */
9
10#include <kernel/mod2.h>
11
12#include <omalloc/omalloc.h>
13
14#include <misc/intvec.h>
15#include <misc/options.h>
16
17#include <reporter/si_signals.h>
18#include <reporter/s_buff.h>
19
20#include <coeffs/bigintmat.h>
21#include <coeffs/longrat.h>
22
23#include <polys/monomials/ring.h>
24#include <polys/monomials/p_polys.h>
25#include <polys/ext_fields/transext.h>
26#include <polys/simpleideals.h>
27#include <polys/matpol.h>
28
29#include <kernel/oswrapper/timer.h>
30#include <kernel/oswrapper/feread.h>
31#include <kernel/oswrapper/rlimit.h>
32
33#include <Singular/tok.h>
34#include <Singular/ipid.h>
35#include <Singular/ipshell.h>
36#include <Singular/subexpr.h>
37#include <Singular/links/silink.h>
38#include <Singular/cntrlc.h>
39#include <Singular/lists.h>
40#include <Singular/blackbox.h>
41#include <Singular/links/ssiLink.h>
42
43#ifdef HAVE_SIMPLEIPC
44#include <Singular/links/simpleipc.h>
45#endif
46
47#include <stdio.h>
48#include <fcntl.h>
49#include <errno.h>
50#include <unistd.h>
51#include <sys/types.h>
52#include <signal.h>
53#include <sys/types.h>          /* for portability */
54#include <sys/select.h>
55#include <sys/socket.h>
56#include <netinet/in.h>
57#include <ctype.h>   /*for isdigit*/
58#include <netdb.h>
59#include <sys/wait.h>
60#include <time.h>
61
62#define SSI_VERSION 10
63// 5->6: changed newstruct representation
64// 6->7: attributes
65// 7->8: qring
66// 8->9: module: added rank
67// 9->10: tokens in grammar.h/tok.h reorganized
68// 10->11: extended ring descr. for named coeffs (not in used until 4.1)
69
70link_list ssiToBeClosed=NULL;
71volatile BOOLEAN ssiToBeClosed_inactive=TRUE;
72
73// forward declarations:
74void ssiWritePoly_R(const ssiInfo *d, int typ, poly p, const ring r);
75void ssiWriteIdeal_R(const ssiInfo *d, int typ,const ideal I, const ring r);
76poly ssiReadPoly_R(const ssiInfo *D, const ring r);
77ideal ssiReadIdeal_R(const ssiInfo *d,const ring r);
78
79// the helper functions:
80BOOLEAN ssiSetCurrRing(const ring r) /* returned: not accepted */
81{
82  //  if (currRing!=NULL)
83  //  Print("need to change the ring, currRing:%s, switch to: ssiRing%d\n",IDID(currRingHdl),nr);
84  //  else
85  //  Print("no ring, switch to ssiRing%d\n",nr);
86  if (!rEqual(r,currRing,1))
87  {
88    char name[20];
89    int nr=0;
90    idhdl h=NULL;
91    loop
92    {
93      sprintf(name,"ssiRing%d",nr); nr++;
94      h=IDROOT->get(name, 0);
95      if (h==NULL)
96      {
97        h=enterid(omStrDup(name),0,RING_CMD,&IDROOT,FALSE);
98        IDRING(h)=r;
99        r->ref++;
100        break;
101      }
102      else if ((IDTYP(h)==RING_CMD)
103      && (rEqual(r,IDRING(h),1)))
104        break;
105    }
106    rSetHdl(h);
107    return FALSE;
108  }
109  else
110  {
111    rKill(r);
112    return TRUE;
113  }
114}
115// the implementation of the functions:
116void ssiWriteInt(const ssiInfo *d,const int i)
117{
118  fprintf(d->f_write,"%d ",i);
119  //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
120}
121
122void ssiWriteString(const ssiInfo *d,const char *s)
123{
124  fprintf(d->f_write,"%d %s ",(int)strlen(s),s);
125  //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
126}
127
128void ssiWriteBigInt(const ssiInfo *d, const number n)
129{
130 n_WriteFd(n,d->f_write,coeffs_BIGINT);
131}
132
133void ssiWriteNumber_CF(const ssiInfo *d, const number n, const coeffs cf)
134{
135  // syntax is as follows:
136  // case 1 Z/p:   3 <int>
137  // case 2 Q:     3 4 <int>
138  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
139  //        or     3 1  dto.
140  //        or     3 3 <mpz_t nominator>
141  //        or     3 5 <mpz_t raw nom.> <mpz_t raw denom.>
142  //        or     3 6 <mpz_t raw nom.> <mpz_t raw denom.>
143  //        or     3 8 <mpz_t raw nom.>
144  if (getCoeffType(cf)==n_transExt)
145  {
146    fraction f=(fraction)n;
147    ssiWritePoly_R(d,POLY_CMD,NUM(f),cf->extRing);
148    ssiWritePoly_R(d,POLY_CMD,DEN(f),cf->extRing);
149  }
150  else if (getCoeffType(cf)==n_algExt)
151  {
152    ssiWritePoly_R(d,POLY_CMD,(poly)n,cf->extRing);
153  }
154  else if (cf->cfWriteFd!=NULL)
155  {
156    n_WriteFd(n,d->f_write,cf);
157  }
158  else WerrorS("coeff field not implemented");
159}
160
161void ssiWriteNumber(const ssiInfo *d, const number n)
162{
163  ssiWriteNumber_CF(d,n,d->r->cf);
164}
165
166void ssiWriteRing_R(ssiInfo *d,const ring r)
167{
168  /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
169  /* ch=-1: transext, coeff ring follows */
170  /* ch=-2: algext, coeff ring and minpoly follows */
171  /* ch=-3: cf name follows */
172  if (r!=NULL)
173  {
174    if (rField_is_Q(r) || rField_is_Zp(r))
175      fprintf(d->f_write,"%d %d ",n_GetChar(r->cf),r->N);
176    else if (rFieldType(r)==n_transExt)
177      fprintf(d->f_write,"-1 %d ",r->N);
178    else if (rFieldType(r)==n_algExt)
179      fprintf(d->f_write,"-2 %d ",r->N);
180    else /*dummy*/
181    {
182      fprintf(d->f_write,"-3 %d ",r->N);
183      ssiWriteString(d,nCoeffName(r->cf));
184    }
185
186    int i;
187    for(i=0;i<r->N;i++)
188    {
189      fprintf(d->f_write,"%d %s ",(int)strlen(r->names[i]),r->names[i]);
190    }
191    /* number of orderings:*/
192    i=0;
193    // remember dummy ring: everything 0:
194    if (r->order!=NULL) while (r->order[i]!=0) i++;
195    fprintf(d->f_write,"%d ",i);
196    /* each ordering block: */
197    i=0;
198    if (r->order!=NULL) while(r->order[i]!=0)
199    {
200      fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
201      switch(r->order[i])
202      {
203        case ringorder_a:
204        case ringorder_wp:
205        case ringorder_Wp:
206        case ringorder_ws:
207        case ringorder_Ws:
208        case ringorder_aa:
209        {
210          int ii;
211          for(ii=r->block0[i];ii<=r->block1[i];ii++)
212            fprintf(d->f_write,"%d ",r->wvhdl[i][ii-r->block0[i]]);
213        }
214        break;
215
216        case ringorder_a64:
217        case ringorder_M:
218        case ringorder_L:
219        case ringorder_IS:
220          Werror("ring oder not implemented for ssi:%d",r->order[i]);
221          break;
222
223        default: break;
224      }
225      i++;
226    }
227    if ((rFieldType(r)==n_transExt)
228    || (rFieldType(r)==n_algExt))
229    {
230      ssiWriteRing_R(d,r->cf->extRing); /* includes alg.ext if rFieldType(r)==n_algExt */
231    }
232    /* Q-ideal :*/
233    if (r->qideal!=NULL)
234    {
235      ssiWriteIdeal_R(d,IDEAL_CMD,r->qideal,r);
236    }
237    else
238    {
239      fputs("0 ",d->f_write/*ideal with 0 entries */);
240    }
241  }
242  else /* dummy ring r==NULL*/
243  {
244    fputs("0 0 0 0 "/*,r->ch,r->N, blocks, q-ideal*/,d->f_write);
245  }
246}
247
248void ssiWriteRing(ssiInfo *d,const ring r)
249{
250  /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
251  /* ch=-1: transext, coeff ring follows */
252  /* ch=-2: algext, coeff ring and minpoly follows */
253  /* ch=-3: cf name follows */
254  if ((r==NULL)||(r->cf==NULL))
255  {
256    WerrorS("undefined ring");
257    return;
258  }
259  if (r==currRing) // see recursive calls for transExt/algExt
260  {
261    if (d->r!=NULL) rKill(d->r);
262    d->r=r;
263  }
264  if (r!=NULL)
265  {
266    /*d->*/r->ref++;
267  }
268  ssiWriteRing_R(d,r);
269}
270void ssiWritePoly_R(const ssiInfo *d, int /*typ*/, poly p, const ring r)
271{
272  fprintf(d->f_write,"%d ",pLength(p));//number of terms
273
274  while(p!=NULL)
275  {
276    ssiWriteNumber_CF(d,pGetCoeff(p),r->cf);
277    //nWrite(fich,pGetCoeff(p));
278    fprintf(d->f_write,"%ld ",p_GetComp(p,r));//component
279
280    for(int j=1;j<=rVar(r);j++)
281    {
282      fprintf(d->f_write,"%ld ",p_GetExp(p,j,r ));//x^j
283    }
284    pIter(p);
285  }
286}
287
288void ssiWritePoly(const ssiInfo *d, int typ, poly p)
289{
290  ssiWritePoly_R(d,typ,p,d->r);
291}
292
293void ssiWriteIdeal_R(const ssiInfo *d, int typ,const ideal I, const ring R)
294{
295   // syntax: 7 # of elements <poly 1> <poly2>.....
296   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....
297   matrix M=(matrix)I;
298   int mn;
299   if (typ==MATRIX_CMD)
300   {
301     mn=MATROWS(M)*MATCOLS(M);
302     fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
303   }
304   else
305   {
306     mn=IDELEMS(I);
307     fprintf(d->f_write,"%d ",IDELEMS(I));
308   }
309
310   int i;
311   int tt;
312   if (typ==MODUL_CMD) tt=VECTOR_CMD;
313   else                tt=POLY_CMD;
314
315   for(i=0;i<mn;i++)
316   {
317     ssiWritePoly_R(d,tt,I->m[i],R);
318   }
319}
320void ssiWriteIdeal(const ssiInfo *d, int typ,const ideal I)
321{
322  ssiWriteIdeal_R(d,typ,I,d->r);
323}
324
325void ssiWriteCommand(si_link l, command D)
326{
327  ssiInfo *d=(ssiInfo*)l->data;
328  // syntax: <num ops> <operation> <op1> <op2> ....
329  fprintf(d->f_write,"%d %d ",D->argc,D->op);
330  if (D->argc >0) ssiWrite(l, &(D->arg1));
331  if (D->argc < 4)
332  {
333    if (D->argc >1) ssiWrite(l, &(D->arg2));
334    if (D->argc >2) ssiWrite(l, &(D->arg3));
335  }
336}
337
338void ssiWriteProc(const ssiInfo *d,procinfov p)
339{
340  if (p->data.s.body==NULL)
341    iiGetLibProcBuffer(p);
342  if (p->data.s.body!=NULL)
343    ssiWriteString(d,p->data.s.body);
344  else
345    ssiWriteString(d,"");
346}
347
348void ssiWriteList(si_link l,lists dd)
349{
350  ssiInfo *d=(ssiInfo*)l->data;
351  int Ll=dd->nr;
352  fprintf(d->f_write,"%d ",Ll+1);
353  int i;
354  for(i=0;i<=Ll;i++)
355  {
356    ssiWrite(l,&(dd->m[i]));
357  }
358}
359void ssiWriteIntvec(const ssiInfo *d,intvec * v)
360{
361  fprintf(d->f_write,"%d ",v->length());
362  int i;
363  for(i=0;i<v->length();i++)
364  {
365    fprintf(d->f_write,"%d ",(*v)[i]);
366  }
367}
368void ssiWriteIntmat(const ssiInfo *d,intvec * v)
369{
370  fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
371  int i;
372  for(i=0;i<v->length();i++)
373  {
374    fprintf(d->f_write,"%d ",(*v)[i]);
375  }
376}
377
378void ssiWriteBigintmat(const ssiInfo *d,bigintmat * v)
379{
380  fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
381  int i;
382  for(i=0;i<v->length();i++)
383  {
384    ssiWriteBigInt(d,(*v)[i]);
385  }
386}
387
388char *ssiReadString(const ssiInfo *d)
389{
390  char *buf;
391  int l;
392  l=s_readint(d->f_read);
393  buf=(char*)omAlloc0(l+1);
394  int throwaway =s_getc(d->f_read); /* skip ' '*/
395  throwaway=s_readbytes(buf,l,d->f_read);
396  //if (throwaway!=l) printf("want %d, got %d bytes\n",l,throwaway);
397  buf[l]='\0';
398  return buf;
399}
400
401int ssiReadInt(s_buff fich)
402{
403  return s_readint(fich);
404}
405
406number ssiReadNumber_CF(const ssiInfo *d, const coeffs cf)
407{
408  if (cf->cfReadFd!=NULL)
409  {
410     return n_ReadFd(d->f_read,cf);
411  }
412  else if (getCoeffType(cf) == n_transExt)
413  {
414    // poly poly
415    fraction f=(fraction)n_Init(1,cf);
416    p_Delete(&NUM(f),cf->extRing);
417    NUM(f)=ssiReadPoly_R(d,cf->extRing);
418    DEN(f)=ssiReadPoly_R(d,cf->extRing);
419    return (number)f;
420  }
421  else if (getCoeffType(cf) == n_algExt)
422  {
423    // poly
424    return (number)ssiReadPoly_R(d,cf->extRing);
425  }
426  else WerrorS("coeffs not implemented in ssiReadNumber");
427  return NULL;
428}
429
430number ssiReadBigInt(const ssiInfo *d)
431{
432  number n=ssiReadNumber_CF(d,coeffs_BIGINT);
433  if ((SR_HDL(n) & SR_INT)==0)
434  {
435    if (n->s!=3) Werror("invalid sub type in bigint:%d",n->s);
436  }
437  return n;
438}
439
440number ssiReadNumber(const ssiInfo *d)
441{
442  if (currRing==NULL) ssiSetCurrRing(d->r);
443  return ssiReadNumber_CF(d,d->r->cf);
444}
445
446ring ssiReadRing(const ssiInfo *d)
447{
448/* syntax is <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <Q-ideal> */
449  int ch, N,i;
450  char **names;
451  ch=s_readint(d->f_read);
452  N=s_readint(d->f_read);
453  coeffs cf=NULL;
454  if (ch==-3)
455  {
456    char *cf_name=ssiReadString(d);
457    cf=nFindCoeffByName(cf_name);
458    if (cf==NULL)
459    {
460      Werror("cannot find cf:%s",cf_name);
461      omFree(cf_name);
462      return NULL;
463    }
464  }
465  if (N!=0)
466  {
467    names=(char**)omAlloc(N*sizeof(char*));
468    for(i=0;i<N;i++)
469    {
470      names[i]=ssiReadString(d);
471    }
472  }
473  // read the orderings:
474  int num_ord; // number of orderings
475  num_ord=s_readint(d->f_read);
476  rRingOrder_t *ord=(rRingOrder_t *)omAlloc0((num_ord+1)*sizeof(rRingOrder_t));
477  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
478  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
479  int **wvhdl=(int**)omAlloc0((num_ord+1)*sizeof(int*));
480  for(i=0;i<num_ord;i++)
481  {
482    ord[i]=(rRingOrder_t)s_readint(d->f_read);
483    block0[i]=s_readint(d->f_read);
484    block1[i]=s_readint(d->f_read);
485    switch(ord[i])
486    {
487      case ringorder_a:
488      case ringorder_wp:
489      case ringorder_Wp:
490      case ringorder_ws:
491      case ringorder_Ws:
492      case ringorder_aa:
493      {
494        wvhdl[i]=(int*)omAlloc((block1[i]-block0[i]+1)*sizeof(int));
495        int ii;
496        for(ii=block0[i];ii<=block1[i];ii++)
497          wvhdl[i][ii-block0[i]]=s_readint(d->f_read);
498      }
499      break;
500
501      case ringorder_a64:
502      case ringorder_M:
503      case ringorder_L:
504      case ringorder_IS:
505        Werror("ring oder not implemented for ssi:%d",ord[i]);
506        break;
507
508      default: break;
509    }
510  }
511  if (N==0)
512  {
513    omFree(ord);
514    omFree(block0);
515    omFree(block1);
516    omFree(wvhdl);
517    return NULL;
518  }
519  else
520  {
521    ring r=NULL;
522    if (ch>=0) /* Q, Z/p */
523      r=rDefault(ch,N,names,num_ord,ord,block0,block1,wvhdl);
524    else if (ch==-1) /* trans ext. */
525    {
526      TransExtInfo T;
527      T.r=ssiReadRing(d);
528      if (T.r==NULL) return NULL;
529      cf=nInitChar(n_transExt,&T);
530      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
531    }
532    else if (ch==-2) /* alg ext. */
533    {
534      TransExtInfo T;
535      T.r=ssiReadRing(d); /* includes qideal */
536      if (T.r==NULL) return NULL;
537      cf=nInitChar(n_algExt,&T);
538      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
539    }
540    else if (ch==-3)
541    {
542      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
543    }
544    else
545    {
546      Werror("ssi: read unknown coeffs type (%d)",ch);
547      for(i=0;i<N;i++)
548      {
549        omFree(names[i]);
550      }
551      omFreeSize(names,N*sizeof(char*));
552      return NULL;
553    }
554    ideal q=ssiReadIdeal_R(d,r);
555    if (IDELEMS(q)==0) omFreeBin(q,sip_sideal_bin);
556    else r->qideal=q;
557    for(i=0;i<N;i++)
558    {
559      omFree(names[i]);
560    }
561    omFreeSize(names,N*sizeof(char*));
562    return r;
563  }
564}
565
566poly ssiReadPoly_R(const ssiInfo *D, const ring r)
567{
568// < # of terms> < term1> < .....
569  int n,i,l;
570  n=ssiReadInt(D->f_read); // # of terms
571  //Print("poly: terms:%d\n",n);
572  poly p;
573  poly ret=NULL;
574  poly prev=NULL;
575  for(l=0;l<n;l++) // read n terms
576  {
577// coef,comp.exp1,..exp N
578    p=p_Init(r);
579    pSetCoeff0(p,ssiReadNumber_CF(D,r->cf));
580    int d;
581    d=s_readint(D->f_read);
582    p_SetComp(p,d,r);
583    for(i=1;i<=rVar(r);i++)
584    {
585      d=s_readint(D->f_read);
586      p_SetExp(p,i,d,r);
587    }
588    p_Setm(p,r);
589    p_Test(p,r);
590    if (ret==NULL) ret=p;
591    else           pNext(prev)=p;
592    prev=p;
593 }
594 return ret;
595}
596
597poly ssiReadPoly(const ssiInfo *D)
598{
599  if (currRing==NULL) ssiSetCurrRing(D->r);
600  return ssiReadPoly_R(D,D->r);
601}
602
603ideal ssiReadIdeal_R(const ssiInfo *d,const ring r)
604{
605// < # of terms> < term1> < .....
606  int n,i;
607  ideal I;
608  n=s_readint(d->f_read);
609  I=idInit(n,1);
610  for(i=0;i<IDELEMS(I);i++) // read n terms
611  {
612    I->m [i]=ssiReadPoly_R(d,r);
613  }
614  return I;
615}
616
617ideal ssiReadIdeal(const ssiInfo *d)
618{
619  if (currRing==NULL) ssiSetCurrRing(d->r);
620  return ssiReadIdeal_R(d,d->r);
621}
622
623matrix ssiReadMatrix(const ssiInfo *d)
624{
625  int n,m;
626  m=s_readint(d->f_read);
627  n=s_readint(d->f_read);
628  matrix M=mpNew(m,n);
629  poly p;
630  for(int i=1;i<=MATROWS(M);i++)
631    for(int j=1;j<=MATCOLS(M);j++)
632    {
633      p=ssiReadPoly(d);
634      MATELEM(M,i,j)=p;
635    }
636  return M;
637}
638
639command ssiReadCommand(si_link l)
640{
641  ssiInfo *d=(ssiInfo*)l->data;
642  // syntax: <num ops> <operation> <op1> <op2> ....
643  command D=(command)omAlloc0(sizeof(*D));
644  int argc,op;
645  argc=s_readint(d->f_read);
646  op=s_readint(d->f_read);
647  D->argc=argc; D->op=op;
648  leftv v;
649  if (argc >0)
650  {
651    v=ssiRead1(l);
652    memcpy(&(D->arg1),v,sizeof(*v));
653    omFreeBin(v,sleftv_bin);
654  }
655  if (argc <4)
656  {
657    if (D->argc >1)
658    {
659      v=ssiRead1(l);
660      memcpy(&(D->arg2),v,sizeof(*v));
661      omFreeBin(v,sleftv_bin);
662    }
663    if (D->argc >2)
664    {
665      v=ssiRead1(l);
666      memcpy(&(D->arg3),v,sizeof(*v));
667      omFreeBin(v,sleftv_bin);
668    }
669  }
670  else
671  {
672    leftv prev=&(D->arg1);
673    argc--;
674    while(argc >0)
675    {
676      v=ssiRead1(l);
677      prev->next=v;
678      prev=v;
679      argc--;
680    }
681  }
682  return D;
683}
684
685procinfov ssiReadProc(const ssiInfo *d)
686{
687  char *s=ssiReadString(d);
688  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
689  p->language=LANG_SINGULAR;
690  p->libname=omStrDup("");
691  p->procname=omStrDup("");
692  p->data.s.body=s;
693  return p;
694}
695lists ssiReadList(si_link l)
696{
697  ssiInfo *d=(ssiInfo*)l->data;
698  int nr;
699  nr=s_readint(d->f_read);
700  lists L=(lists)omAlloc0Bin(slists_bin);
701  L->Init(nr);
702
703  int i;
704  leftv v;
705  for(i=0;i<=L->nr;i++)
706  {
707    v=ssiRead1(l);
708    memcpy(&(L->m[i]),v,sizeof(*v));
709    omFreeBin(v,sleftv_bin);
710  }
711  return L;
712}
713intvec* ssiReadIntvec(const ssiInfo *d)
714{
715  int nr;
716  nr=s_readint(d->f_read);
717  intvec *v=new intvec(nr);
718  for(int i=0;i<nr;i++)
719  {
720    (*v)[i]=s_readint(d->f_read);
721  }
722  return v;
723}
724intvec* ssiReadIntmat(const ssiInfo *d)
725{
726  int r,c;
727  r=s_readint(d->f_read);
728  c=s_readint(d->f_read);
729  intvec *v=new intvec(r,c,0);
730  for(int i=0;i<r*c;i++)
731  {
732    (*v)[i]=s_readint(d->f_read);
733  }
734  return v;
735}
736bigintmat* ssiReadBigintmat(const ssiInfo *d)
737{
738  int r,c;
739  r=s_readint(d->f_read);
740  c=s_readint(d->f_read);
741  bigintmat *v=new bigintmat(r,c,coeffs_BIGINT);
742  for(int i=0;i<r*c;i++)
743  {
744    (*v)[i]=ssiReadBigInt(d);
745  }
746  return v;
747}
748
749void ssiReadBlackbox(leftv res, si_link l)
750{
751  ssiInfo *d=(ssiInfo*)l->data;
752  int throwaway=s_readint(d->f_read);
753  char *name=ssiReadString(d);
754  int tok;
755  blackboxIsCmd(name,tok);
756  if (tok>MAX_TOK)
757  {
758    blackbox *b=getBlackboxStuff(tok);
759    res->rtyp=tok;
760    b->blackbox_deserialize(&b,&(res->data),l);
761  }
762  else
763  {
764    Werror("blackbox %s not found",name);
765  }
766  omFree(name);
767}
768
769void ssiReadAttrib(leftv res, si_link l)
770{
771  ssiInfo *d=(ssiInfo*)l->data;
772  BITSET fl=(BITSET)s_readint(d->f_read);
773  int nr_of_attr=s_readint(d->f_read);
774  if (nr_of_attr>0)
775  {
776    for(int i=1;i<nr_of_attr;i++)
777    {
778    }
779  }
780  leftv tmp=ssiRead1(l);
781  memcpy(res,tmp,sizeof(sleftv));
782  memset(tmp,0,sizeof(sleftv));
783  omFreeBin(tmp,sleftv_bin);
784  if (nr_of_attr>0)
785  {
786  }
787  res->flag=fl;
788}
789//**************************************************************************/
790
791BOOLEAN ssiOpen(si_link l, short flag, leftv u)
792{
793  if (l!=NULL)
794  {
795    const char *mode;
796    ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
797    if (flag & SI_LINK_OPEN)
798    {
799      if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
800        flag = SI_LINK_READ;
801      else flag = SI_LINK_WRITE;
802    }
803
804    if (flag == SI_LINK_READ) mode = "r";
805    else if (strcmp(l->mode, "w") == 0) mode = "w";
806    else if (strcmp(l->mode, "fork") == 0) mode = "fork";
807    else if (strcmp(l->mode, "tcp") == 0) mode = "tcp";
808    else if (strcmp(l->mode, "connect") == 0) mode = "connect";
809    else mode = "a";
810
811
812    SI_LINK_SET_OPEN_P(l, flag);
813    if(l->data!=NULL) omFreeSize(l->data,sizeof(ssiInfo));
814    l->data=d;
815    omFree(l->mode);
816    l->mode = omStrDup(mode);
817
818    if (l->name[0] == '\0')
819    {
820      if (strcmp(mode,"fork")==0)
821      {
822        link_list n=(link_list)omAlloc(sizeof(link_struct));
823        n->u=u;
824        n->l=l;
825        n->next=(void *)ssiToBeClosed;
826        ssiToBeClosed=n;
827
828        int pc[2];
829        int cp[2];
830        pipe(pc);
831        pipe(cp);
832        pid_t pid = fork();
833        if (pid == -1 && errno == EAGAIN)   // RLIMIT_NPROC too low?
834        {
835          raise_rlimit_nproc();
836          pid = fork();
837        }
838        if (pid == -1)
839        {
840          WerrorS("could not fork");
841        }
842        if (pid==0) /*fork: child*/
843        {
844          /* block SIGINT */
845          sigset_t sigint;
846          sigemptyset(&sigint);
847          sigaddset(&sigint, SIGINT);
848          sigprocmask(SIG_BLOCK, &sigint, NULL);
849
850          link_list hh=(link_list)ssiToBeClosed->next;
851          /* we know: l is the first entry in ssiToBeClosed-list */
852          while(hh!=NULL)
853          {
854            SI_LINK_SET_CLOSE_P(hh->l);
855            ssiInfo *dd=(ssiInfo*)hh->l->data;
856            s_close(dd->f_read);
857            fclose(dd->f_write);
858            if (dd->r!=NULL) rKill(dd->r);
859            omFreeSize((ADDRESS)dd,(sizeof *dd));
860            hh->l->data=NULL;
861            link_list nn=(link_list)hh->next;
862            omFree(hh);
863            hh=nn;
864          }
865          ssiToBeClosed->next=NULL;
866#ifdef HAVE_SIMPLEIPC
867          memset(sem_acquired, 0, SIPC_MAX_SEMAPHORES*sizeof(sem_acquired[0]));
868#endif   // HAVE_SIMPLEIPC
869          si_close(pc[1]); si_close(cp[0]);
870          d->f_write=fdopen(cp[1],"w");
871          d->f_read=s_open(pc[0]);
872          d->fd_read=pc[0];
873          d->fd_write=cp[1];
874          //d->r=currRing;
875          //if (d->r!=NULL) d->r->ref++;
876          l->data=d;
877          omFree(l->mode);
878          l->mode = omStrDup(mode);
879          singular_in_batchmode=TRUE;
880          SI_LINK_SET_RW_OPEN_P(l);
881          //myynest=0;
882          fe_fgets_stdin=fe_fgets_dummy;
883          if ((u!=NULL)&&(u->rtyp==IDHDL))
884          {
885            idhdl h=(idhdl)u->data;
886            h->lev=0;
887          }
888          loop
889          {
890            if (!SI_LINK_OPEN_P(l)) m2_end(0);
891            if(d->f_read->is_eof) m2_end(0);
892            leftv h=ssiRead1(l); /*contains an exit.... */
893            if (feErrors != NULL && *feErrors != '\0')
894            {
895              // handle errors:
896              PrintS(feErrors); /* currently quite simple */
897              *feErrors = '\0';
898            }
899            ssiWrite(l,h);
900            h->CleanUp();
901            omFreeBin(h, sleftv_bin);
902          }
903          /* never reached*/
904        }
905        else if (pid>0) /*fork: parent*/
906        {
907          d->pid=pid;
908          si_close(pc[0]); si_close(cp[1]);
909          d->f_write=fdopen(pc[1],"w");
910          d->f_read=s_open(cp[0]);
911          d->fd_read=cp[0];
912          d->fd_write=pc[1];
913          SI_LINK_SET_RW_OPEN_P(l);
914          d->send_quit_at_exit=1;
915          //d->r=currRing;
916          //if (d->r!=NULL) d->r->ref++;
917        }
918        else
919        {
920          Werror("fork failed (%d)",errno);
921          l->data=NULL;
922          omFree(d);
923          return TRUE;
924        }
925      }
926      // ---------------------------------------------------------------------
927      else if (strcmp(mode,"tcp")==0)
928      {
929        int sockfd, newsockfd, portno, clilen;
930        struct sockaddr_in serv_addr, cli_addr;
931        sockfd = socket(AF_INET, SOCK_STREAM, 0);
932        if(sockfd < 0)
933        {
934          WerrorS("ERROR opening socket");
935          l->data=NULL;
936          omFree(d);
937          return TRUE;
938        }
939        memset((char *) &serv_addr,0, sizeof(serv_addr));
940        portno = 1025;
941        serv_addr.sin_family = AF_INET;
942        serv_addr.sin_addr.s_addr = INADDR_ANY;
943        do
944        {
945          portno++;
946          serv_addr.sin_port = htons(portno);
947          if(portno > 50000)
948          {
949            WerrorS("ERROR on binding (no free port available?)");
950            l->data=NULL;
951            omFree(d);
952            return TRUE;
953          }
954        }
955        while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
956        Print("waiting on port %d\n", portno);mflush();
957        listen(sockfd,1);
958        newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
959        if(newsockfd < 0)
960        {
961          WerrorS("ERROR on accept");
962          l->data=NULL;
963          omFree(d);
964          return TRUE;
965        }
966        PrintS("client accepted\n");
967        d->fd_read = newsockfd;
968        d->fd_write = newsockfd;
969        d->f_read = s_open(newsockfd);
970        d->f_write = fdopen(newsockfd, "w");
971        SI_LINK_SET_RW_OPEN_P(l);
972        si_close(sockfd);
973      }
974      // no ssi-Link on stdin or stdout
975      else
976      {
977        Werror("invalid mode >>%s<< for ssi",mode);
978        l->data=NULL;
979        omFree(d);
980        return TRUE;
981      }
982    }
983    // =========================================================================
984    else /*l->name=NULL*/
985    {
986      // tcp mode
987      if(strcmp(mode,"tcp")==0)
988      {
989        int sockfd, newsockfd, portno, clilen;
990        struct sockaddr_in serv_addr, cli_addr;
991        sockfd = socket(AF_INET, SOCK_STREAM, 0);
992        if(sockfd < 0)
993        {
994          WerrorS("ERROR opening socket");
995          l->data=NULL;
996          omFree(d);
997          return TRUE;
998        }
999        memset((char *) &serv_addr,0, sizeof(serv_addr));
1000        portno = 1025;
1001        serv_addr.sin_family = AF_INET;
1002        serv_addr.sin_addr.s_addr = INADDR_ANY;
1003        do
1004        {
1005          portno++;
1006          serv_addr.sin_port = htons(portno);
1007          if(portno > 50000)
1008          {
1009            WerrorS("ERROR on binding (no free port available?)");
1010            l->data=NULL;
1011            return TRUE;
1012          }
1013        }
1014        while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
1015        //Print("waiting on port %d\n", portno);mflush();
1016        listen(sockfd,1);
1017        char* cli_host = (char*)omAlloc(256);
1018        char* path = (char*)omAlloc(1024);
1019        int r = si_sscanf(l->name,"%255[^:]:%s",cli_host,path);
1020        if(r == 0)
1021        {
1022          WerrorS("ERROR: no host specified");
1023          l->data=NULL;
1024          omFree(d);
1025          omFree(path);
1026          omFree(cli_host);
1027          return TRUE;
1028        }
1029        else if(r == 1)
1030        {
1031          WarnS("program not specified, using /usr/local/bin/Singular");
1032          Warn("in line >>%s<<",my_yylinebuf);
1033          strcpy(path,"/usr/local/bin/Singular");
1034        }
1035        char* ssh_command = (char*)omAlloc(256);
1036        char* ser_host = (char*)omAlloc(64);
1037        gethostname(ser_host,64);
1038        sprintf(ssh_command,"ssh %s %s -q --batch --link=ssi --MPhost=%s --MPport=%d &",cli_host,path,ser_host,portno);
1039        //Print("client on %s started:%s\n",cli_host,path);
1040        omFree(path);
1041        omFree(cli_host);
1042        if (TEST_OPT_PROT) { Print("running >>%s<<\n",ssh_command); }
1043        system(ssh_command);
1044        omFree(ssh_command);
1045        omFree(ser_host);
1046        clilen = sizeof(cli_addr);
1047        newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
1048        if(newsockfd < 0)
1049        {
1050          WerrorS("ERROR on accept");
1051          l->data=NULL;
1052          omFree(d);
1053          return TRUE;
1054        }
1055        //PrintS("client accepted\n");
1056        d->fd_read = newsockfd;
1057        d->fd_write = newsockfd;
1058        d->f_read = s_open(newsockfd);
1059        d->f_write = fdopen(newsockfd, "w");
1060        si_close(sockfd);
1061        SI_LINK_SET_RW_OPEN_P(l);
1062        d->send_quit_at_exit=1;
1063        link_list newlink=(link_list)omAlloc(sizeof(link_struct));
1064        newlink->u=u;
1065        newlink->l=l;
1066        newlink->next=(void *)ssiToBeClosed;
1067        ssiToBeClosed=newlink;
1068        fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
1069      }
1070      // ----------------------------------------------------------------------
1071      else if(strcmp(mode,"connect")==0)
1072      {
1073        char* host = (char*)omAlloc(256);
1074        int sockfd, portno;
1075        struct sockaddr_in serv_addr;
1076        struct hostent *server;
1077
1078        si_sscanf(l->name,"%255[^:]:%d",host,&portno);
1079        //Print("connect to host %s, port %d\n",host,portno);mflush();
1080        if (portno!=0)
1081        {
1082          sockfd = socket(AF_INET, SOCK_STREAM, 0);
1083          if (sockfd < 0) { WerrorS("ERROR opening socket"); return TRUE; }
1084          server = gethostbyname(host);
1085          if (server == NULL) {  WerrorS("ERROR, no such host");  return TRUE; }
1086          memset((char *) &serv_addr, 0, sizeof(serv_addr));
1087          serv_addr.sin_family = AF_INET;
1088          memcpy((char *)&serv_addr.sin_addr.s_addr,
1089                (char *)server->h_addr,
1090                server->h_length);
1091          serv_addr.sin_port = htons(portno);
1092          if (si_connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
1093          { Werror("ERROR connecting(errno=%d)",errno); return TRUE; }
1094          //PrintS("connected\n");mflush();
1095          d->f_read=s_open(sockfd);
1096          d->fd_read=sockfd;
1097          d->f_write=fdopen(sockfd,"w");
1098          d->fd_write=sockfd;
1099          SI_LINK_SET_RW_OPEN_P(l);
1100          omFree(host);
1101        }
1102        else
1103        {
1104          l->data=NULL;
1105          omFree(d);
1106          return TRUE;
1107        }
1108      }
1109      // ======================================================================
1110      else
1111      {
1112        // normal link to a file
1113        FILE *outfile;
1114        char *filename=l->name;
1115
1116        if(filename[0]=='>')
1117        {
1118          if (filename[1]=='>')
1119          {
1120            filename+=2;
1121            mode = "a";
1122          }
1123          else
1124          {
1125            filename++;
1126            mode="w";
1127          }
1128        }
1129        outfile=myfopen(filename,mode);
1130        if (outfile!=NULL)
1131        {
1132          if (strcmp(l->mode,"r")==0)
1133          {
1134            fclose(outfile);
1135            d->f_read=s_open_by_name(filename);
1136          }
1137          else
1138          {
1139            d->f_write = outfile;
1140            fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
1141          }
1142        }
1143        else
1144        {
1145          omFree(d);
1146          l->data=NULL;
1147          return TRUE;
1148        }
1149      }
1150    }
1151  }
1152
1153  return FALSE;
1154}
1155
1156//**************************************************************************/
1157BOOLEAN ssiPrepClose(si_link l)
1158{
1159  if (l!=NULL)
1160  {
1161    SI_LINK_SET_CLOSE_P(l);
1162    ssiInfo *d = (ssiInfo *)l->data;
1163    if (d!=NULL)
1164    {
1165      if (d->send_quit_at_exit)
1166      {
1167        fputs("99\n",d->f_write);
1168        fflush(d->f_write);
1169      }
1170      d->quit_sent=1;
1171    }
1172  }
1173  return FALSE;
1174}
1175
1176BOOLEAN ssiClose(si_link l)
1177{
1178  if (l!=NULL)
1179  {
1180    SI_LINK_SET_CLOSE_P(l);
1181    ssiInfo *d = (ssiInfo *)l->data;
1182    if (d!=NULL)
1183    {
1184      // send quit signal
1185      if ((d->send_quit_at_exit)
1186      && (d->quit_sent==0))
1187      {
1188        fputs("99\n",d->f_write);
1189        fflush(d->f_write);
1190      }
1191      // clean ring
1192      if (d->r!=NULL) rKill(d->r);
1193      // did the child to stop ?
1194      si_waitpid(d->pid,NULL,WNOHANG);
1195      if ((d->pid!=0)
1196      && (kill(d->pid,0)==0)) // child is still running
1197      {
1198        struct timespec t;
1199        t.tv_sec=0;
1200        t.tv_nsec=100000000; // <=100 ms
1201        struct timespec rem;
1202        int r;
1203        loop
1204        {
1205          // wait till signal or time rem:
1206          r = nanosleep(&t, &rem);
1207          t = rem;
1208          // child finished:
1209          if (si_waitpid(d->pid,NULL,WNOHANG) != 0) break;
1210          // other signal, waited s>= 100 ms:
1211          if ((r==0) || (errno != EINTR)) break;
1212        }
1213        if (kill(d->pid,0) == 0) // pid still exists
1214        {
1215          kill(d->pid,15);
1216          t.tv_sec=5; // <=5s
1217          t.tv_nsec=0;
1218          loop
1219          {
1220            // wait till signal or time rem:
1221            r = nanosleep(&t, &rem);
1222            t = rem;
1223            // child finished:
1224            if (si_waitpid(d->pid,NULL,WNOHANG) != 0) break;
1225            // other signal, waited s>=  5 s:
1226            if ((r==0) || (errno != EINTR)) break;
1227          }
1228          if (kill(d->pid,0) == 0)
1229          {
1230            kill(d->pid,9); // just to be sure
1231            si_waitpid(d->pid,NULL,0);
1232          }
1233        }
1234      }
1235      if (d->f_read!=NULL) { s_close(d->f_read);d->f_read=NULL;}
1236      if (d->f_write!=NULL) { fclose(d->f_write); d->f_write=NULL; }
1237      if ((strcmp(l->mode,"tcp")==0)
1238      || (strcmp(l->mode,"fork")==0))
1239      {
1240        link_list hh=ssiToBeClosed;
1241        if (hh!=NULL)
1242        {
1243          if (hh->l==l)
1244          {
1245             ssiToBeClosed=(link_list)hh->next;
1246             omFreeSize(hh,sizeof(link_struct));
1247          }
1248          else while(hh->next!=NULL)
1249          {
1250            link_list hhh=(link_list)hh->next;
1251            if (hhh->l==l)
1252            {
1253              hh->next=hhh->next;
1254              omFreeSize(hhh,sizeof(link_struct));
1255              break;
1256            }
1257            else
1258              hh=(link_list)hh->next;
1259          }
1260        }
1261      }
1262      omFreeSize((ADDRESS)d,(sizeof *d));
1263    }
1264    l->data=NULL;
1265  }
1266  return FALSE;
1267}
1268
1269//**************************************************************************/
1270leftv ssiRead1(si_link l)
1271{
1272  ssiInfo *d = (ssiInfo *)l->data;
1273  leftv res=(leftv)omAlloc0Bin(sleftv_bin);
1274  int t=0;
1275  t=s_readint(d->f_read);
1276  //Print("got type %d\n",t);
1277  switch(t)
1278  {
1279    case 1:res->rtyp=INT_CMD;
1280           res->data=(char *)(long)ssiReadInt(d->f_read);
1281           break;
1282    case 2:res->rtyp=STRING_CMD;
1283           res->data=(char *)ssiReadString(d);
1284           break;
1285    case 3:res->rtyp=NUMBER_CMD;
1286           res->data=(char *)ssiReadNumber(d);
1287           break;
1288    case 4:res->rtyp=BIGINT_CMD;
1289           res->data=(char *)ssiReadBigInt(d);
1290           break;
1291    case 15:
1292    case 5:{
1293             d->r=ssiReadRing(d);
1294             if (d->r==NULL) return NULL;
1295             res->data=(char*)d->r;
1296             d->r->ref++;
1297             res->rtyp=RING_CMD;
1298             if (t==15) // setring
1299             {
1300               if(ssiSetCurrRing(d->r)) { d->r=currRing; d->r->ref++; }
1301               omFreeBin(res,sleftv_bin);
1302               return ssiRead1(l);
1303             }
1304           }
1305           break;
1306    case 6:res->rtyp=POLY_CMD;
1307           if (d->r==NULL) goto no_ring;
1308           res->data=(char*)ssiReadPoly(d);
1309           break;
1310    case 7:res->rtyp=IDEAL_CMD;
1311           if (d->r==NULL) goto no_ring;
1312           res->data=(char*)ssiReadIdeal(d);
1313           break;
1314    case 8:res->rtyp=MATRIX_CMD;
1315           if (d->r==NULL) goto no_ring;
1316           res->data=(char*)ssiReadMatrix(d);
1317           break;
1318    case 9:res->rtyp=VECTOR_CMD;
1319           if (d->r==NULL) goto no_ring;
1320           res->data=(char*)ssiReadPoly(d);
1321           break;
1322    case 10:res->rtyp=MODUL_CMD;
1323           if (d->r==NULL) goto no_ring;
1324           {
1325             int rk=s_readint(d->f_read);
1326             ideal M=ssiReadIdeal(d);
1327             M->rank=rk;
1328             res->data=(char*)M;
1329           }
1330           break;
1331    case 11:
1332           {
1333             res->rtyp=COMMAND;
1334             res->data=ssiReadCommand(l);
1335             int nok=res->Eval();
1336             if (nok) WerrorS("error in eval");
1337             break;
1338           }
1339    case 12: /*DEF_CMD*/
1340           {
1341             res->rtyp=0;
1342             res->name=(char *)ssiReadString(d);
1343             int nok=res->Eval();
1344             if (nok) WerrorS("error in name lookup");
1345             break;
1346           }
1347    case 13: res->rtyp=PROC_CMD;
1348             res->data=ssiReadProc(d);
1349             break;
1350    case 14: res->rtyp=LIST_CMD;
1351             res->data=ssiReadList(l);
1352             break;
1353    case 16: res->rtyp=NONE; res->data=NULL;
1354             break;
1355    case 17: res->rtyp=INTVEC_CMD;
1356             res->data=ssiReadIntvec(d);
1357             break;
1358    case 18: res->rtyp=INTMAT_CMD;
1359             res->data=ssiReadIntmat(d);
1360             break;
1361    case 19: res->rtyp=BIGINTMAT_CMD;
1362             res->data=ssiReadBigintmat(d);
1363             break;
1364    case 20: ssiReadBlackbox(res,l);
1365             break;
1366    case 21: ssiReadAttrib(res,l);
1367             break;
1368    // ------------
1369    case 98: // version
1370             {
1371                int n98_v,n98_m;
1372                BITSET n98_o1,n98_o2;
1373                n98_v=s_readint(d->f_read);
1374                n98_m=s_readint(d->f_read);
1375                n98_o1=s_readint(d->f_read);
1376                n98_o2=s_readint(d->f_read);
1377                if ((n98_v!=SSI_VERSION) ||(n98_m!=MAX_TOK))
1378                {
1379                  Print("incompatible versions of ssi: %d/%d vs %d/%d\n",
1380                                  SSI_VERSION,MAX_TOK,n98_v,n98_m);
1381                }
1382                #ifndef SING_NDEBUG
1383                if (TEST_OPT_DEBUG)
1384                  Print("// opening ssi-%d, MAX_TOK=%d\n",n98_v,n98_m);
1385                #endif
1386                si_opt_1=n98_o1;
1387                si_opt_2=n98_o2;
1388                omFreeBin(res,sleftv_bin);
1389                return ssiRead1(l);
1390             }
1391    case 99: omFreeBin(res,sleftv_bin); ssiClose(l); m2_end(0);
1392    case 0: if (s_iseof(d->f_read))
1393            {
1394              ssiClose(l);
1395            }
1396            res->rtyp=DEF_CMD;
1397            break;
1398    default: Werror("not implemented (t:%d)",t);
1399             omFreeBin(res,sleftv_bin);
1400             res=NULL;
1401             break;
1402  }
1403  // if currRing is required for the result, but lost
1404  // define "ssiRing%d" as currRing:
1405  if ((d->r!=NULL)
1406  && (currRing!=d->r)
1407  && (res->RingDependend()))
1408  {
1409    if(ssiSetCurrRing(d->r)) { d->r=currRing; d->r->ref++; }
1410  }
1411  return res;
1412no_ring: WerrorS("no ring");
1413  omFreeBin(res,sleftv_bin);
1414  return NULL;
1415}
1416//**************************************************************************/
1417BOOLEAN ssiSetRing(si_link l, ring r, BOOLEAN send)
1418{
1419  if(SI_LINK_W_OPEN_P(l)==0)
1420     if (slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL)) return TRUE;
1421  ssiInfo *d = (ssiInfo *)l->data;
1422  if (d->r!=r)
1423  {
1424    if (send)
1425    {
1426      fputs("15 ",d->f_write);
1427      ssiWriteRing(d,r);
1428    }
1429    d->r=r;
1430  }
1431  if (currRing!=r) rChangeCurrRing(r);
1432  return FALSE;
1433}
1434//**************************************************************************/
1435
1436BOOLEAN ssiWrite(si_link l, leftv data)
1437{
1438  if(SI_LINK_W_OPEN_P(l)==0)
1439     if (slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL)) return TRUE;
1440  ssiInfo *d = (ssiInfo *)l->data;
1441  d->level++;
1442  //FILE *fich=d->f;
1443  while (data!=NULL)
1444  {
1445    int tt=data->Typ();
1446    void *dd=data->Data();
1447    attr *aa=data->Attribute();
1448    BOOLEAN with_attr=FALSE;
1449    if (((*aa)!=NULL)||(data->flag!=0))
1450    {
1451      attr a=*aa;
1452      int n=0;
1453      while(a!=NULL) { n++; a=a->next;}
1454      fprintf(d->f_write,"21 %d %d ",data->flag,n);
1455      a=*aa;
1456    }
1457    if ((dd==NULL) && (data->name!=NULL) && (tt==0)) tt=DEF_CMD;
1458      // return pure undefined names as def
1459
1460    switch(tt /*data->Typ()*/)
1461    {
1462          case 0: /*error*/
1463          case NONE/* nothing*/:fputs("16 ",d->f_write);
1464                          break;
1465          case STRING_CMD: fputs("2 ",d->f_write);
1466                           ssiWriteString(d,(char *)dd);
1467                           break;
1468          case INT_CMD: fputs("1 ",d->f_write);
1469                        ssiWriteInt(d,(int)(long)dd);
1470                        break;
1471          case BIGINT_CMD:fputs("4 ",d->f_write);
1472                        ssiWriteBigInt(d,(number)dd);
1473                        break;
1474          case NUMBER_CMD:
1475                          if (d->r!=currRing)
1476                          {
1477                            fputs("15 ",d->f_write);
1478                            ssiWriteRing(d,currRing);
1479                            if (d->level<=1) fputc('\n',d->f_write);
1480                          }
1481                          fputs("3 ",d->f_write);
1482                          ssiWriteNumber(d,(number)dd);
1483                        break;
1484          case RING_CMD:fputs("5 ",d->f_write);
1485                        ssiWriteRing(d,(ring)dd);
1486                        break;
1487          case POLY_CMD:
1488          case VECTOR_CMD:
1489                        if (d->r!=currRing)
1490                        {
1491                          fputs("15 ",d->f_write);
1492                          ssiWriteRing(d,currRing);
1493                          if (d->level<=1) fputc('\n',d->f_write);
1494                        }
1495                        if(tt==POLY_CMD) fputs("6 ",d->f_write);
1496                        else             fputs("9 ",d->f_write);
1497                        ssiWritePoly(d,tt,(poly)dd);
1498                        break;
1499          case IDEAL_CMD:
1500          case MODUL_CMD:
1501          case MATRIX_CMD:
1502                        if (d->r!=currRing)
1503                        {
1504                          fputs("15 ",d->f_write);
1505                          ssiWriteRing(d,currRing);
1506                          if (d->level<=1) fputc('\n',d->f_write);
1507                        }
1508                        if(tt==IDEAL_CMD)       fputs("7 ",d->f_write);
1509                        else if(tt==MATRIX_CMD) fputs("8 ",d->f_write);
1510                        else
1511                        {
1512                          ideal M=(ideal)dd;
1513                          fprintf(d->f_write,"10 %d ",(int)M->rank);
1514                        }
1515                        ssiWriteIdeal(d,tt,(ideal)dd);
1516                        break;
1517          case COMMAND:
1518                   fputs("11 ",d->f_write);
1519                   ssiWriteCommand(l,(command)dd);
1520                   break;
1521          case DEF_CMD: /* not evaluated stuff in quotes */
1522                   fputs("12 ",d->f_write);
1523                   ssiWriteString(d,data->Name());
1524                   break;
1525          case PROC_CMD:
1526                   fputs("13 ",d->f_write);
1527                   ssiWriteProc(d,(procinfov)dd);
1528                   break;
1529          case LIST_CMD:
1530                   fputs("14 ",d->f_write);
1531                   ssiWriteList(l,(lists)dd);
1532                   break;
1533          case INTVEC_CMD:
1534                   fputs("17 ",d->f_write);
1535                   ssiWriteIntvec(d,(intvec *)dd);
1536                   break;
1537          case INTMAT_CMD:
1538                   fputs("18 ",d->f_write);
1539                   ssiWriteIntmat(d,(intvec *)dd);
1540                   break;
1541          case BIGINTMAT_CMD:
1542                   fputs("19 ",d->f_write);
1543                   ssiWriteBigintmat(d,(bigintmat *)dd);
1544                   break;
1545          default:
1546            if (tt>MAX_TOK)
1547            {
1548              blackbox *b=getBlackboxStuff(tt);
1549              fputs("20 ",d->f_write);
1550              b->blackbox_serialize(b,dd,l);
1551            }
1552            else
1553            {
1554              Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
1555              d->level=0;
1556              return TRUE;
1557            }
1558            break;
1559    }
1560    if (d->level<=1) { fputc('\n',d->f_write); fflush(d->f_write); }
1561    data=data->next;
1562  }
1563  d->level--;
1564  return FALSE;
1565}
1566
1567BOOLEAN ssiGetDump(si_link l);
1568BOOLEAN ssiDump(si_link l);
1569
1570si_link_extension slInitSsiExtension(si_link_extension s)
1571{
1572  s->Open=ssiOpen;
1573  s->Close=ssiClose;
1574  s->Kill=ssiClose;
1575  s->Read=ssiRead1;
1576  s->Read2=(slRead2Proc)NULL;
1577  s->Write=ssiWrite;
1578  s->Dump=ssiDump;
1579  s->GetDump=ssiGetDump;
1580
1581  s->Status=slStatusSsi;
1582  s->SetRing=ssiSetRing;
1583  s->type="ssi";
1584  return s;
1585}
1586
1587const char* slStatusSsi(si_link l, const char* request)
1588{
1589  ssiInfo *d=(ssiInfo*)l->data;
1590  if (d==NULL) return "not open";
1591  if (((strcmp(l->mode,"fork")==0)
1592  ||(strcmp(l->mode,"tcp")==0)
1593  ||(strcmp(l->mode,"connect")==0))
1594  && (strcmp(request, "read") == 0))
1595  {
1596    fd_set  mask;
1597    struct timeval wt;
1598    if (s_isready(d->f_read)) return "ready";
1599    loop
1600    {
1601      /* Don't block. Return socket status immediately. */
1602      wt.tv_sec  = 0;
1603      wt.tv_usec = 0;
1604
1605      FD_ZERO(&mask);
1606      FD_SET(d->fd_read, &mask);
1607      //Print("test fd %d\n",d->fd_read);
1608    /* check with select: chars waiting: no -> not ready */
1609      switch (si_select(d->fd_read+1, &mask, NULL, NULL, &wt))
1610      {
1611        case 0: /* not ready */ return "not ready";
1612        case -1: /*error*/      return "error";
1613        case 1: /*ready ? */    break;
1614      }
1615    /* yes: read 1 char*/
1616    /* if \n, check again with select else ungetc(c), ready*/
1617      int c=s_getc(d->f_read);
1618      //Print("try c=%d\n",c);
1619      if (c== -1) return "eof"; /* eof or error */
1620      else if (isdigit(c))
1621      { s_ungetc(c,d->f_read); return "ready"; }
1622      else if (c>' ')
1623      {
1624        Werror("unknown char in ssiLink(%d)",c);
1625        return "error";
1626      }
1627      /* else: next char */
1628    }
1629  }
1630  else if (strcmp(request, "read") == 0)
1631  {
1632    if (SI_LINK_R_OPEN_P(l) && (!s_iseof(d->f_read)) && (s_isready(d->f_read))) return "ready";
1633    else return "not ready";
1634  }
1635  else if (strcmp(request, "write") == 0)
1636  {
1637    if (SI_LINK_W_OPEN_P(l)) return "ready";
1638    else return "not ready";
1639  }
1640  else return "unknown status request";
1641}
1642
1643int slStatusSsiL(lists L, int timeout)
1644{
1645// input: L: a list with links of type
1646//           ssi-connect, ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch.
1647//           Note: Not every entry in L must be set.
1648//        timeout: timeout for select in micro-seconds
1649//           or -1 for infinity
1650//           or 0 for polling
1651// returns: ERROR (via Werror): L has wrong elements or link not open
1652//           -2: select returns an error
1653//           -1: the read state of all links is eof
1654//           0:  timeout (or polling): none ready,
1655//           i>0: (at least) L[i] is ready
1656  si_link l;
1657  ssiInfo *d;
1658  int d_fd;
1659  fd_set  mask, fdmask;
1660  FD_ZERO(&fdmask);
1661  FD_ZERO(&mask);
1662  int max_fd=0; /* 1 + max fd in fd_set */
1663
1664  /* timeout */
1665  struct timeval wt;
1666  struct timeval *wt_ptr=&wt;
1667  int startingtime = getRTimer()/TIMER_RESOLUTION;  // in seconds
1668  if (timeout== -1)
1669  {
1670    wt_ptr=NULL;
1671  }
1672  else
1673  {
1674    wt.tv_sec  = timeout / 1000000;
1675    wt.tv_usec = timeout % 1000000;
1676  }
1677
1678  /* auxiliary variables */
1679  int i;
1680  int j;
1681  int k;
1682  int s;
1683  char fdmaskempty;
1684
1685  /* check the links and fill in fdmask */
1686  /* check ssi links for ungetc_buf */
1687  for(i=L->nr; i>=0; i--)
1688  {
1689    if (L->m[i].Typ()!=DEF_CMD)
1690    {
1691      if (L->m[i].Typ()!=LINK_CMD)
1692      { WerrorS("all elements must be of type link"); return -2;}
1693      l=(si_link)L->m[i].Data();
1694      if(SI_LINK_OPEN_P(l)==0)
1695      { WerrorS("all links must be open"); return -2;}
1696      if (((strcmp(l->m->type,"ssi")!=0) && (strcmp(l->m->type,"MPtcp")!=0))
1697      || ((strcmp(l->mode,"fork")!=0) && (strcmp(l->mode,"tcp")!=0)
1698        && (strcmp(l->mode,"launch")!=0) && (strcmp(l->mode,"connect")!=0)))
1699      {
1700        WerrorS("all links must be of type ssi:fork, ssi:tcp, ssi:connect");
1701        return -2;
1702      }
1703      if (strcmp(l->m->type,"ssi")==0)
1704      {
1705        d=(ssiInfo*)l->data;
1706        d_fd=d->fd_read;
1707        if (!s_isready(d->f_read))
1708        {
1709          FD_SET(d_fd, &fdmask);
1710          if (d_fd > max_fd) max_fd=d_fd;
1711        }
1712        else
1713          return i+1;
1714      }
1715      else
1716      {
1717        Werror("wrong link type >>%s<<",l->m->type);
1718        return -2;
1719      }
1720    }
1721  }
1722  max_fd++;
1723
1724do_select:
1725  /* copy fdmask to mask */
1726  FD_ZERO(&mask);
1727  for(k = 0; k < max_fd; k++)
1728  {
1729    if(FD_ISSET(k, &fdmask))
1730    {
1731      FD_SET(k, &mask);
1732    }
1733  }
1734
1735  /* check with select: chars waiting: no -> not ready */
1736  s = si_select(max_fd, &mask, NULL, NULL, wt_ptr);
1737  if (s==-1)
1738  {
1739    WerrorS("error in select call");
1740    return -2; /*error*/
1741  }
1742  if (s==0)
1743  {
1744    return 0; /*poll: not ready */
1745  }
1746  else /* s>0, at least one ready  (the number of fd which are ready is s)*/
1747  {
1748    j=0;
1749    while (j<=max_fd) { if (FD_ISSET(j,&mask)) break; j++; }
1750    for(i=L->nr; i>=0; i--)
1751    {
1752      if (L->m[i].rtyp==LINK_CMD)
1753      {
1754        l=(si_link)L->m[i].Data();
1755        if (strcmp(l->m->type,"ssi")==0)
1756        {
1757          d=(ssiInfo*)l->data;
1758          d_fd=d->fd_read;
1759          if(j==d_fd) break;
1760        }
1761        else
1762        {
1763          Werror("wrong link type >>%s<<",l->m->type);
1764          return -2;
1765        }
1766      }
1767    }
1768    // only ssi links:
1769    loop
1770    {
1771      /* yes: read 1 char*/
1772      /* if \n, check again with select else ungetc(c), ready*/
1773      /* setting: d: current ssiInfo, j current fd, i current entry in L*/
1774      int c=s_getc(d->f_read);
1775      //Print("try c=%d\n",c);
1776      if (c== -1) /* eof */
1777      {
1778        FD_CLR(j,&fdmask);
1779        fdmaskempty = 1;
1780        for(k = 0; k < max_fd; k++)
1781        {
1782          if(FD_ISSET(k, &fdmask))
1783          {
1784            fdmaskempty = 0;
1785            break;
1786          }
1787        }
1788        if(fdmaskempty)
1789        {
1790          return -1;
1791        }
1792        if(timeout != -1)
1793        {
1794          timeout = si_max(0,
1795             timeout - 1000000*(getRTimer()/TIMER_RESOLUTION - startingtime));
1796          wt.tv_sec  = timeout / 1000000;
1797          wt.tv_usec = (timeout % 1000000);
1798        }
1799        goto do_select;
1800      }
1801
1802      else if (isdigit(c))
1803      { s_ungetc(c,d->f_read); return i+1; }
1804      else if (c>' ')
1805      {
1806        Werror("unknown char in ssiLink(%d)",c);
1807        return -2;
1808      }
1809      /* else: next char */
1810      goto do_select;
1811    }
1812  }
1813}
1814
1815int ssiBatch(const char *host, const char * port)
1816/* return 0 on success, >0 else*/
1817{
1818  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
1819  char *buf=(char*)omAlloc(256);
1820  sprintf(buf,"ssi:connect %s:%s",host,port);
1821  slInit(l, buf);
1822  omFreeSize(buf,256);
1823  if (slOpen(l,SI_LINK_OPEN,NULL)) return 1;
1824  SI_LINK_SET_RW_OPEN_P(l);
1825
1826  idhdl id = enterid(omStrDup("link_ll"), 0, LINK_CMD, &IDROOT, FALSE);
1827  IDLINK(id) = l;
1828
1829  loop
1830  {
1831    leftv h=ssiRead1(l); /*contains an exit.... */
1832    if (feErrors != NULL && *feErrors != '\0')
1833    {
1834      // handle errors:
1835      PrintS(feErrors); /* currently quite simple */
1836      *feErrors = '\0';
1837    }
1838    ssiWrite(l,h);
1839    h->CleanUp();
1840    omFreeBin(h, sleftv_bin);
1841  }
1842  /* never reached*/
1843  exit(0);
1844}
1845
1846static int ssiReserved_P=0;
1847static int ssiReserved_sockfd;
1848static  struct sockaddr_in ssiResverd_serv_addr;
1849static int  ssiReserved_Clients;
1850int ssiReservePort(int clients)
1851{
1852  if (ssiReserved_P!=0)
1853  {
1854    WerrorS("ERROR already a reverved port requested");
1855    return 0;
1856  }
1857  int portno;
1858  ssiReserved_sockfd = socket(AF_INET, SOCK_STREAM, 0);
1859  if(ssiReserved_sockfd < 0)
1860  {
1861    WerrorS("ERROR opening socket");
1862    return 0;
1863  }
1864  memset((char *) &ssiResverd_serv_addr,0, sizeof(ssiResverd_serv_addr));
1865  portno = 1025;
1866  ssiResverd_serv_addr.sin_family = AF_INET;
1867  ssiResverd_serv_addr.sin_addr.s_addr = INADDR_ANY;
1868  do
1869  {
1870    portno++;
1871    ssiResverd_serv_addr.sin_port = htons(portno);
1872    if(portno > 50000)
1873    {
1874      WerrorS("ERROR on binding (no free port available?)");
1875      return 0;
1876    }
1877  }
1878  while(bind(ssiReserved_sockfd, (struct sockaddr *) &ssiResverd_serv_addr, sizeof(ssiResverd_serv_addr)) < 0);
1879  ssiReserved_P=portno;
1880  listen(ssiReserved_sockfd,clients);
1881  ssiReserved_Clients=clients;
1882  return portno;
1883}
1884
1885extern si_link_extension si_link_root;
1886si_link ssiCommandLink()
1887{
1888  if (ssiReserved_P==0)
1889  {
1890    WerrorS("ERROR no reverved port requested");
1891    return NULL;
1892  }
1893  struct sockaddr_in cli_addr;
1894  int clilen = sizeof(cli_addr);
1895  int newsockfd = si_accept(ssiReserved_sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
1896  if(newsockfd < 0)
1897  {
1898    Werror("ERROR on accept (errno=%d)",errno);
1899    return NULL;
1900  }
1901  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
1902  si_link_extension s = si_link_root;
1903  si_link_extension prev = s;
1904  while (strcmp(s->type, "ssi") != 0)
1905  {
1906    if (s->next == NULL)
1907    {
1908      prev = s;
1909      s = NULL;
1910      break;
1911    }
1912    else
1913    {
1914      s = s->next;
1915    }
1916  }
1917  if (s != NULL)
1918    l->m = s;
1919  else
1920  {
1921    si_link_extension ns = (si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
1922    prev->next=slInitSsiExtension(ns);
1923    l->m = prev->next;
1924  }
1925  l->name=omStrDup("");
1926  l->mode=omStrDup("tcp");
1927  l->ref=1;
1928  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
1929  l->data=d;
1930  d->fd_read = newsockfd;
1931  d->fd_write = newsockfd;
1932  d->f_read = s_open(newsockfd);
1933  d->f_write = fdopen(newsockfd, "w");
1934  SI_LINK_SET_RW_OPEN_P(l);
1935  ssiReserved_Clients--;
1936  if (ssiReserved_Clients<=0)
1937  {
1938    ssiReserved_P=0;
1939    si_close(ssiReserved_sockfd);
1940  }
1941  return l;
1942}
1943/*---------------------------------------------------------------------*/
1944/**
1945 * @brief additional default signal handler
1946
1947  // some newer Linux version cannot have SIG_IGN for SIGCHLD,
1948  // so use this nice routine here:
1949  //  SuSe 9.x reports -1 always
1950  //  Redhat 9.x/FC x reports sometimes -1
1951  // see also: hpux_system
1952  // also needed by getrusage (timer etc.)
1953
1954 @param[in] sig
1955**/
1956/*---------------------------------------------------------------------*/
1957void sig_chld_hdl(int)
1958{
1959  pid_t kidpid;
1960  int status;
1961
1962  loop
1963  {
1964    kidpid = si_waitpid(-1, &status, WNOHANG);
1965    if (kidpid==-1)
1966    {
1967      /* continue on interruption (EINTR): */
1968      if (errno == EINTR) continue;
1969      /* break on anything else (EINVAL or ECHILD according to manpage): */
1970      break;
1971    }
1972    else if (kidpid==0) break; /* no more children to process, so break */
1973
1974    //printf("Child %ld terminated\n", kidpid);
1975    link_list hh=ssiToBeClosed;
1976    while((hh!=NULL)&&(ssiToBeClosed_inactive))
1977    {
1978      if((hh->l!=NULL) && (hh->l->m->Open==ssiOpen))
1979      {
1980        ssiInfo *d = (ssiInfo *)hh->l->data;
1981        if(d->pid==kidpid)
1982        {
1983          if(ssiToBeClosed_inactive)
1984          {
1985            ssiToBeClosed_inactive=FALSE;
1986            slClose(hh->l);
1987            ssiToBeClosed_inactive=TRUE;
1988            break;
1989          }
1990          else break;
1991        }
1992        else hh=(link_list)hh->next;
1993      }
1994      else hh=(link_list)hh->next;
1995    }
1996  }
1997}
1998
1999static BOOLEAN DumpSsiIdhdl(si_link l, idhdl h)
2000{
2001  int type_id = IDTYP(h);
2002
2003  // C-proc not to be dumped, also LIB-proc not
2004  if (type_id == PROC_CMD)
2005  {
2006    if (IDPROC(h)->language == LANG_C) return FALSE;
2007    if (IDPROC(h)->libname != NULL) return FALSE;
2008  }
2009  // do not dump links
2010  if (type_id == LINK_CMD) return FALSE;
2011
2012  // do not dump ssi internal rings: ssiRing*
2013  if ((type_id == RING_CMD) && (strncmp(IDID(h),"ssiRing",7)==0))
2014    return FALSE;
2015
2016  command D=(command)omAlloc0(sizeof(*D));
2017  sleftv tmp;
2018  memset(&tmp,0,sizeof(tmp));
2019  tmp.rtyp=COMMAND;
2020  tmp.data=D;
2021
2022  if (type_id == PACKAGE_CMD)
2023  {
2024    // do not dump Top, Standard
2025    if ((strcmp(IDID(h), "Top") == 0)
2026    || (strcmp(IDID(h), "Standard") == 0))
2027    {
2028      omFreeSize(D,sizeof(*D));
2029      return FALSE;
2030    }
2031    package p=(package)IDDATA(h);
2032    // dump Singular-packages as LIB("...");
2033    if (p->language==LANG_SINGULAR)
2034    {
2035      D->op=LOAD_CMD;
2036      D->argc=2;
2037      D->arg1.rtyp=STRING_CMD;
2038      D->arg1.data=p->libname;
2039      D->arg2.rtyp=STRING_CMD;
2040      D->arg2.data=(char*)"with";
2041      ssiWrite(l,&tmp);
2042      omFreeSize(D,sizeof(*D));
2043      return FALSE;
2044    }
2045    // dump Singular-packages as load("...");
2046    else if (p->language==LANG_C)
2047    {
2048      D->op=LOAD_CMD;
2049      D->argc=1;
2050      D->arg1.rtyp=STRING_CMD;
2051      D->arg1.data=p->libname;
2052      ssiWrite(l,&tmp);
2053      omFreeSize(D,sizeof(*D));
2054      return FALSE;
2055    }
2056  }
2057
2058  // put type and name
2059  //Print("generic dump:%s,%s\n",IDID(h),Tok2Cmdname(IDTYP(h)));
2060  D->op='=';
2061  D->argc=2;
2062  D->arg1.rtyp=DEF_CMD;
2063  D->arg1.name=IDID(h);
2064  D->arg2.rtyp=IDTYP(h);
2065  D->arg2.data=IDDATA(h);
2066  ssiWrite(l,&tmp);
2067  omFreeSize(D,sizeof(*D));
2068  return FALSE;
2069}
2070static BOOLEAN ssiDumpIter(si_link l, idhdl h)
2071{
2072  if (h == NULL) return FALSE;
2073
2074  if (ssiDumpIter(l, IDNEXT(h))) return TRUE;
2075
2076  // need to set the ring before writing it, otherwise we get in
2077  // trouble with minpoly
2078  if (IDTYP(h) == RING_CMD)
2079    rSetHdl(h);
2080
2081  if (DumpSsiIdhdl(l, h)) return TRUE;
2082
2083  // do not dump ssi internal rings: ssiRing*
2084  // but dump objects of all other rings
2085  if ((IDTYP(h) == RING_CMD)
2086  && (strncmp(IDID(h),"ssiRing",7)!=0))
2087    return ssiDumpIter(l, IDRING(h)->idroot);
2088  else
2089    return FALSE;
2090}
2091BOOLEAN ssiDump(si_link l)
2092{
2093  idhdl h = IDROOT, rh = currRingHdl;
2094  BOOLEAN status = ssiDumpIter(l, h);
2095
2096  //if (! status ) status = DumpAsciiMaps(fd, h, NULL);
2097
2098  if (currRingHdl != rh) rSetHdl(rh);
2099  //fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
2100
2101  return status;
2102}
2103BOOLEAN ssiGetDump(si_link l)
2104{
2105  ssiInfo *d=(ssiInfo*)l->data;
2106  loop
2107  {
2108    if (!SI_LINK_OPEN_P(l)) break;
2109    if (s_iseof(d->f_read)) break;
2110    leftv h=ssiRead1(l); /*contains an exit.... */
2111    if (feErrors != NULL && *feErrors != '\0')
2112    {
2113      // handle errors:
2114      PrintS(feErrors); /* currently quite simple */
2115      return TRUE;
2116      *feErrors = '\0';
2117    }
2118    h->CleanUp();
2119    omFreeBin(h, sleftv_bin);
2120  }
2121  return FALSE;
2122}
2123// ----------------------------------------------------------------
2124// format
2125// 1 int %d
2126// 2 string <len> %s
2127// 3 number
2128// 4 bigint 4 %d or 3 <mpz_t>
2129// 5 ring
2130// 6 poly
2131// 7 ideal
2132// 8 matrix
2133// 9 vector
2134// 10 module
2135// 11 command
2136// 12 def <len> %s
2137// 13 proc <len> %s
2138// 14 list %d <elem1> ....
2139// 15 setring .......
2140// 16 nothing
2141// 17 intvec <len> ...
2142// 18 intmat
2143// 19 bigintmat <r> <c> ...
2144// 20 blackbox <name> 1 <len> ...
2145// 21 attrib <bit-attrib> <len> <a-name1> <val1>... <data>
2146//
2147// 98: verify version: <ssi-version> <MAX_TOK> <OPT1> <OPT2>
2148// 99: quit Singular
Note: See TracBrowser for help on using the repository browser.