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