source: git/Singular/links/ssiLink.cc @ 2ffd25

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