source: git/Singular/links/ssiLink.cc @ 9ae5a3

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