My Project
Loading...
Searching...
No Matches
ssiLink.cc
Go to the documentation of this file.
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 "misc/intvec.h"
13#include "misc/options.h"
14
15#include "reporter/si_signals.h"
16#include "reporter/s_buff.h"
17
18#include "coeffs/bigintmat.h"
19#include "coeffs/longrat.h"
20
24#include "polys/simpleideals.h"
25#include "polys/matpol.h"
26
30
31#include "Singular/tok.h"
32#include "Singular/ipid.h"
33#include "Singular/ipshell.h"
34#include "Singular/subexpr.h"
36#include "Singular/cntrlc.h"
37#include "Singular/feOpt.h"
38#include "Singular/lists.h"
39#include "Singular/blackbox.h"
41
42#ifdef HAVE_SIMPLEIPC
44#endif
45
46#include <errno.h>
47#include <sys/types.h> /* for portability */
48#include <ctype.h> /*for isdigit*/
49#include <netdb.h>
50#include <netinet/in.h> /* for htons etc.*/
51
52#define SSI_VERSION 15
53// 5->6: changed newstruct representation
54// 6->7: attributes
55// 7->8: qring
56// 8->9: module: added rank
57// 9->10: tokens in grammar.h/tok.h reorganized
58// 10->11: extended ring descr. for named coeffs (not in used until 4.1)
59// 11->12: add rank to ideal/module, add smatrix
60// 12->13: NC rings
61// 13->14: ring references
62// 14->15: bigintvec, prune_map, mres_map
63
66
67// forward declarations:
68static void ssiWriteIdeal(const ssiInfo *d, int typ,const ideal I);
69static void ssiWritePoly_R(const ssiInfo *d, int typ, poly p, const ring r);
70static void ssiWriteIdeal_R(const ssiInfo *d, int typ,const ideal I, const ring r);
71static poly ssiReadPoly_R(const ssiInfo *D, const ring r);
72static ideal ssiReadIdeal_R(const ssiInfo *d,const ring r);
73
74// the helper functions:
75static BOOLEAN ssiSetCurrRing(const ring r) /* returned: not accepted */
76{
77 // if (currRing!=NULL)
78 // Print("need to change the ring, currRing:%s, switch to: ssiRing%d\n",IDID(currRingHdl),nr);
79 // else
80 // Print("no ring, switch to ssiRing%d\n",nr);
81 if (r==currRing)
82 {
83 rIncRefCnt(r);
85 return TRUE;
86 }
87 else if ((currRing==NULL) || (!rEqual(r,currRing,1)))
88 {
89 char name[20];
90 int nr=0;
91 idhdl h=NULL;
92 loop
93 {
94 snprintf(name,20,"ssiRing%d",nr); nr++;
95 h=IDROOT->get(name, 0);
96 if (h==NULL)
97 {
100 r->ref=2;/*ref==2: d->r and h */
101 break;
102 }
103 else if ((IDTYP(h)==RING_CMD)
104 && (rEqual(r,IDRING(h),1)))
105 {
107 break;
108 }
109 }
110 rSetHdl(h);
111 return FALSE;
112 }
113 else
114 {
115 rKill(r);
117 return TRUE;
118 }
119}
120static void ssiCheckCurrRing(const ring r)
121{
122 if ((r!=currRing)
123 ||(currRingHdl==NULL)
124 ||(IDRING(currRingHdl)!=r))
125 {
126 char name[20];
127 int nr=0;
128 idhdl h=NULL;
129 loop
130 {
131 snprintf(name,20,"ssiRing%d",nr); nr++;
132 h=IDROOT->get(name, 0);
133 if (h==NULL)
134 {
136 IDRING(h)=rIncRefCnt(r);
137 r->ref=2;/*ref==2: d->r and h */
138 break;
139 }
140 else if ((IDTYP(h)==RING_CMD)
141 && (rEqual(r,IDRING(h),1)))
142 {
143 break;
144 }
145 }
146 rSetHdl(h);
147 }
148 assume((currRing==r) || rEqual(r,currRing));
149}
150// the implementation of the functions:
151static void ssiWriteInt(const ssiInfo *d,const int i)
152{
153 fprintf(d->f_write,"%d ",i);
154 //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
155}
156
157static void ssiWriteString(const ssiInfo *d,const char *s)
158{
159 fprintf(d->f_write,"%d %s ",(int)strlen(s),s);
160 //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
161}
162
163static void ssiWriteBigInt(const ssiInfo *d, const number n)
164{
166}
167
168static void ssiWriteNumber_CF(const ssiInfo *d, const number n, const coeffs cf)
169{
170 // syntax is as follows:
171 // case 1 Z/p: 3 <int>
172 // case 2 Q: 3 4 <int>
173 // or 3 0 <mpz_t nominator> <mpz_t denominator>
174 // or 3 1 dto.
175 // or 3 3 <mpz_t nominator>
176 // or 3 5 <mpz_t raw nom.> <mpz_t raw denom.>
177 // or 3 6 <mpz_t raw nom.> <mpz_t raw denom.>
178 // or 3 8 <mpz_t raw nom.>
180 {
181 fraction f=(fraction)n;
182 ssiWritePoly_R(d,POLY_CMD,NUM(f),cf->extRing);
183 ssiWritePoly_R(d,POLY_CMD,DEN(f),cf->extRing);
184 }
185 else if (getCoeffType(cf)==n_algExt)
186 {
187 ssiWritePoly_R(d,POLY_CMD,(poly)n,cf->extRing);
188 }
189 else if (cf->cfWriteFd!=NULL)
190 {
191 n_WriteFd(n,d,cf);
192 }
193 else WerrorS("coeff field not implemented");
194}
195
196static void ssiWriteNumber(const ssiInfo *d, const number n)
197{
198 ssiWriteNumber_CF(d,n,d->r->cf);
199}
200
201static void ssiWriteRing_R(ssiInfo *d,const ring r)
202{
203 /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
204 /* ch=-1: transext, coeff ring follows */
205 /* ch=-2: algext, coeff ring and minpoly follows */
206 /* ch=-3: cf name follows */
207 /* ch=-4: NULL*/
208 /* ch=-5: reference <int> */
209 /* ch=-6: new reference <int> <ring> */
210 if (r!=NULL)
211 {
212 for(int i=0;i<SI_RING_CACHE;i++)
213 {
214 if (d->rings[i]==r)
215 {
216 fprintf(d->f_write,"-5 %d ",i);
217 return;
218 }
219 }
220 for(int i=0;i<SI_RING_CACHE;i++)
221 {
222 if (d->rings[i]==NULL)
223 {
224 d->rings[i]=rIncRefCnt(r);
225 fprintf(d->f_write,"-6 %d ",i);
226 break;
227 }
228 }
229 if (rField_is_Q(r) || rField_is_Zp(r))
230 fprintf(d->f_write,"%d %d ",n_GetChar(r->cf),r->N);
231 else if (rFieldType(r)==n_transExt)
232 fprintf(d->f_write,"-1 %d ",r->N);
233 else if (rFieldType(r)==n_algExt)
234 fprintf(d->f_write,"-2 %d ",r->N);
235 else /*dummy*/
236 {
237 fprintf(d->f_write,"-3 %d ",r->N);
238 ssiWriteString(d,nCoeffName(r->cf));
239 }
240
241 int i;
242 for(i=0;i<r->N;i++)
243 {
244 fprintf(d->f_write,"%d %s ",(int)strlen(r->names[i]),r->names[i]);
245 }
246 /* number of orderings:*/
247 i=0;
248 // remember dummy ring: everything 0:
249 if (r->order!=NULL) while (r->order[i]!=0) i++;
250 fprintf(d->f_write,"%d ",i);
251 /* each ordering block: */
252 i=0;
253 if (r->order!=NULL) while(r->order[i]!=0)
254 {
255 fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
256 switch(r->order[i])
257 {
258 case ringorder_a:
259 case ringorder_wp:
260 case ringorder_Wp:
261 case ringorder_ws:
262 case ringorder_Ws:
263 case ringorder_aa:
264 {
265 int s=r->block1[i]-r->block0[i]+1; // #vars
266 for(int ii=0;ii<s;ii++)
267 fprintf(d->f_write,"%d ",r->wvhdl[i][ii]);
268 }
269 break;
270 case ringorder_M:
271 {
272 int s=r->block1[i]-r->block0[i]+1; // #vars
273 for(int ii=0;ii<s*s;ii++)
274 {
275 fprintf(d->f_write,"%d ",r->wvhdl[i][ii]);
276 }
277 }
278 break;
279
280 case ringorder_a64:
281 case ringorder_L:
282 case ringorder_IS:
283 Werror("ring oder not implemented for ssi:%d",r->order[i]);
284 break;
285
286 default: break;
287 }
288 i++;
289 }
290 if ((rFieldType(r)==n_transExt)
291 || (rFieldType(r)==n_algExt))
292 {
293 ssiWriteRing_R(d,r->cf->extRing); /* includes alg.ext if rFieldType(r)==n_algExt */
294 }
295 /* Q-ideal :*/
296 if (r->qideal!=NULL)
297 {
298 ssiWriteIdeal_R(d,IDEAL_CMD,r->qideal,r);
299 }
300 else
301 {
302 fputs("0 ",d->f_write/*ideal with 0 entries */);
303 }
304 }
305 else /* dummy ring r==NULL*/
306 {
307 fputs("0 0 0 0 "/*,r->ch,r->N, blocks, q-ideal*/,d->f_write);
308 }
309 if (rIsLPRing(r)) // cannot be combined with 23 2
310 {
311 fprintf(d->f_write,"23 1 %d %d ",SI_LOG2(r->bitmask),r->isLPring);
312 }
313 else
314 {
315 unsigned long bm=0;
316 int b=0;
317 bm=rGetExpSize(bm,b,r->N);
318 if (r->bitmask!=bm)
319 {
320 fprintf(d->f_write,"23 0 %d ",SI_LOG2(r->bitmask));
321 }
322 if (rIsPluralRing(r))
323 {
324 fputs("23 2 ",d->f_write);
325 ssiWriteIdeal(d,MATRIX_CMD,(ideal)r->GetNC()->C);
326 ssiWriteIdeal(d,MATRIX_CMD,(ideal)r->GetNC()->D);
327 }
328 }
329}
330
331static void ssiWriteRing(ssiInfo *d,const ring r)
332{
333 /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
334 /* ch=-1: transext, coeff ring follows */
335 /* ch=-2: algext, coeff ring and minpoly follows */
336 /* ch=-3: cf name follows */
337 /* ch=-4: NULL */
338 /* ch=-5: reference <int> */
339 /* ch=-6: new reference <int> <ring> */
340 if ((r==NULL)||(r->cf==NULL))
341 {
342 fputs("-4 ",d->f_write);
343 return;
344 }
345 if (r==currRing) // see recursive calls for transExt/algExt
346 {
347 if (d->r!=NULL) rKill(d->r);
348 d->r=r;
349 }
350 if (r!=NULL)
351 {
352 /*d->*/rIncRefCnt(r);
353 }
354 ssiWriteRing_R(d,r);
355}
356static void ssiWritePoly_R(const ssiInfo *d, int /*typ*/, poly p, const ring r)
357{
358 fprintf(d->f_write,"%d ",pLength(p));//number of terms
359
360 while(p!=NULL)
361 {
362 ssiWriteNumber_CF(d,pGetCoeff(p),r->cf);
363 //nWrite(fich,pGetCoeff(p));
364 fprintf(d->f_write,"%ld ",p_GetComp(p,r));//component
365
366 for(int j=1;j<=rVar(r);j++)
367 {
368 fprintf(d->f_write,"%ld ",p_GetExp(p,j,r ));//x^j
369 }
370 pIter(p);
371 }
372}
373
374static void ssiWritePoly(const ssiInfo *d, int typ, poly p)
375{
376 ssiWritePoly_R(d,typ,p,d->r);
377}
378
379static void ssiWriteIdeal_R(const ssiInfo *d, int typ,const ideal I, const ring R)
380{
381 // syntax: 7 # of elements <poly 1> <poly2>.....(ideal,module,smatrix)
382 // syntax: 8 <rows> <cols> <poly 1> <poly2>.....(matrix)
383 // syntax
384 matrix M=(matrix)I;
385 int mn;
386 if (typ==MATRIX_CMD)
387 {
388 mn=MATROWS(M)*MATCOLS(M);
389 fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
390 }
391 else
392 {
393 mn=IDELEMS(I);
394 fprintf(d->f_write,"%d ",IDELEMS(I));
395 }
396
397 int i;
398 int tt;
399 if ((typ==MODUL_CMD)||(typ==SMATRIX_CMD))
400 tt=VECTOR_CMD;
401 else
402 tt=POLY_CMD;
403
404 for(i=0;i<mn;i++)
405 {
406 ssiWritePoly_R(d,tt,I->m[i],R);
407 }
408}
409static void ssiWriteIdeal(const ssiInfo *d, int typ,const ideal I)
410{
411 ssiWriteIdeal_R(d,typ,I,d->r);
412}
413
415{
416 ssiInfo *d=(ssiInfo*)l->data;
417 // syntax: <num ops> <operation> <op1> <op2> ....
418 fprintf(d->f_write,"%d %d ",D->argc,D->op);
419 if (D->argc >0) ssiWrite(l, &(D->arg1));
420 if (D->argc < 4)
421 {
422 if (D->argc >1) ssiWrite(l, &(D->arg2));
423 if (D->argc >2) ssiWrite(l, &(D->arg3));
424 }
425}
426
427static void ssiWriteProc(const ssiInfo *d,procinfov p)
428{
429 if (p->data.s.body==NULL)
431 if (p->data.s.body!=NULL)
432 ssiWriteString(d,p->data.s.body);
433 else
434 ssiWriteString(d,"");
435}
436
438{
439 ssiInfo *d=(ssiInfo*)l->data;
440 int Ll=dd->nr;
441 fprintf(d->f_write,"%d ",Ll+1);
442 int i;
443 for(i=0;i<=Ll;i++)
444 {
445 ssiWrite(l,&(dd->m[i]));
446 }
447}
448static void ssiWriteIntvec(const ssiInfo *d,intvec * v)
449{
450 fprintf(d->f_write,"%d ",v->length());
451 int i;
452 for(i=0;i<v->length();i++)
453 {
454 fprintf(d->f_write,"%d ",(*v)[i]);
455 }
456}
457static void ssiWriteIntmat(const ssiInfo *d,intvec * v)
458{
459 fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
460 int i;
461 for(i=0;i<v->length();i++)
462 {
463 fprintf(d->f_write,"%d ",(*v)[i]);
464 }
465}
466
467static void ssiWriteBigintmat(const ssiInfo *d,bigintmat * v)
468{
469 fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
470 int i;
471 for(i=0;i<v->length();i++)
472 {
473 ssiWriteBigInt(d,(*v)[i]);
474 }
475}
476
477static void ssiWriteBigintvec(const ssiInfo *d,bigintmat * v)
478{
479 fprintf(d->f_write,"%d ",v->cols());
480 int i;
481 for(i=0;i<v->length();i++)
482 {
483 ssiWriteBigInt(d,(*v)[i]);
484 }
485}
486
487static char *ssiReadString(const ssiInfo *d)
488{
489 char *buf;
490 int l;
491 l=s_readint(d->f_read);
492 buf=(char*)omAlloc0(l+1);
493 int throwaway =s_getc(d->f_read); /* skip ' '*/
494 throwaway=s_readbytes(buf,l,d->f_read);
495 //if (throwaway!=l) printf("want %d, got %d bytes\n",l,throwaway);
496 buf[l]='\0';
497 return buf;
498}
499
500static int ssiReadInt(s_buff fich)
501{
502 return s_readint(fich);
503}
504
505static number ssiReadNumber_CF(const ssiInfo *d, const coeffs cf)
506{
507 if (cf->cfReadFd!=ndReadFd)
508 {
509 return n_ReadFd(d,cf);
510 }
511 else if (getCoeffType(cf) == n_transExt)
512 {
513 // poly poly
514 fraction f=(fraction)n_Init(1,cf);
515 p_Delete(&NUM(f),cf->extRing);
516 NUM(f)=ssiReadPoly_R(d,cf->extRing);
517 DEN(f)=ssiReadPoly_R(d,cf->extRing);
518 return (number)f;
519 }
520 else if (getCoeffType(cf) == n_algExt)
521 {
522 // poly
523 return (number)ssiReadPoly_R(d,cf->extRing);
524 }
525 else WerrorS("coeffs not implemented in ssiReadNumber");
526 return NULL;
527}
528
529static number ssiReadBigInt(const ssiInfo *d)
530{
532 if ((SR_HDL(n) & SR_INT)==0)
533 {
534 if (n->s!=3) Werror("invalid sub type in bigint:%d",n->s);
535 }
536 return n;
537}
538
539static number ssiReadNumber(ssiInfo *d)
540{
541 return ssiReadNumber_CF(d,d->r->cf);
542}
543
544static ring ssiReadRing(ssiInfo *d)
545{
546/* syntax is <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <Q-ideal> */
547 int ch;
548 int new_ref=-1;
549 ch=s_readint(d->f_read);
550 if (ch==-6)
551 {
552 new_ref=s_readint(d->f_read);
553 ch=s_readint(d->f_read);
554 }
555 if (ch==-5)
556 {
557 int index=s_readint(d->f_read);
558 ring r=d->rings[index];
559 rIncRefCnt(r);
560 return r;
561 }
562 if (ch==-4)
563 return NULL;
564 int N=s_readint(d->f_read);
565 char **names;
566 coeffs cf=NULL;
567 if (ch==-3)
568 {
569 char *cf_name=ssiReadString(d);
570 cf=nFindCoeffByName(cf_name);
571 if (cf==NULL)
572 {
573 Werror("cannot find cf:%s",cf_name);
574 omFreeBinAddr(cf_name);
575 return NULL;
576 }
577 }
578 if (N!=0)
579 {
580 names=(char**)omAlloc(N*sizeof(char*));
581 for(int i=0;i<N;i++)
582 {
583 names[i]=ssiReadString(d);
584 }
585 }
586 // read the orderings:
587 int num_ord; // number of orderings
588 num_ord=s_readint(d->f_read);
589 rRingOrder_t *ord=(rRingOrder_t *)omAlloc0((num_ord+1)*sizeof(rRingOrder_t));
590 int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
591 int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
592 int **wvhdl=(int**)omAlloc0((num_ord+1)*sizeof(int*));
593 for(int i=0;i<num_ord;i++)
594 {
595 ord[i]=(rRingOrder_t)s_readint(d->f_read);
596 block0[i]=s_readint(d->f_read);
597 block1[i]=s_readint(d->f_read);
598 switch(ord[i])
599 {
600 case ringorder_a:
601 case ringorder_wp:
602 case ringorder_Wp:
603 case ringorder_ws:
604 case ringorder_Ws:
605 case ringorder_aa:
606 {
607 int s=block1[i]-block0[i]+1; // #vars
608 wvhdl[i]=(int*)omAlloc(s*sizeof(int));
609 for(int ii=0;ii<s;ii++)
610 wvhdl[i][ii]=s_readint(d->f_read);
611 }
612 break;
613 case ringorder_M:
614 {
615 int s=block1[i]-block0[i]+1; // #vars
616 wvhdl[i]=(int*)omAlloc(s*s*sizeof(int));
617 for(int ii=0;ii<s*s;ii++)
618 {
619 wvhdl[i][ii]=s_readint(d->f_read);
620 }
621 }
622 break;
623 case ringorder_a64:
624 case ringorder_L:
625 case ringorder_IS:
626 Werror("ring order not implemented for ssi:%d",ord[i]);
627 break;
628
629 default: break;
630 }
631 }
632 if (N==0)
633 {
634 omFree(ord);
635 omFree(block0);
636 omFree(block1);
637 omFree(wvhdl);
638 return NULL;
639 }
640 else
641 {
642 ring r=NULL;
643 if (ch>=0) /* Q, Z/p */
644 r=rDefault(ch,N,names,num_ord,ord,block0,block1,wvhdl);
645 else if (ch==-1) /* trans ext. */
646 {
648 T.r=ssiReadRing(d);
649 if (T.r==NULL) return NULL;
651 r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
652 }
653 else if (ch==-2) /* alg ext. */
654 {
656 T.r=ssiReadRing(d); /* includes qideal */
657 if (T.r==NULL) return NULL;
659 r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
660 }
661 else if (ch==-3)
662 {
663 r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
664 }
665 else
666 {
667 Werror("ssi: read unknown coeffs type (%d)",ch);
668 for(int i=0;i<N;i++)
669 {
670 omFree(names[i]);
671 }
672 omFreeSize(names,N*sizeof(char*));
673 return NULL;
674 }
675 ideal q=ssiReadIdeal_R(d,r);
676 if (IDELEMS(q)==0) omFreeBin(q,sip_sideal_bin);
677 else r->qideal=q;
678 for(int i=0;i<N;i++)
679 {
680 omFree(names[i]);
681 }
682 omFreeSize(names,N*sizeof(char*));
683 rIncRefCnt(r);
684 // check if such ring already exist as ssiRing*
685 char name[20];
686 int nr=0;
687 idhdl h=NULL;
688 loop
689 {
690 snprintf(name,20,"ssiRing%d",nr); nr++;
691 h=IDROOT->get(name, 0);
692 if (h==NULL)
693 {
694 break;
695 }
696 else if ((IDTYP(h)==RING_CMD)
697 && (r!=IDRING(h))
698 && (rEqual(r,IDRING(h),1)))
699 {
700 rDelete(r);
701 r=rIncRefCnt(IDRING(h));
702 break;
703 }
704 }
705 if (new_ref!=-1)
706 {
707 d->rings[new_ref]=r;
708 rIncRefCnt(r);
709 }
710 return r;
711 }
712}
713
714static poly ssiReadPoly_R(const ssiInfo *d, const ring r)
715{
716// < # of terms> < term1> < .....
717 int n,i,l;
718 n=ssiReadInt(d->f_read); // # of terms
719 //Print("poly: terms:%d\n",n);
720 poly p;
721 poly ret=NULL;
722 poly prev=NULL;
723 for(l=0;l<n;l++) // read n terms
724 {
725// coef,comp.exp1,..exp N
726 p=p_Init(r,r->PolyBin);
727 pSetCoeff0(p,ssiReadNumber_CF(d,r->cf));
728 int D;
729 D=s_readint(d->f_read);
730 p_SetComp(p,D,r);
731 for(i=1;i<=rVar(r);i++)
732 {
733 D=s_readint(d->f_read);
734 p_SetExp(p,i,D,r);
735 }
736 p_Setm(p,r);
737 p_Test(p,r);
738 if (ret==NULL) ret=p;
739 else pNext(prev)=p;
740 prev=p;
741 }
742 return ret;
743}
744
745static poly ssiReadPoly(ssiInfo *d)
746{
747 return ssiReadPoly_R(d,d->r);
748}
749
750static ideal ssiReadIdeal_R(const ssiInfo *d,const ring r)
751{
752// < # of terms> < term1> < .....
753 int n,i;
754 ideal I;
755 n=s_readint(d->f_read);
756 I=idInit(n,1); // will be fixed later for module/smatrix
757 for(i=0;i<IDELEMS(I);i++) // read n terms
758 {
759 I->m [i]=ssiReadPoly_R(d,r);
760 }
761 return I;
762}
763
764static ideal ssiReadIdeal(ssiInfo *d)
765{
766 return ssiReadIdeal_R(d,d->r);
767}
768
770{
771 int n,m;
772 m=s_readint(d->f_read);
773 n=s_readint(d->f_read);
774 matrix M=mpNew(m,n);
775 poly p;
776 for(int i=1;i<=MATROWS(M);i++)
777 for(int j=1;j<=MATCOLS(M);j++)
778 {
779 p=ssiReadPoly(d);
780 MATELEM(M,i,j)=p;
781 }
782 return M;
783}
784
786{
787 ssiInfo *d=(ssiInfo*)l->data;
788 // syntax: <num ops> <operation> <op1> <op2> ....
789 command D=(command)omAlloc0(sizeof(*D));
790 int argc,op;
791 argc=s_readint(d->f_read);
792 op=s_readint(d->f_read);
793 D->argc=argc; D->op=op;
794 leftv v;
795 if (argc >0)
796 {
797 v=ssiRead1(l);
798 memcpy(&(D->arg1),v,sizeof(*v));
800 }
801 if (argc <4)
802 {
803 if (D->argc >1)
804 {
805 v=ssiRead1(l);
806 memcpy(&(D->arg2),v,sizeof(*v));
808 }
809 if (D->argc >2)
810 {
811 v=ssiRead1(l);
812 memcpy(&(D->arg3),v,sizeof(*v));
814 }
815 }
816 else
817 {
818 leftv prev=&(D->arg1);
819 argc--;
820 while(argc >0)
821 {
822 v=ssiRead1(l);
823 prev->next=v;
824 prev=v;
825 argc--;
826 }
827 }
828 return D;
829}
830
832{
833 char *s=ssiReadString(d);
836 p->libname=omStrDup("");
837 p->procname=omStrDup("");
838 p->data.s.body=s;
839 return p;
840}
842{
843 ssiInfo *d=(ssiInfo*)l->data;
844 int nr;
845 nr=s_readint(d->f_read);
847 L->Init(nr);
848
849 int i;
850 leftv v;
851 for(i=0;i<=L->nr;i++)
852 {
853 v=ssiRead1(l);
854 memcpy(&(L->m[i]),v,sizeof(*v));
856 }
857 return L;
858}
859static intvec* ssiReadIntvec(const ssiInfo *d)
860{
861 int nr;
862 nr=s_readint(d->f_read);
863 intvec *v=new intvec(nr);
864 for(int i=0;i<nr;i++)
865 {
866 (*v)[i]=s_readint(d->f_read);
867 }
868 return v;
869}
870static intvec* ssiReadIntmat(const ssiInfo *d)
871{
872 int r,c;
873 r=s_readint(d->f_read);
874 c=s_readint(d->f_read);
875 intvec *v=new intvec(r,c,0);
876 for(int i=0;i<r*c;i++)
877 {
878 (*v)[i]=s_readint(d->f_read);
879 }
880 return v;
881}
883{
884 int r,c;
885 r=s_readint(d->f_read);
886 c=s_readint(d->f_read);
888 for(int i=0;i<r*c;i++)
889 {
890 (*v)[i]=ssiReadBigInt(d);
891 }
892 return v;
893}
895{
896 int c;
897 c=s_readint(d->f_read);
899 for(int i=0;i<c;i++)
900 {
901 (*v)[i]=ssiReadBigInt(d);
902 }
903 return v;
904}
905
907{
908 ssiInfo *d=(ssiInfo*)l->data;
909 leftv lv=ssiRead1(l);
910 char *name=(char*)lv->data;
912 int tok;
913 blackboxIsCmd(name,tok);
914 if (tok>MAX_TOK)
915 {
916 ring save_ring=currRing;
917 idhdl save_hdl=currRingHdl;
918 blackbox *b=getBlackboxStuff(tok);
919 res->rtyp=tok;
920 b->blackbox_deserialize(&b,&(res->data),l);
921 if (save_ring!=currRing)
922 {
923 rChangeCurrRing(save_ring);
924 if (save_hdl!=NULL) rSetHdl(save_hdl);
925 else currRingHdl=NULL;
926 }
927 }
928 else
929 {
930 Werror("blackbox %s not found",name);
931 }
932 omFree(name);
933}
934
936{
937 ssiInfo *d=(ssiInfo*)l->data;
939 int nr_of_attr=s_readint(d->f_read);
940 if (nr_of_attr>0)
941 {
942 for(int i=1;i<nr_of_attr;i++)
943 {
944 }
945 }
946 leftv tmp=ssiRead1(l);
947 memcpy(res,tmp,sizeof(sleftv));
948 memset(tmp,0,sizeof(sleftv));
950 if (nr_of_attr>0)
951 {
952 }
953 res->flag=fl;
954}
956{
957 ssiInfo *d=(ssiInfo*)l->data;
958 int what=s_readint(d->f_read);
959 switch(what)
960 {
961 case 0: // bitmask
962 {
963 int lb=s_readint(d->f_read);
964 unsigned long bm=~0L;
965 bm=bm<<lb;
966 bm=~bm;
967 rUnComplete(d->r);
968 d->r->bitmask=bm;
969 rComplete(d->r);
970 break;
971 }
972 case 1: // LPRing
973 {
974 int lb=s_readint(d->f_read);
975 int isLPring=s_readint(d->f_read);
976 unsigned long bm=~0L;
977 bm=bm<<lb;
978 bm=~bm;
979 rUnComplete(d->r);
980 d->r->bitmask=bm;
981 d->r->isLPring=isLPring;
982 rComplete(d->r);
983 break;
984 }
985 case 2: // Plural rings
986 {
989 nc_CallPlural(C,D,NULL,NULL,d->r,true,true,false,d->r,false);
990 break;
991 }
992 }
993}
994//**************************************************************************/
995
997{
998 if (l!=NULL)
999 {
1000 const char *mode;
1001 ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
1002 if (flag & SI_LINK_OPEN)
1003 {
1004 if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
1005 flag = SI_LINK_READ;
1006 else flag = SI_LINK_WRITE;
1007 }
1008
1009 if (flag == SI_LINK_READ) mode = "r";
1010 else if (strcmp(l->mode, "w") == 0) mode = "w";
1011 else if (strcmp(l->mode, "fork") == 0) mode = "fork";
1012 else if (strcmp(l->mode, "tcp") == 0) mode = "tcp";
1013 else if (strcmp(l->mode, "connect") == 0) mode = "connect";
1014 else mode = "a";
1015
1016
1017 SI_LINK_SET_OPEN_P(l, flag);
1018 if(l->data!=NULL) omFreeSize(l->data,sizeof(ssiInfo));
1019 l->data=d;
1020 omFreeBinAddr(l->mode);
1021 l->mode = omStrDup(mode);
1022
1023 if (l->name[0] == '\0')
1024 {
1025 if (strcmp(mode,"fork")==0)
1026 {
1027 int pc[2];
1028 int cp[2];
1029 int err1=pipe(pc);
1030 int err2=pipe(cp);
1031 if (err1 || err2)
1032 {
1033 Werror("pipe failed with %d\n",errno);
1034 return TRUE;
1035 }
1037 n->u=u;
1038 n->l=l;
1039 n->next=(void *)ssiToBeClosed;
1040 ssiToBeClosed=n;
1041
1042 pid_t pid = fork();
1043 if (pid == -1 && errno == EAGAIN) // RLIMIT_NPROC too low?
1044 {
1046 pid = fork();
1047 }
1048 if (pid == -1)
1049 {
1050 WerrorS("could not fork");
1051 }
1052 if (pid==0) /*fork: child*/
1053 {
1054 /* block SIGINT */
1055 sigset_t sigint;
1056 sigemptyset(&sigint);
1057 sigaddset(&sigint, SIGINT);
1058 sigprocmask(SIG_BLOCK, &sigint, NULL);
1059 /* set #cpu to 1 for the child:*/
1060 feSetOptValue(FE_OPT_CPUS,1);
1061
1063 /* we know: l is the first entry in ssiToBeClosed-list */
1064 while(hh!=NULL)
1065 {
1067 ssiInfo *dd=(ssiInfo*)hh->l->data;
1068 s_close(dd->f_read);
1069 fclose(dd->f_write);
1070 if (dd->r!=NULL) rKill(dd->r);
1071 omFreeSize((ADDRESS)dd,(sizeof *dd));
1072 hh->l->data=NULL;
1073 link_list nn=(link_list)hh->next;
1074 omFree(hh);
1075 hh=nn;
1076 }
1078#ifdef HAVE_SIMPLEIPC
1079 memset(sem_acquired, 0, SIPC_MAX_SEMAPHORES*sizeof(sem_acquired[0]));
1080#endif // HAVE_SIMPLEIPC
1081 si_close(pc[1]); si_close(cp[0]);
1082 d->f_write=fdopen(cp[1],"w");
1083 d->f_read=s_open(pc[0]);
1084 d->fd_read=pc[0];
1085 d->fd_write=cp[1];
1086 //d->r=currRing;
1087 //if (d->r!=NULL) d->r->ref++;
1088 l->data=d;
1089 omFreeBinAddr(l->mode);
1090 l->mode = omStrDup(mode);
1093 //myynest=0;
1095 if ((u!=NULL)&&(u->rtyp==IDHDL))
1096 {
1097 idhdl h=(idhdl)u->data;
1098 h->lev=0;
1099 }
1100 loop
1101 {
1102 if (!SI_LINK_OPEN_P(l)) m2_end(0);
1103 if(d->f_read->is_eof) m2_end(0);
1104 leftv h=ssiRead1(l); /*contains an exit.... */
1105 if (feErrors != NULL && *feErrors != '\0')
1106 {
1107 // handle errors:
1108 PrintS(feErrors); /* currently quite simple */
1109 *feErrors = '\0';
1110 }
1111 ssiWrite(l,h);
1112 h->CleanUp();
1114 }
1115 /* never reached*/
1116 }
1117 else if (pid>0) /*fork: parent*/
1118 {
1119 d->pid=pid;
1120 si_close(pc[0]); si_close(cp[1]);
1121 d->f_write=fdopen(pc[1],"w");
1122 d->f_read=s_open(cp[0]);
1123 d->fd_read=cp[0];
1124 d->fd_write=pc[1];
1126 d->send_quit_at_exit=1;
1127 //d->r=currRing;
1128 //if (d->r!=NULL) d->r->ref++;
1129 }
1130 else
1131 {
1132 Werror("fork failed (%d)",errno);
1133 l->data=NULL;
1134 omFree(d);
1135 return TRUE;
1136 }
1137 }
1138 // ---------------------------------------------------------------------
1139 else if (strcmp(mode,"tcp")==0)
1140 {
1141 int sockfd, newsockfd, portno, clilen;
1142 struct sockaddr_in serv_addr, cli_addr;
1143 sockfd = socket(AF_INET, SOCK_STREAM, 0);
1144 if(sockfd < 0)
1145 {
1146 WerrorS("ERROR opening socket");
1147 l->data=NULL;
1148 l->flags=0;
1149 omFree(d);
1150 return TRUE;
1151 }
1152 memset((char *) &serv_addr,0, sizeof(serv_addr));
1153 portno = 1025;
1154 serv_addr.sin_family = AF_INET;
1155 serv_addr.sin_addr.s_addr = INADDR_ANY;
1156 do
1157 {
1158 portno++;
1159 serv_addr.sin_port = htons(portno);
1160 if(portno > 50000)
1161 {
1162 WerrorS("ERROR on binding (no free port available?)");
1163 l->data=NULL;
1164 l->flags=0;
1165 omFree(d);
1166 return TRUE;
1167 }
1168 }
1169 while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
1170 Print("waiting on port %d\n", portno);mflush();
1171 listen(sockfd,1);
1172 newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
1173 if(newsockfd < 0)
1174 {
1175 WerrorS("ERROR on accept");
1176 l->data=NULL;
1177 l->flags=0;
1178 omFree(d);
1179 return TRUE;
1180 }
1181 PrintS("client accepted\n");
1182 d->fd_read = newsockfd;
1183 d->fd_write = newsockfd;
1184 d->f_read = s_open(newsockfd);
1185 d->f_write = fdopen(newsockfd, "w");
1187 si_close(sockfd);
1188 }
1189 // no ssi-Link on stdin or stdout
1190 else
1191 {
1192 Werror("invalid mode >>%s<< for ssi",mode);
1193 l->data=NULL;
1194 l->flags=0;
1195 omFree(d);
1196 return TRUE;
1197 }
1198 }
1199 // =========================================================================
1200 else /*now l->name!=NULL*/
1201 {
1202 // tcp mode
1203 if(strcmp(mode,"tcp")==0)
1204 {
1205 int sockfd, newsockfd, portno, clilen;
1206 struct sockaddr_in serv_addr, cli_addr;
1207 sockfd = socket(AF_INET, SOCK_STREAM, 0);
1208 if(sockfd < 0)
1209 {
1210 WerrorS("ERROR opening socket");
1211 l->data=NULL;
1212 l->flags=0;
1213 omFree(d);
1214 return TRUE;
1215 }
1216 memset((char *) &serv_addr,0, sizeof(serv_addr));
1217 portno = 1025;
1218 serv_addr.sin_family = AF_INET;
1219 serv_addr.sin_addr.s_addr = INADDR_ANY;
1220 do
1221 {
1222 portno++;
1223 serv_addr.sin_port = htons(portno);
1224 if(portno > 50000)
1225 {
1226 WerrorS("ERROR on binding (no free port available?)");
1227 l->data=NULL;
1228 l->flags=0;
1229 return TRUE;
1230 }
1231 }
1232 while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
1233 //Print("waiting on port %d\n", portno);mflush();
1234 listen(sockfd,1);
1235 char* cli_host = (char*)omAlloc(256);
1236 char* path = (char*)omAlloc(1024);
1237 int r = si_sscanf(l->name,"%255[^:]:%s",cli_host,path);
1238 if(r == 0)
1239 {
1240 WerrorS("ERROR: no host specified");
1241 l->data=NULL;
1242 l->flags=0;
1243 omFree(d);
1244 omFree(path);
1245 omFree(cli_host);
1246 return TRUE;
1247 }
1248 else if(r == 1)
1249 {
1250 WarnS("program not specified, using /usr/local/bin/Singular");
1251 Warn("in line >>%s<<",my_yylinebuf);
1252 strcpy(path,"/usr/local/bin/Singular");
1253 }
1254 char* ssh_command = (char*)omAlloc(256);
1255 char* ser_host = (char*)omAlloc(64);
1256 if(strcmp(cli_host,"localhost")==0)
1257 strcpy(ser_host,"localhost");
1258 else
1259 gethostname(ser_host,64);
1260 if (strcmp(cli_host,"localhost")==0) /*avoid "ssh localhost" as key may change*/
1261 snprintf(ssh_command,256,"%s -q --batch --link=ssi --MPhost=%s --MPport=%d &",path,ser_host,portno);
1262 else
1263 snprintf(ssh_command,256,"ssh %s %s -q --batch --link=ssi --MPhost=%s --MPport=%d &",cli_host,path,ser_host,portno);
1264 //Print("client on %s started:%s\n",cli_host,path);
1265 omFree(path);
1266 omFree(cli_host);
1267 if (TEST_OPT_PROT) { Print("running >>%s<<\n",ssh_command); }
1268 int re=system(ssh_command);
1269 if (re<0)
1270 {
1271 Werror("ERROR running `%s` (%d)",ssh_command,re);
1272 l->data=NULL;
1273 l->flags=0;
1274 omFree(d);
1275 return TRUE;
1276 }
1277 omFree(ssh_command);
1278 omFree(ser_host);
1279 clilen = sizeof(cli_addr);
1280 newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
1281 if(newsockfd < 0)
1282 {
1283 WerrorS("ERROR on accept");
1284 l->data=NULL;
1285 l->flags=0;
1286 omFree(d);
1287 return TRUE;
1288 }
1289 //PrintS("client accepted\n");
1290 d->fd_read = newsockfd;
1291 d->fd_write = newsockfd;
1292 d->f_read = s_open(newsockfd);
1293 d->f_write = fdopen(newsockfd, "w");
1294 si_close(sockfd);
1296 d->send_quit_at_exit=1;
1297 link_list newlink=(link_list)omAlloc(sizeof(link_struct));
1298 newlink->u=u;
1299 newlink->l=l;
1300 newlink->next=(void *)ssiToBeClosed;
1301 ssiToBeClosed=newlink;
1302 fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
1303 }
1304 // ----------------------------------------------------------------------
1305 else if(strcmp(mode,"connect")==0)
1306 {
1307 char* host = (char*)omAlloc(256);
1308 int sockfd, portno;
1309 struct sockaddr_in serv_addr;
1310 struct hostent *server;
1311
1312 si_sscanf(l->name,"%255[^:]:%d",host,&portno);
1313 //Print("connect to host %s, port %d\n",host,portno);mflush();
1314 if (portno!=0)
1315 {
1316 sockfd = socket(AF_INET, SOCK_STREAM, 0);
1317 if (sockfd < 0)
1318 {
1319 WerrorS("ERROR opening socket");
1320 l->flags=0;
1321 return TRUE;
1322 }
1323 server = gethostbyname(host);
1324 if (server == NULL)
1325 {
1326 WerrorS("ERROR, no such host");
1327 l->flags=0;
1328 return TRUE;
1329 }
1330 memset((char *) &serv_addr, 0, sizeof(serv_addr));
1331 serv_addr.sin_family = AF_INET;
1332 memcpy((char *)&serv_addr.sin_addr.s_addr,
1333 (char *)server->h_addr,
1334 server->h_length);
1335 serv_addr.sin_port = htons(portno);
1336 if (si_connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
1337 {
1338 Werror("ERROR connecting(errno=%d)",errno);
1339 l->flags=0;
1340 return TRUE;
1341 }
1342 //PrintS("connected\n");mflush();
1343 d->f_read=s_open(sockfd);
1344 d->fd_read=sockfd;
1345 d->f_write=fdopen(sockfd,"w");
1346 d->fd_write=sockfd;
1348 omFree(host);
1349 }
1350 else
1351 {
1352 l->data=NULL;
1353 l->flags=0;
1354 omFree(d);
1355 return TRUE;
1356 }
1357 }
1358 // ======================================================================
1359 else
1360 {
1361 // normal link to a file
1362 FILE *outfile;
1363 char *filename=l->name;
1364
1365 if(filename[0]=='>')
1366 {
1367 if (filename[1]=='>')
1368 {
1369 filename+=2;
1370 mode = "a";
1371 }
1372 else
1373 {
1374 filename++;
1375 mode="w";
1376 }
1377 }
1378 outfile=myfopen(filename,mode);
1379 if (outfile!=NULL)
1380 {
1381 if (strcmp(l->mode,"r")==0)
1382 {
1383 fclose(outfile);
1384 d->f_read=s_open_by_name(filename);
1385 }
1386 else
1387 {
1388 d->f_write = outfile;
1389 fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
1390 }
1391 }
1392 else
1393 {
1394 omFree(d);
1395 l->data=NULL;
1396 l->flags=0;
1397 return TRUE;
1398 }
1399 }
1400 }
1401 }
1402
1403 return FALSE;
1404}
1405
1406//**************************************************************************/
1408{
1409 if (l!=NULL)
1410 {
1412 ssiInfo *d = (ssiInfo *)l->data;
1413 if (d!=NULL)
1414 {
1415 if (d->send_quit_at_exit)
1416 {
1417 fputs("99\n",d->f_write);
1418 fflush(d->f_write);
1419 }
1420 d->quit_sent=1;
1421 }
1422 }
1423 return FALSE;
1424}
1425
1427{
1428 if (l!=NULL)
1429 {
1431 ssiInfo *d = (ssiInfo *)l->data;
1432 if (d!=NULL)
1433 {
1434 // send quit signal
1435 if ((d->send_quit_at_exit)
1436 && (d->quit_sent==0))
1437 {
1438 fputs("99\n",d->f_write);
1439 fflush(d->f_write);
1440 }
1441 // clean ring
1442 if (d->r!=NULL) rKill(d->r);
1443 for(int i=0;i<SI_RING_CACHE;i++)
1444 {
1445 if (d->rings[i]!=NULL) rKill(d->rings[i]);
1446 d->rings[i]=NULL;
1447 }
1448 // did the child to stop ?
1449 si_waitpid(d->pid,NULL,WNOHANG);
1450 if ((d->pid!=0)
1451 && (kill(d->pid,0)==0)) // child is still running
1452 {
1453 struct timespec t;
1454 t.tv_sec=0;
1455 t.tv_nsec=100000000; // <=100 ms
1456 struct timespec rem;
1457 int r;
1458 loop
1459 {
1460 // wait till signal or time rem:
1461 r = nanosleep(&t, &rem);
1462 t = rem;
1463 // child finished:
1464 if (si_waitpid(d->pid,NULL,WNOHANG) != 0) break;
1465 // other signal, waited s>= 100 ms:
1466 if ((r==0) || (errno != EINTR)) break;
1467 }
1468 if (kill(d->pid,0) == 0) // pid still exists
1469 {
1470 kill(d->pid,15);
1471 t.tv_sec=5; // <=5s
1472 t.tv_nsec=0;
1473 loop
1474 {
1475 // wait till signal or time rem:
1476 r = nanosleep(&t, &rem);
1477 t = rem;
1478 // child finished:
1479 if (si_waitpid(d->pid,NULL,WNOHANG) != 0) break;
1480 // other signal, waited s>= 5 s:
1481 if ((r==0) || (errno != EINTR)) break;
1482 }
1483 if (kill(d->pid,0) == 0)
1484 {
1485 kill(d->pid,9); // just to be sure
1486 si_waitpid(d->pid,NULL,0);
1487 }
1488 }
1489 }
1490 if (d->f_read!=NULL) { s_close(d->f_read);d->f_read=NULL;}
1491 if (d->f_write!=NULL) { fclose(d->f_write); d->f_write=NULL; }
1492 if ((strcmp(l->mode,"tcp")==0)
1493 || (strcmp(l->mode,"fork")==0))
1494 {
1496 if (hh!=NULL)
1497 {
1498 if (hh->l==l)
1499 {
1501 omFreeSize(hh,sizeof(link_struct));
1502 }
1503 else while(hh->next!=NULL)
1504 {
1505 link_list hhh=(link_list)hh->next;
1506 if (hhh->l==l)
1507 {
1508 hh->next=hhh->next;
1509 omFreeSize(hhh,sizeof(link_struct));
1510 break;
1511 }
1512 else
1513 hh=(link_list)hh->next;
1514 }
1515 }
1516 }
1517 omFreeSize((ADDRESS)d,(sizeof *d));
1518 }
1519 l->data=NULL;
1520 }
1521 return FALSE;
1522}
1523
1524//**************************************************************************/
1526{
1527 ssiInfo *d = (ssiInfo *)l->data;
1529 int t=0;
1530 t=s_readint(d->f_read);
1531 //Print("got type %d\n",t);
1532 switch(t)
1533 {
1534 case 1:res->rtyp=INT_CMD;
1535 res->data=(char *)(long)ssiReadInt(d->f_read);
1536 //Print("int: %d\n",(int)(long)res->data);
1537 break;
1538 case 2:res->rtyp=STRING_CMD;
1539 res->data=(char *)ssiReadString(d);
1540 //Print("str: %s\n",(char*)res->data);
1541 break;
1542 case 3:res->rtyp=NUMBER_CMD;
1543 if (d->r==NULL) goto no_ring;
1544 ssiCheckCurrRing(d->r);
1545 res->data=(char *)ssiReadNumber(d);
1546 //Print("number\n");
1547 break;
1548 case 4:res->rtyp=BIGINT_CMD;
1549 res->data=(char *)ssiReadBigInt(d);
1550 //Print("bigint\n");
1551 break;
1552 case 15:
1553 case 5:{
1554 //Print("ring %d\n",t);
1555 d->r=ssiReadRing(d);
1556 if (errorreported) return NULL;
1557 res->data=(char*)d->r;
1558 if (d->r!=NULL) rIncRefCnt(d->r);
1559 res->rtyp=RING_CMD;
1560 if (t==15) // setring
1561 {
1562 if(ssiSetCurrRing(d->r)) { d->r=currRing; }
1564 return ssiRead1(l);
1565 }
1566 }
1567 break;
1568 case 6:res->rtyp=POLY_CMD;
1569 //Print("poly\n");
1570 if (d->r==NULL) goto no_ring;
1571 ssiCheckCurrRing(d->r);
1572 res->data=(char*)ssiReadPoly(d);
1573 break;
1574 case 7:res->rtyp=IDEAL_CMD;
1575 //Print("ideal\n");
1576 if (d->r==NULL) goto no_ring;
1577 ssiCheckCurrRing(d->r);
1578 res->data=(char*)ssiReadIdeal(d);
1579 break;
1580 case 8:res->rtyp=MATRIX_CMD;
1581 //Print("matrix\n");
1582 if (d->r==NULL) goto no_ring;
1583 ssiCheckCurrRing(d->r);
1584 res->data=(char*)ssiReadMatrix(d);
1585 break;
1586 case 9:res->rtyp=VECTOR_CMD;
1587 //Print("vector\n");
1588 if (d->r==NULL) goto no_ring;
1589 ssiCheckCurrRing(d->r);
1590 res->data=(char*)ssiReadPoly(d);
1591 break;
1592 case 10:
1593 case 22:if (t==22) res->rtyp=SMATRIX_CMD;
1594 else res->rtyp=MODUL_CMD;
1595 //Print("module/smatrix %d\n",t);
1596 if (d->r==NULL) goto no_ring;
1597 ssiCheckCurrRing(d->r);
1598 {
1599 int rk=s_readint(d->f_read);
1600 ideal M=ssiReadIdeal(d);
1601 M->rank=rk;
1602 res->data=(char*)M;
1603 }
1604 break;
1605 case 11:
1606 {
1607 //Print("cmd\n",t);
1608 res->rtyp=COMMAND;
1609 res->data=ssiReadCommand(l);
1610 int nok=res->Eval();
1611 if (nok) WerrorS("error in eval");
1612 break;
1613 }
1614 case 12: /*DEF_CMD*/
1615 {
1616 //Print("def\n",t);
1617 res->rtyp=0;
1618 res->name=(char *)ssiReadString(d);
1619 int nok=res->Eval();
1620 if (nok) WerrorS("error in name lookup");
1621 break;
1622 }
1623 case 13: res->rtyp=PROC_CMD;
1624 res->data=ssiReadProc(d);
1625 break;
1626 case 14: res->rtyp=LIST_CMD;
1627 res->data=ssiReadList(l);
1628 break;
1629 case 16: res->rtyp=NONE; res->data=NULL;
1630 break;
1631 case 17: res->rtyp=INTVEC_CMD;
1632 res->data=ssiReadIntvec(d);
1633 break;
1634 case 18: res->rtyp=INTMAT_CMD;
1635 res->data=ssiReadIntmat(d);
1636 break;
1637 case 19: res->rtyp=BIGINTMAT_CMD;
1638 res->data=ssiReadBigintmat(d);
1639 break;
1640 case 20: ssiReadBlackbox(res,l);
1641 break;
1642 case 21: ssiReadAttrib(res,l);
1643 break;
1644 case 23: ssiReadRingProperties(l);
1645 return ssiRead1(l);
1646 break;
1647 case 24: res->rtyp=BIGINTVEC_CMD;
1648 res->data=ssiReadBigintvec(d);
1649 break;
1650 // ------------
1651 case 98: // version
1652 {
1653 int n98_v,n98_m;
1654 BITSET n98_o1,n98_o2;
1655 n98_v=s_readint(d->f_read);
1656 n98_m=s_readint(d->f_read);
1657 n98_o1=s_readint(d->f_read);
1658 n98_o2=s_readint(d->f_read);
1659 if ((n98_v!=SSI_VERSION) ||(n98_m!=MAX_TOK))
1660 {
1661 Print("incompatible versions of ssi: %d/%d vs %d/%d\n",
1662 SSI_VERSION,MAX_TOK,n98_v,n98_m);
1663 }
1664 #ifndef SING_NDEBUG
1665 if (TEST_OPT_DEBUG)
1666 Print("// opening ssi-%d, MAX_TOK=%d\n",n98_v,n98_m);
1667 #endif
1668 si_opt_1=n98_o1;
1669 si_opt_2=n98_o2;
1671 return ssiRead1(l);
1672 }
1673 case 99: omFreeBin(res,sleftv_bin); ssiClose(l); m2_end(0);
1674 break; /*to make compiler happy*/
1675 case 0: if (s_iseof(d->f_read))
1676 {
1677 ssiClose(l);
1678 }
1679 res->rtyp=DEF_CMD;
1680 break;
1681 default: Werror("not implemented (t:%d)",t);
1683 res=NULL;
1684 break;
1685 }
1686 // if currRing is required for the result, but lost
1687 // define "ssiRing%d" as currRing:
1688 if ((d->r!=NULL)
1689 && (currRing!=d->r)
1690 && (res->RingDependend()))
1691 {
1692 if(ssiSetCurrRing(d->r)) { d->r=currRing; }
1693 }
1694 return res;
1695no_ring: WerrorS("no ring");
1697 return NULL;
1698}
1699//**************************************************************************/
1700static BOOLEAN ssiSetRing(si_link l, ring r, BOOLEAN send)
1701{
1702 if(SI_LINK_W_OPEN_P(l)==0)
1704 ssiInfo *d = (ssiInfo *)l->data;
1705 if (d->r!=r)
1706 {
1707 if (send)
1708 {
1709 fputs("15 ",d->f_write);
1710 ssiWriteRing(d,r);
1711 }
1712 d->r=r;
1713 }
1714 if (currRing!=r) rChangeCurrRing(r);
1715 return FALSE;
1716}
1717//**************************************************************************/
1718
1720{
1721 if(SI_LINK_W_OPEN_P(l)==0)
1723 ssiInfo *d = (ssiInfo *)l->data;
1724 d->level++;
1725 //FILE *fich=d->f;
1726 while (data!=NULL)
1727 {
1728 int tt=data->Typ();
1729 void *dd=data->Data();
1730 attr *aa=data->Attribute();
1731 if ((aa!=NULL) && ((*aa)!=NULL)) // n user attributes
1732 {
1733 attr a=*aa;
1734 int n=0;
1735 while(a!=NULL) { n++; a=a->next;}
1736 fprintf(d->f_write,"21 %d %d ",data->flag,n);
1737 }
1738 else if (data->flag!=0) // only "flag" attributes
1739 {
1740 fprintf(d->f_write,"21 %d 0 ",data->flag);
1741 }
1742 if ((dd==NULL) && (data->name!=NULL) && (tt==0)) tt=DEF_CMD;
1743 // return pure undefined names as def
1744
1745 switch(tt /*data->Typ()*/)
1746 {
1747 case 0: /*error*/
1748 case NONE/* nothing*/:fputs("16 ",d->f_write);
1749 break;
1750 case STRING_CMD: fputs("2 ",d->f_write);
1751 ssiWriteString(d,(char *)dd);
1752 break;
1753 case INT_CMD: fputs("1 ",d->f_write);
1754 ssiWriteInt(d,(int)(long)dd);
1755 break;
1756 case BIGINT_CMD:fputs("4 ",d->f_write);
1757 ssiWriteBigInt(d,(number)dd);
1758 break;
1759 case NUMBER_CMD:
1760 if (d->r!=currRing)
1761 {
1762 fputs("15 ",d->f_write);
1764 if (d->level<=1) fputc('\n',d->f_write);
1765 }
1766 fputs("3 ",d->f_write);
1767 ssiWriteNumber(d,(number)dd);
1768 break;
1769 case RING_CMD:fputs("5 ",d->f_write);
1770 ssiWriteRing(d,(ring)dd);
1771 break;
1772 case BUCKET_CMD:
1773 {
1775 if (d->r!=sBucketGetRing(b))
1776 {
1777 fputs("15 ",d->f_write);
1779 if (d->level<=1) fputc('\n',d->f_write);
1780 }
1781 fputs("6 ",d->f_write);
1782 ssiWritePoly(d,tt,sBucketPeek(b));
1783 break;
1784 }
1785 case POLY_CMD:
1786 case VECTOR_CMD:
1787 if (d->r!=currRing)
1788 {
1789 fputs("15 ",d->f_write);
1791 if (d->level<=1) fputc('\n',d->f_write);
1792 }
1793 if(tt==POLY_CMD) fputs("6 ",d->f_write);
1794 else fputs("9 ",d->f_write);
1795 ssiWritePoly(d,tt,(poly)dd);
1796 break;
1797 case IDEAL_CMD:
1798 case MODUL_CMD:
1799 case MATRIX_CMD:
1800 case SMATRIX_CMD:
1801 if (d->r!=currRing)
1802 {
1803 fputs("15 ",d->f_write);
1805 if (d->level<=1) fputc('\n',d->f_write);
1806 }
1807 if(tt==IDEAL_CMD) fputs("7 ",d->f_write);
1808 else if(tt==MATRIX_CMD) fputs("8 ",d->f_write);
1809 else /* tt==MODUL_CMD, SMATRIX_CMD*/
1810 {
1811 ideal M=(ideal)dd;
1812 if (tt==MODUL_CMD)
1813 fprintf(d->f_write,"10 %d ",(int)M->rank);
1814 else /*(tt==SMATRIX_CMD)*/
1815 fprintf(d->f_write,"22 %d ",(int)M->rank);
1816 }
1817 ssiWriteIdeal(d,tt,(ideal)dd);
1818 break;
1819 case COMMAND:
1820 fputs("11 ",d->f_write);
1822 break;
1823 case DEF_CMD: /* not evaluated stuff in quotes */
1824 fputs("12 ",d->f_write);
1825 ssiWriteString(d,data->Name());
1826 break;
1827 case PROC_CMD:
1828 fputs("13 ",d->f_write);
1829 ssiWriteProc(d,(procinfov)dd);
1830 break;
1831 case LIST_CMD:
1832 fputs("14 ",d->f_write);
1833 ssiWriteList(l,(lists)dd);
1834 break;
1835 case INTVEC_CMD:
1836 fputs("17 ",d->f_write);
1837 ssiWriteIntvec(d,(intvec *)dd);
1838 break;
1839 case INTMAT_CMD:
1840 fputs("18 ",d->f_write);
1841 ssiWriteIntmat(d,(intvec *)dd);
1842 break;
1843 case BIGINTMAT_CMD:
1844 fputs("19 ",d->f_write);
1846 break;
1847 case BIGINTVEC_CMD:
1848 fputs("24 ",d->f_write);
1850 break;
1851 default:
1852 if (tt>MAX_TOK)
1853 {
1854 blackbox *b=getBlackboxStuff(tt);
1855 fputs("20 ",d->f_write);
1856 b->blackbox_serialize(b,dd,l);
1857 }
1858 else
1859 {
1860 Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
1861 d->level=0;
1862 return TRUE;
1863 }
1864 break;
1865 }
1866 if (d->level<=1) { fputc('\n',d->f_write); fflush(d->f_write); }
1867 data=data->next;
1868 }
1869 d->level--;
1870 return FALSE;
1871}
1872
1875
1876si_link_extension slInitSsiExtension(si_link_extension s)
1877{
1878 s->Open=ssiOpen;
1879 s->Close=ssiClose;
1880 s->Kill=ssiClose;
1881 s->Read=ssiRead1;
1882 s->Read2=(slRead2Proc)NULL;
1883 s->Write=ssiWrite;
1884 s->Dump=ssiDump;
1885 s->GetDump=ssiGetDump;
1886
1887 s->Status=slStatusSsi;
1888 s->SetRing=ssiSetRing;
1889 s->type="ssi";
1890 return s;
1891}
1892
1893const char* slStatusSsi(si_link l, const char* request)
1894{
1895 ssiInfo *d=(ssiInfo*)l->data;
1896 if (d==NULL) return "not open";
1897 if (((strcmp(l->mode,"fork")==0)
1898 ||(strcmp(l->mode,"tcp")==0)
1899 ||(strcmp(l->mode,"connect")==0))
1900 && (strcmp(request, "read") == 0))
1901 {
1902 if (s_isready(d->f_read)) return "ready";
1903#if defined(HAVE_POLL)
1904 pollfd pfd;
1905 loop
1906 {
1907 /* Don't block. Return socket status immediately. */
1908 pfd.fd=d->fd_read;
1909 pfd.events=POLLIN;
1910 //Print("test fd %d\n",d->fd_read);
1911 /* check with select: chars waiting: no -> not ready */
1912 switch (si_poll(&pfd,1,0))
1913 {
1914 case 0: /* not ready */ return "not ready";
1915 case -1: /*error*/ return "error";
1916 case 1: /*ready ? */ break;
1917 }
1918#else
1919 fd_set mask;
1920 struct timeval wt;
1921 if (FD_SETSIZE<=d->fd_read)
1922 {
1923 Werror("file descriptor number too high (%d)",d->fd_read);
1924 return "error";
1925 }
1926
1927 loop
1928 {
1929 /* Don't block. Return socket status immediately. */
1930 wt.tv_sec = 0;
1931 wt.tv_usec = 0;
1932
1933 FD_ZERO(&mask);
1934 FD_SET(d->fd_read, &mask);
1935 //Print("test fd %d\n",d->fd_read);
1936 /* check with select: chars waiting: no -> not ready */
1937 switch (si_select(d->fd_read+1, &mask, NULL, NULL, &wt))
1938 {
1939 case 0: /* not ready */ return "not ready";
1940 case -1: /*error*/ return "error";
1941 case 1: /*ready ? */ break;
1942 }
1943#endif
1944 /* yes: read 1 char*/
1945 /* if \n, check again with select else ungetc(c), ready*/
1946 int c=s_getc(d->f_read);
1947 //Print("try c=%d\n",c);
1948 if (c== -1) return "eof"; /* eof or error */
1949 else if (isdigit(c))
1950 { s_ungetc(c,d->f_read); return "ready"; }
1951 else if (c>' ')
1952 {
1953 Werror("unknown char in ssiLink(%d)",c);
1954 return "error";
1955 }
1956 /* else: next char */
1957 }
1958 }
1959 else if (strcmp(request, "read") == 0)
1960 {
1961 if (SI_LINK_R_OPEN_P(l) && (!s_iseof(d->f_read)) && (s_isready(d->f_read))) return "ready";
1962 else return "not ready";
1963 }
1964 else if (strcmp(request, "write") == 0)
1965 {
1966 if (SI_LINK_W_OPEN_P(l)) return "ready";
1967 else return "not ready";
1968 }
1969 else return "unknown status request";
1970}
1971
1972int slStatusSsiL(lists L, int timeout, BOOLEAN *ignore)
1973{
1974// input: L: a list with links of type
1975// ssi-connect, ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch.
1976// Note: Not every entry in L must be set.
1977// timeout: timeout for select in milli-seconds
1978// or -1 for infinity
1979// or 0 for polling
1980// returns: ERROR (via Werror): L has wrong elements or link not open
1981// -2: error in L
1982// -1: the read state of all links is eof
1983// 0: timeout (or polling): none ready,
1984// i>0: (at least) L[i] is ready
1985#if defined(HAVE_POLL) && !defined(__APPLE__)
1986 si_link l;
1987 ssiInfo *d=NULL;
1988 int d_fd;
1989 int s;
1990 int nfd=L->nr+1;
1991 pollfd *pfd=(pollfd*)omAlloc0(nfd*sizeof(pollfd));
1992 for(int i=L->nr; i>=0; i--)
1993 {
1994 pfd[i].fd=-1;
1995 if (L->m[i].Typ()!=DEF_CMD)
1996 {
1997 if (L->m[i].Typ()!=LINK_CMD)
1998 { WerrorS("all elements must be of type link"); return -2;}
1999 l=(si_link)L->m[i].Data();
2000 if(SI_LINK_OPEN_P(l)==0)
2001 { WerrorS("all links must be open"); return -2;}
2002 if (((strcmp(l->m->type,"ssi")!=0) && (strcmp(l->m->type,"MPtcp")!=0))
2003 || ((strcmp(l->mode,"fork")!=0) && (strcmp(l->mode,"tcp")!=0)
2004 && (strcmp(l->mode,"launch")!=0) && (strcmp(l->mode,"connect")!=0)))
2005 {
2006 WerrorS("all links must be of type ssi:fork, ssi:tcp, ssi:connect");
2007 return -2;
2008 }
2009 if (strcmp(l->m->type,"ssi")==0)
2010 {
2011 d=(ssiInfo*)l->data;
2012 d_fd=d->fd_read;
2013 if (!s_isready(d->f_read))
2014 {
2015 pfd[i].fd=d_fd;
2016 pfd[i].events=POLLIN;
2017 }
2018 else
2019 {
2020 return i+1;
2021 }
2022 }
2023 else
2024 {
2025 Werror("wrong link type >>%s<<",l->m->type);
2026 return -2;
2027 }
2028 }
2029 else if (ignore!=NULL)
2030 {
2031 ignore[i]=TRUE; // not a link
2032 }
2033 }
2034 s=si_poll(pfd,nfd,timeout);
2035 if (s==-1)
2036 {
2037 Werror("error in poll call (errno:%d)",errno);
2038 return -2; /*error*/
2039 }
2040 if(s==0)
2041 {
2042 return 0; /*timeout*/
2043 }
2044 for(int i=L->nr; i>=0; i--)
2045 {
2046 if ((L->m[i].rtyp==LINK_CMD)
2047 && ((ignore==NULL)||(ignore[i]==FALSE)))
2048 {
2049 // the link type is ssi, that's already tested
2050 l=(si_link)L->m[i].Data();
2051 d=(ssiInfo*)l->data;
2052 d_fd=d->fd_read;
2053 if (pfd[i].fd==d_fd)
2054 {
2055 if (pfd[i].revents &POLLIN)
2056 {
2057 omFree(pfd);
2058 return i+1;
2059 }
2060 }
2061 }
2062 }
2063 // no ready
2064 return 0;
2065#else
2066 si_link l;
2067 ssiInfo *d=NULL;
2068 int d_fd;
2069 fd_set fdmask;
2070 FD_ZERO(&fdmask);
2071 int max_fd=0; /* 1 + max fd in fd_set */
2072
2073 /* timeout */
2074 struct timeval wt;
2075 struct timeval *wt_ptr=&wt;
2076 int startingtime = getRTimer()/TIMER_RESOLUTION; // in seconds
2077 if (timeout== -1)
2078 {
2079 wt_ptr=NULL;
2080 }
2081 else
2082 {
2083 wt.tv_sec = timeout / 1000;
2084 wt.tv_usec = (timeout % 1000)*1000;
2085 }
2086
2087 /* auxiliary variables */
2088 int i;
2089 int j;
2090 int k;
2091 int s;
2092 char fdmaskempty;
2093
2094 /* check the links and fill in fdmask */
2095 /* check ssi links for ungetc_buf */
2096 for(i=L->nr; i>=0; i--)
2097 {
2098 if (L->m[i].Typ()!=DEF_CMD)
2099 {
2100 if (L->m[i].Typ()!=LINK_CMD)
2101 { WerrorS("all elements must be of type link"); return -2;}
2102 l=(si_link)L->m[i].Data();
2103 if(SI_LINK_OPEN_P(l)==0)
2104 { WerrorS("all links must be open"); return -2;}
2105 if (((strcmp(l->m->type,"ssi")!=0) && (strcmp(l->m->type,"MPtcp")!=0))
2106 || ((strcmp(l->mode,"fork")!=0) && (strcmp(l->mode,"tcp")!=0)
2107 && (strcmp(l->mode,"launch")!=0) && (strcmp(l->mode,"connect")!=0)))
2108 {
2109 WerrorS("all links must be of type ssi:fork, ssi:tcp, ssi:connect");
2110 return -2;
2111 }
2112 if (strcmp(l->m->type,"ssi")==0)
2113 {
2114 d=(ssiInfo*)l->data;
2115 d_fd=d->fd_read;
2116 if (!s_isready(d->f_read))
2117 {
2118 if ((ignore==NULL) || (ignore[i]==FALSE))
2119 {
2120 FD_SET(d_fd, &fdmask);
2121 if (d_fd > max_fd) max_fd=d_fd;
2122 }
2123 }
2124 else
2125 return i+1;
2126 }
2127 else
2128 {
2129 Werror("wrong link type >>%s<<",l->m->type);
2130 return -2;
2131 }
2132 }
2133 }
2134 max_fd++;
2135 if (FD_SETSIZE<=max_fd)
2136 {
2137 Werror("file descriptor number too high (%d)",max_fd);
2138 return -2;
2139 }
2140
2141 /* check with select: chars waiting: no -> not ready */
2142 s = si_select(max_fd, &fdmask, NULL, NULL, wt_ptr);
2143 if (s==-1)
2144 {
2145 Werror("error in select call (errno:%d)",errno);
2146 return -2; /*error*/
2147 }
2148 if (s==0)
2149 {
2150 return 0; /*poll: not ready */
2151 }
2152 else /* s>0, at least one ready (the number of fd which are ready is s)*/
2153 {
2154 j=0;
2155 while (j<=max_fd) { if (FD_ISSET(j,&fdmask)) break; j++; }
2156 for(i=L->nr; i>=0; i--)
2157 {
2158 if (L->m[i].rtyp==LINK_CMD)
2159 {
2160 l=(si_link)L->m[i].Data();
2161 if (strcmp(l->m->type,"ssi")==0)
2162 {
2163 d=(ssiInfo*)l->data;
2164 d_fd=d->fd_read;
2165 if(j==d_fd) return i+1;
2166 }
2167 }
2168 }
2169 }
2170 return 0;
2171#endif
2172}
2173
2174int ssiBatch(const char *host, const char * port)
2175/* return 0 on success, >0 else*/
2176{
2178 char *buf=(char*)omAlloc(256);
2179 snprintf(buf,256,"ssi:connect %s:%s",host,port);
2180 slInit(l, buf);
2181 omFreeSize(buf,256);
2182 if (slOpen(l,SI_LINK_OPEN,NULL)) return 1;
2184
2185 idhdl id = enterid("link_ll", 0, LINK_CMD, &IDROOT, FALSE);
2186 IDLINK(id) = l;
2187
2188 loop
2189 {
2190 leftv h=ssiRead1(l); /*contains an exit.... */
2191 if (feErrors != NULL && *feErrors != '\0')
2192 {
2193 // handle errors:
2194 PrintS(feErrors); /* currently quite simple */
2195 *feErrors = '\0';
2196 }
2197 ssiWrite(l,h);
2198 h->CleanUp();
2200 }
2201 /* never reached*/
2202 exit(0);
2203}
2204
2209int ssiReservePort(int clients)
2210{
2211 if (ssiReserved_P!=0)
2212 {
2213 WerrorS("ERROR already a reserved port requested");
2214 return 0;
2215 }
2216 int portno;
2217 ssiReserved_sockfd = socket(AF_INET, SOCK_STREAM, 0);
2218 if(ssiReserved_sockfd < 0)
2219 {
2220 WerrorS("ERROR opening socket");
2221 return 0;
2222 }
2223 memset((char *) &ssiResverd_serv_addr,0, sizeof(ssiResverd_serv_addr));
2224 portno = 1025;
2225 ssiResverd_serv_addr.sin_family = AF_INET;
2226 ssiResverd_serv_addr.sin_addr.s_addr = INADDR_ANY;
2227 do
2228 {
2229 portno++;
2230 ssiResverd_serv_addr.sin_port = htons(portno);
2231 if(portno > 50000)
2232 {
2233 WerrorS("ERROR on binding (no free port available?)");
2234 return 0;
2235 }
2236 }
2237 while(bind(ssiReserved_sockfd, (struct sockaddr *) &ssiResverd_serv_addr, sizeof(ssiResverd_serv_addr)) < 0);
2238 ssiReserved_P=portno;
2239 listen(ssiReserved_sockfd,clients);
2240 ssiReserved_Clients=clients;
2241 return portno;
2242}
2243
2244EXTERN_VAR si_link_extension si_link_root;
2246{
2247 if (ssiReserved_P==0)
2248 {
2249 WerrorS("ERROR no reserved port requested");
2250 return NULL;
2251 }
2252 struct sockaddr_in cli_addr;
2253 int clilen = sizeof(cli_addr);
2254 int newsockfd = si_accept(ssiReserved_sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
2255 if(newsockfd < 0)
2256 {
2257 Werror("ERROR on accept (errno=%d)",errno);
2258 return NULL;
2259 }
2261 si_link_extension s = si_link_root;
2262 si_link_extension prev = s;
2263 while (strcmp(s->type, "ssi") != 0)
2264 {
2265 if (s->next == NULL)
2266 {
2267 prev = s;
2268 s = NULL;
2269 break;
2270 }
2271 else
2272 {
2273 s = s->next;
2274 }
2275 }
2276 if (s != NULL)
2277 l->m = s;
2278 else
2279 {
2280 si_link_extension ns = (si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
2281 prev->next=slInitSsiExtension(ns);
2282 l->m = prev->next;
2283 }
2284 l->name=omStrDup("");
2285 l->mode=omStrDup("tcp");
2286 l->ref=1;
2287 ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
2288 l->data=d;
2289 d->fd_read = newsockfd;
2290 d->fd_write = newsockfd;
2291 d->f_read = s_open(newsockfd);
2292 d->f_write = fdopen(newsockfd, "w");
2295 if (ssiReserved_Clients<=0)
2296 {
2297 ssiReserved_P=0;
2298 si_close(ssiReserved_sockfd);
2299 }
2300 return l;
2301}
2302/*---------------------------------------------------------------------*/
2303/**
2304 * @brief additional default signal handler
2305
2306 // some newer Linux version cannot have SIG_IGN for SIGCHLD,
2307 // so use this nice routine here:
2308 // SuSe 9.x reports -1 always
2309 // Redhat 9.x/FC x reports sometimes -1
2310 // see also: hpux_system
2311 // also needed by getrusage (timer etc.)
2312
2313 @param[in] sig
2314**/
2315/*---------------------------------------------------------------------*/
2317{
2318 pid_t kidpid;
2319 int status;
2320
2321 loop
2322 {
2323 kidpid = si_waitpid(-1, &status, WNOHANG);
2324 if (kidpid==-1)
2325 {
2326 /* continue on interruption (EINTR): */
2327 if (errno == EINTR) continue;
2328 /* break on anything else (EINVAL or ECHILD according to manpage): */
2329 break;
2330 }
2331 else if (kidpid==0) break; /* no more children to process, so break */
2332
2333 //printf("Child %ld terminated\n", kidpid);
2335 while((hh!=NULL)&&(ssiToBeClosed_inactive))
2336 {
2337 if((hh->l!=NULL) && (hh->l->m->Open==ssiOpen))
2338 {
2339 ssiInfo *d = (ssiInfo *)hh->l->data;
2340 if(d->pid==kidpid)
2341 {
2343 {
2345 slClose(hh->l);
2347 break;
2348 }
2349 else break;
2350 }
2351 else hh=(link_list)hh->next;
2352 }
2353 else hh=(link_list)hh->next;
2354 }
2355 }
2356}
2357
2359{
2360 int type_id = IDTYP(h);
2361
2362 // C-proc not to be dumped, also LIB-proc not
2363 if (type_id == PROC_CMD)
2364 {
2365 if (IDPROC(h)->language == LANG_C) return FALSE;
2366 if (IDPROC(h)->libname != NULL) return FALSE;
2367 }
2368 // do not dump links
2369 if (type_id == LINK_CMD) return FALSE;
2370
2371 // do not dump ssi internal rings: ssiRing*
2372 if ((type_id == RING_CMD) && (strncmp(IDID(h),"ssiRing",7)==0))
2373 return FALSE;
2374
2375 // do not dump default cring:
2376 if (type_id == CRING_CMD)
2377 {
2378 if (strcmp(IDID(h),"ZZ")==0) return FALSE;
2379 if (strcmp(IDID(h),"QQ")==0) return FALSE;
2380 #ifdef SINGULAR_4_2
2381 if (strcmp(IDID(h),"AE")==0) return FALSE;
2382 if (strcmp(IDID(h),"QAE")==0) return FALSE;
2383 #endif
2384 }
2385
2386 command D=(command)omAlloc0(sizeof(*D));
2387 sleftv tmp;
2388 memset(&tmp,0,sizeof(tmp));
2389 tmp.rtyp=COMMAND;
2390 tmp.data=D;
2391
2392 if (type_id == PACKAGE_CMD)
2393 {
2394 // do not dump Top, Standard
2395 if ((strcmp(IDID(h), "Top") == 0)
2396 || (strcmp(IDID(h), "Standard") == 0))
2397 {
2398 omFreeSize(D,sizeof(*D));
2399 return FALSE;
2400 }
2401 package p=(package)IDDATA(h);
2402 // dump Singular-packages as LIB("...");
2403 if (p->language==LANG_SINGULAR)
2404 {
2405 D->op=LOAD_CMD;
2406 D->argc=2;
2407 D->arg1.rtyp=STRING_CMD;
2408 D->arg1.data=p->libname;
2409 D->arg2.rtyp=STRING_CMD;
2410 D->arg2.data=(char*)"with";
2411 ssiWrite(l,&tmp);
2412 omFreeSize(D,sizeof(*D));
2413 return FALSE;
2414 }
2415 // dump Singular-packages as load("...");
2416 else if (p->language==LANG_C)
2417 {
2418 D->op=LOAD_CMD;
2419 D->argc=1;
2420 D->arg1.rtyp=STRING_CMD;
2421 D->arg1.data=p->libname;
2422 ssiWrite(l,&tmp);
2423 omFreeSize(D,sizeof(*D));
2424 return FALSE;
2425 }
2426 }
2427
2428 // put type and name
2429 //Print("generic dump:%s,%s\n",IDID(h),Tok2Cmdname(IDTYP(h)));
2430 D->op='=';
2431 D->argc=2;
2432 D->arg1.rtyp=DEF_CMD;
2433 D->arg1.name=IDID(h);
2434 D->arg2.rtyp=IDTYP(h);
2435 D->arg2.data=IDDATA(h);
2436 ssiWrite(l,&tmp);
2437 omFreeSize(D,sizeof(*D));
2438 return FALSE;
2439}
2441{
2442 if (h == NULL) return FALSE;
2443
2444 if (ssiDumpIter(l, IDNEXT(h))) return TRUE;
2445
2446 // need to set the ring before writing it, otherwise we get in
2447 // trouble with minpoly
2448 if (IDTYP(h) == RING_CMD)
2449 rSetHdl(h);
2450
2451 if (DumpSsiIdhdl(l, h)) return TRUE;
2452
2453 // do not dump ssi internal rings: ssiRing*
2454 // but dump objects of all other rings
2455 if ((IDTYP(h) == RING_CMD)
2456 && (strncmp(IDID(h),"ssiRing",7)!=0))
2457 return ssiDumpIter(l, IDRING(h)->idroot);
2458 else
2459 return FALSE;
2460}
2462{
2463 idhdl h = IDROOT, rh = currRingHdl;
2465
2466 //if (! status ) status = DumpAsciiMaps(fd, h, NULL);
2467
2468 if (currRingHdl != rh) rSetHdl(rh);
2469 //fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
2470
2471 return status;
2472}
2474{
2475 ssiInfo *d=(ssiInfo*)l->data;
2476 loop
2477 {
2478 if (!SI_LINK_OPEN_P(l)) break;
2479 if (s_iseof(d->f_read)) break;
2480 leftv h=ssiRead1(l); /*contains an exit.... */
2481 if (feErrors != NULL && *feErrors != '\0')
2482 {
2483 // handle errors:
2484 PrintS(feErrors); /* currently quite simple */
2485 return TRUE;
2486 *feErrors = '\0';
2487 }
2488 h->CleanUp();
2490 }
2491 return FALSE;
2492}
2493// ----------------------------------------------------------------
2494// format
2495// 1 int %d
2496// 2 string <len> %s
2497// 3 number
2498// 4 bigint 4 %d or 3 <mpz_t>
2499// 5 ring
2500// 6 poly
2501// 7 ideal
2502// 8 matrix
2503// 9 vector
2504// 10 module
2505// 11 command
2506// 12 def <len> %s
2507// 13 proc <len> %s
2508// 14 list %d <elem1> ....
2509// 15 setring .......
2510// 16 nothing
2511// 17 intvec <len> ...
2512// 18 intmat
2513// 19 bigintmat <r> <c> ...
2514// 20 blackbox <name> <len> ...
2515// 21 attrib <bit-attrib> <len> <a-name1> <val1>... <data>
2516// 22 smatrix
2517// 23 0 <log(bitmask)> ring properties: max.exp.
2518// 23 1 <log(bitmask)> <r->IsLPRing> ring properties:LPRing
2519// 23 2 <matrix C> <matrix D> ring properties: PLuralRing
2520// 24 bigintvec <c>
2521//
2522// 98: verify version: <ssi-version> <MAX_TOK> <OPT1> <OPT2>
2523// 99: quit Singular
int BOOLEAN
Definition auxiliary.h:87
#define TRUE
Definition auxiliary.h:100
#define FALSE
Definition auxiliary.h:96
void * ADDRESS
Definition auxiliary.h:119
blackbox * getBlackboxStuff(const int t)
return the structure to the type given by t
Definition blackbox.cc:17
int blackboxIsCmd(const char *n, int &tok)
used by scanner: returns ROOT_DECL for known types (and the type number in tok)
Definition blackbox.cc:219
const CanonicalForm CFMap CFMap & N
Definition cfEzgcd.cc:56
int l
Definition cfEzgcd.cc:100
int m
Definition cfEzgcd.cc:128
int i
Definition cfEzgcd.cc:132
int k
Definition cfEzgcd.cc:99
int p
Definition cfModGcd.cc:4086
CanonicalForm cf
Definition cfModGcd.cc:4091
CanonicalForm b
Definition cfModGcd.cc:4111
FILE * f
Definition checklibs.c:9
Matrices of numbers.
Definition bigintmat.h:51
Definition idrec.h:35
Definition attrib.h:21
attr next
Definition attrib.h:26
Class used for (list of) interpreter objects.
Definition subexpr.h:83
int Typ()
Definition subexpr.cc:1048
const char * name
Definition subexpr.h:87
int rtyp
Definition subexpr.h:91
void * Data()
Definition subexpr.cc:1192
leftv next
Definition subexpr.h:86
const char * Name()
Definition subexpr.h:120
void * data
Definition subexpr.h:88
attr * Attribute()
Definition subexpr.cc:1505
BITSET flag
Definition subexpr.h:90
Definition lists.h:24
sleftv * m
Definition lists.h:46
INLINE_THIS void Init(int l=0)
int nr
Definition lists.h:44
VAR BOOLEAN singular_in_batchmode
Definition cntrlc.cc:62
static FORCE_INLINE number n_ReadFd(const ssiInfo *f, const coeffs r)
io via ssi:
Definition coeffs.h:967
static FORCE_INLINE void n_WriteFd(number a, const ssiInfo *f, const coeffs r)
io via ssi:
Definition coeffs.h:963
@ n_algExt
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic
Definition coeffs.h:35
@ n_transExt
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition coeffs.h:38
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition numbers.cc:406
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition coeffs.h:429
static FORCE_INLINE int n_GetChar(const coeffs r)
Return the characteristic of the coeff. domain.
Definition coeffs.h:448
static FORCE_INLINE char * nCoeffName(const coeffs cf)
Definition coeffs.h:956
static FORCE_INLINE number n_Init(long i, const coeffs r)
a number representing i in the given coeff field/ring r
Definition coeffs.h:539
#define Print
Definition emacs.cc:80
#define Warn
Definition emacs.cc:77
#define WarnS
Definition emacs.cc:78
const CanonicalForm int s
Definition facAbsFact.cc:51
CanonicalForm res
Definition facAbsFact.cc:60
const Variable & v
< [in] a sqrfree bivariate poly
Definition facBivar.h:39
int j
Definition facHensel.cc:110
VAR short errorreported
Definition feFopen.cc:23
void WerrorS(const char *s)
Definition feFopen.cc:24
FILE * myfopen(const char *path, const char *mode)
Definition feFopen.cc:167
const char * feSetOptValue(feOptIndex opt, char *optarg)
Definition feOpt.cc:154
VAR char my_yylinebuf[80]
Definition febase.cc:44
char * fe_fgets_dummy(const char *, char *, int)
Definition feread.cc:455
char *(* fe_fgets_stdin)(const char *pr, char *s, int size)
Definition feread.cc:32
#define D(A)
Definition gentable.cc:126
#define STATIC_VAR
Definition globaldefs.h:7
#define EXTERN_VAR
Definition globaldefs.h:6
#define VAR
Definition globaldefs.h:5
@ IDEAL_CMD
Definition grammar.cc:285
@ MATRIX_CMD
Definition grammar.cc:287
@ BUCKET_CMD
Definition grammar.cc:284
@ BIGINTMAT_CMD
Definition grammar.cc:278
@ PROC_CMD
Definition grammar.cc:281
@ INTMAT_CMD
Definition grammar.cc:280
@ MODUL_CMD
Definition grammar.cc:288
@ SMATRIX_CMD
Definition grammar.cc:292
@ VECTOR_CMD
Definition grammar.cc:293
@ BIGINTVEC_CMD
Definition grammar.cc:279
@ NUMBER_CMD
Definition grammar.cc:289
@ POLY_CMD
Definition grammar.cc:290
@ RING_CMD
Definition grammar.cc:282
idhdl enterid(const char *s, int lev, int t, idhdl *root, BOOLEAN init, BOOLEAN search)
Definition ipid.cc:258
VAR idhdl currRingHdl
Definition ipid.cc:59
VAR coeffs coeffs_BIGINT
Definition ipid.cc:50
#define IDNEXT(a)
Definition ipid.h:118
EXTERN_VAR omBin sleftv_bin
Definition ipid.h:145
ip_command * command
Definition ipid.h:23
#define IDDATA(a)
Definition ipid.h:126
#define IDPROC(a)
Definition ipid.h:140
#define IDLINK(a)
Definition ipid.h:138
#define IDID(a)
Definition ipid.h:122
#define IDROOT
Definition ipid.h:19
#define IDRING(a)
Definition ipid.h:127
#define IDTYP(a)
Definition ipid.h:119
char * iiGetLibProcBuffer(procinfo *pi, int part)
Definition iplib.cc:197
void rKill(ring r)
Definition ipshell.cc:6173
idhdl rFindHdl(ring r, idhdl n)
Definition ipshell.cc:1699
void rSetHdl(idhdl h)
Definition ipshell.cc:5121
STATIC_VAR jList * T
Definition janet.cc:30
STATIC_VAR Poly * h
Definition janet.cc:971
BOOLEAN nc_CallPlural(matrix cc, matrix dd, poly cn, poly dn, ring r, bool bSetupQuotient, bool bCopyInput, bool bBeQuiet, ring curr, bool dummy_ring=false)
returns TRUE if there were errors analyze inputs, check them for consistency detects nc_type,...
VAR omBin slists_bin
Definition lists.cc:23
#define SR_INT
Definition longrat.h:67
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition matpol.cc:37
#define MATELEM(mat, i, j)
1-based access to matrix
Definition matpol.h:29
ip_smatrix * matrix
Definition matpol.h:43
#define MATROWS(i)
Definition matpol.h:26
#define MATCOLS(i)
Definition matpol.h:27
void rem(unsigned long *a, unsigned long *q, unsigned long p, int &dega, int degq)
Definition minpoly.cc:572
#define TIMER_RESOLUTION
Definition mod2.h:35
#define assume(x)
Definition mod2.h:387
void m2_end(int i)
Definition misc_ip.cc:1100
#define p_GetComp(p, r)
Definition monomials.h:64
#define pIter(p)
Definition monomials.h:37
#define pNext(p)
Definition monomials.h:36
#define pSetCoeff0(p, n)
Definition monomials.h:59
static number & pGetCoeff(poly p)
return an alias to the leading coefficient of p assumes that p != NULL NOTE: not copy
Definition monomials.h:44
slists * lists
The main handler for Singular numbers which are suitable for Singular polynomials.
number ndReadFd(const ssiInfo *, const coeffs r)
Definition numbers.cc:150
coeffs nFindCoeffByName(char *cf_name)
find an existing coeff by its "CoeffName"
Definition numbers.cc:633
#define omStrDup(s)
#define omFreeSize(addr, size)
#define omAlloc(size)
#define omAlloc0Bin(bin)
#define omFree(addr)
#define omAlloc0(size)
#define omFreeBin(addr, bin)
#define omFreeBinAddr(addr)
#define NULL
Definition omList.c:12
VAR unsigned si_opt_2
Definition options.c:6
VAR unsigned si_opt_1
Definition options.c:5
#define TEST_OPT_PROT
Definition options.h:103
#define TEST_OPT_DEBUG
Definition options.h:108
static int index(p_Length length, p_Ord ord)
static int pLength(poly a)
Definition p_polys.h:190
static unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
set a single variable exponent @Note: VarOffset encodes the position in p->exp
Definition p_polys.h:488
static unsigned long p_SetComp(poly p, unsigned long c, ring r)
Definition p_polys.h:247
static void p_Setm(poly p, const ring r)
Definition p_polys.h:233
static long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
get a single variable exponent @Note: the integer VarOffset encodes:
Definition p_polys.h:469
static void p_Delete(poly *p, const ring r)
Definition p_polys.h:901
static poly p_Init(const ring r, omBin bin)
Definition p_polys.h:1334
#define p_Test(p, r)
Definition p_polys.h:161
void rChangeCurrRing(ring r)
Definition polys.cc:15
VAR ring currRing
Widely used global variable which specifies the current polynomial ring for Singular interpreter and ...
Definition polys.cc:13
#define NUM
Definition readcf.cc:180
void PrintS(const char *s)
Definition reporter.cc:284
VAR char * feErrors
Definition reporter.cc:47
void Werror(const char *fmt,...)
Definition reporter.cc:189
#define mflush()
Definition reporter.h:58
BOOLEAN rComplete(ring r, int force)
this needs to be called whenever a new ring is created: new fields in ring are created (like VarOffse...
Definition ring.cc:3465
void rUnComplete(ring r)
Definition ring.cc:3996
static unsigned long rGetExpSize(unsigned long bitmask, int &bits)
Definition ring.cc:2587
void rDelete(ring r)
unconditionally deletes fields in r
Definition ring.cc:452
ring rDefault(const coeffs cf, int N, char **n, int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl, unsigned long bitmask)
Definition ring.cc:103
BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
returns TRUE, if r1 equals r2 FALSE, otherwise Equality is determined componentwise,...
Definition ring.cc:1749
static BOOLEAN rField_is_Zp(const ring r)
Definition ring.h:505
static n_coeffType rFieldType(const ring r)
the type of the coefficient filed of r (n_Zp, n_Q, etc)
Definition ring.h:561
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition ring.h:405
static ring rIncRefCnt(ring r)
Definition ring.h:846
static BOOLEAN rIsLPRing(const ring r)
Definition ring.h:416
rRingOrder_t
order stuff
Definition ring.h:68
@ ringorder_a
Definition ring.h:70
@ ringorder_a64
for int64 weights
Definition ring.h:71
@ ringorder_L
Definition ring.h:90
@ ringorder_aa
for idElimination, like a, except pFDeg, pWeigths ignore it
Definition ring.h:92
@ ringorder_Wp
Definition ring.h:82
@ ringorder_ws
Definition ring.h:87
@ ringorder_Ws
Definition ring.h:88
@ ringorder_IS
Induced (Schreyer) ordering.
Definition ring.h:94
@ ringorder_wp
Definition ring.h:81
@ ringorder_M
Definition ring.h:74
static BOOLEAN rField_is_Q(const ring r)
Definition ring.h:511
static short rVar(const ring r)
#define rVar(r) (r->N)
Definition ring.h:597
idrec * idhdl
Definition ring.h:21
int raise_rlimit_nproc()
Definition rlimit.c:18
s_buff s_open(int fd)
Definition s_buff.cc:31
int s_getc(s_buff F)
Definition s_buff.cc:58
int s_isready(s_buff F)
Definition s_buff.cc:85
int s_readint(s_buff F)
Definition s_buff.cc:112
int s_close(s_buff &F)
Definition s_buff.cc:45
s_buff s_open_by_name(const char *n)
Definition s_buff.cc:39
int s_readbytes(char *buff, int len, s_buff F)
Definition s_buff.cc:168
int s_iseof(s_buff F)
Definition s_buff.cc:254
void s_ungetc(int c, s_buff F)
Definition s_buff.cc:99
int fd_write
Definition s_buff.h:26
ring rings[SI_RING_CACHE]
Definition s_buff.h:31
pid_t pid
Definition s_buff.h:25
s_buff f_read
Definition s_buff.h:22
#define SI_RING_CACHE
Definition s_buff.h:30
char send_quit_at_exit
Definition s_buff.h:28
char level
Definition s_buff.h:27
char quit_sent
Definition s_buff.h:29
FILE * f_write
Definition s_buff.h:23
ring r
Definition s_buff.h:24
int fd_read
Definition s_buff.h:26
poly sBucketPeek(sBucket_pt b)
Definition sbuckets.cc:455
ring sBucketGetRing(const sBucket_pt bucket)
Returns bucket ring.
Definition sbuckets.cc:46
sBucket * sBucket_pt
Definition sbuckets.h:16
VAR int sem_acquired[SIPC_MAX_SEMAPHORES]
Definition semaphore.c:25
static int SI_LOG2(int v)
Definition si_log2.h:6
int * status
Definition si_signals.h:61
int status int fd
Definition si_signals.h:69
int status int void * buf
Definition si_signals.h:69
ideal idInit(int idsize, int rank)
initialise an ideal / module
VAR omBin sip_sideal_bin
#define IDELEMS(i)
#define SIPC_MAX_SEMAPHORES
Definition simpleipc.h:10
#define R
Definition sirandom.c:27
#define M
Definition sirandom.c:25
sleftv * leftv
Definition structs.h:57
#define BITSET
Definition structs.h:16
#define loop
Definition structs.h:75
procinfo * procinfov
Definition structs.h:60
VAR omBin procinfo_bin
Definition subexpr.cc:42
language_defs language
Definition subexpr.h:59
@ LANG_SINGULAR
Definition subexpr.h:22
@ LANG_C
Definition subexpr.h:22
int name
New type name for int.
#define SR_HDL(A)
Definition tgb.cc:35
int getRTimer()
Definition timer.cc:150
#define IDHDL
Definition tok.h:31
@ BIGINT_CMD
Definition tok.h:38
@ CRING_CMD
Definition tok.h:56
@ LIST_CMD
Definition tok.h:118
@ INTVEC_CMD
Definition tok.h:101
@ PACKAGE_CMD
Definition tok.h:150
@ DEF_CMD
Definition tok.h:58
@ LINK_CMD
Definition tok.h:117
@ STRING_CMD
Definition tok.h:187
@ LOAD_CMD
Definition tok.h:119
@ INT_CMD
Definition tok.h:96
@ MAX_TOK
Definition tok.h:220
#define NONE
Definition tok.h:223
#define COMMAND
Definition tok.h:29
struct for passing initialization parameters to naInitChar
Definition transext.h:88