source: git/Singular/ssiLink.cc @ 9f8f6a

spielwiese
Last change on this file since 9f8f6a was 9f8f6a, checked in by Hans Schoenemann <hannes@…>, 14 years ago
mpz_out_str/mpz_inp_str git-svn-id: file:///usr/local/Singular/svn/trunk@13168 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 26.5 KB
Line 
1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    ssiLink.h
6 *  Purpose: declaration of sl_link routines for ssi
7 *  Version: $Id$
8 ***************************************************************/
9#include <stdio.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <signal.h>
15#include <sys/types.h>          /* for portability */
16#include <sys/select.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <ctype.h>   /*for isdigit*/
20#include <netdb.h>
21
22
23#include "mod2.h"
24
25#include "tok.h"
26#include "ipid.h"
27#include <omalloc.h>
28#include <kernel/ring.h>
29#include <kernel/matpol.h>
30#include <kernel/ideals.h>
31#include <kernel/polys.h>
32#include <kernel/longrat.h>
33#include <kernel/ideals.h>
34#include "subexpr.h"
35#include "silink.h"
36#include "lists.h"
37#include "ssiLink.h"
38
39typedef struct
40{
41  FILE *f_read;
42  FILE *f_write;
43  ring r;
44  pid_t pid; /* only valid for fork/tcp mode*/
45  int fd_read,fd_write; /* only valid for fork/tcp mode*/
46  char level;
47} ssiInfo;
48
49// the helper functions:
50void ssiSetCurrRing(const ring r)
51{
52  if (!rEqual(r,currRing,1))
53  {
54    char name[20];
55    int nr=0;
56    do
57    { sprintf(name,"ssiRing%d",nr); nr++; }
58    while(IDROOT->get(name, 0)!=NULL);
59    idhdl h=enterid(omStrDup(name),0,RING_CMD,&IDROOT,FALSE);
60    IDRING(h)=r;
61    r->ref++;
62    rSetHdl(h);
63  }
64}
65// the implementation of the functions:
66void ssiWriteInt(ssiInfo *d,const int i)
67{
68  fprintf(d->f_write,"%d ",i);
69  //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
70}
71
72void ssiWriteString(ssiInfo *d,const char *s)
73{
74  fprintf(d->f_write,"%d %s ",strlen(s),s);
75  //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
76}
77
78
79void ssiWriteBigInt(const ssiInfo *d, const number n)
80{
81  // syntax is as follows:
82  // case 2 Q:     3 4 <int>
83  //        or     3 3 <mpz_t nominator>
84  if(SR_HDL(n) & SR_INT)
85  {
86    fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
87    //if (d->f_debug!=NULL) fprintf(d->f_debug,"bigint: short \"%ld\" ",SR_TO_INT(n));
88  }
89  else if (n->s==3)
90  {
91    fprintf(d->f_write,"3 ");
92    mpz_out_str(d->f_write,10,n->z);
93    fprintf(d->f_write," ");
94    //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
95    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"bigint: gmp \"%Zd\" ",n->z);
96  }
97  else Werror("illiegal bigint");
98}
99
100void ssiWriteNumber(const ssiInfo *d, const number n)
101{
102  // syntax is as follows:
103  // case 1 Z/p:   3 <int>
104  // case 2 Q:     3 4 <int>
105  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
106  //        or     3 1  dto.
107  //        or     3 3 <mpz_t nominator>
108  if(rField_is_Zp(d->r))
109  {
110    fprintf(d->f_write,"%d ",(int)(long)n);
111    //if (d->f_debug!=NULL) fprintf(d->f_debug,"number: \"%ld\" ",(int)(long)n);
112  }
113  else if (rField_is_Q(d->r))
114  {
115    if(SR_HDL(n) & SR_INT)
116    {
117      fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
118      //if (d->f_debug!=NULL) fprintf(d->f_debug,"number: short \"%ld\" ",SR_TO_INT(n));
119    }
120    else if (n->s<2)
121    {
122      gmp_fprintf(d->f_write,"%d %Zd %Zd ",n->s,n->z,n->n);
123      //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
124    }
125    else /*n->s==3*/
126    {
127      gmp_fprintf(d->f_write,"3 %Zd ",n->z);
128      //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
129    }
130  }
131  else WerrorS("coeff field not implemented");
132}
133
134void ssiWriteRing(ssiInfo *d,const ring r)
135{
136  /* 5 <ch> <N> <l1> <s1>....<ln> <sN> */
137  if (d->r!=NULL) rKill(d->r);
138  d->r=r;
139  d->r->ref++;
140  fprintf(d->f_write,"%d %d ",r->ch,r->N);
141
142  int i;
143  for(i=0;i<r->N;i++)
144  {
145    fprintf(d->f_write,"%d %s ",strlen(r->names[i]),r->names[i]);
146  }
147  /* number of orderings:*/
148  i=0;
149  while (r->order[i]!=0) i++;
150  fprintf(d->f_write,"%d ",i);
151  /* each ordering block: */
152  i=0;
153  while(r->order[i]!=0)
154  {
155    fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
156    i++;
157  }
158}
159
160void ssiWritePoly(ssiInfo *d, int typ, poly p)
161{
162  fprintf(d->f_write,"%d ",pLength(p));//number of terms
163  int i;
164
165  while(p!=NULL)
166  {
167    ssiWriteNumber(d,pGetCoeff(p));
168    //nWrite(fich,pGetCoeff(p));
169    fprintf(d->f_write,"%ld ",p_GetComp(p,d->r));//component
170
171    for(int j=1;j<=rVar(d->r);j++)
172    {
173      fprintf(d->f_write,"%ld ",p_GetExp(p,j,d->r ));//x^j
174    }
175    pIter(p);
176  }
177}
178
179void ssiWriteIdeal(ssiInfo *d, int typ,ideal I)
180{
181   // syntax: 7 # of elements <poly 1> <poly2>.....
182   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....
183   matrix M=(matrix)I;
184   if (typ==MATRIX_CMD)
185        fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
186   else
187     fprintf(d->f_write,"%d ",IDELEMS(I));
188
189   int i;
190   int tt;
191   if (typ==MODUL_CMD) tt=VECTOR_CMD;
192   else                tt=POLY_CMD;
193
194   for(i=0;i<IDELEMS(I);i++)
195   {
196     ssiWritePoly(d,tt,I->m[i]);
197   }
198}
199void ssiWriteCommand(si_link l, command D)
200{
201  ssiInfo *d=(ssiInfo*)l->data;
202  // syntax: <num ops> <operation> <op1> <op2> ....
203  fprintf(d->f_write,"%d %d ",D->argc,D->op);
204  if (D->argc >0) ssiWrite(l, &(D->arg1));
205  if (D->argc < 4)
206  {
207    if (D->argc >1) ssiWrite(l, &(D->arg2));
208    if (D->argc >2) ssiWrite(l, &(D->arg3));
209  }
210}
211
212void ssiWriteProc(ssiInfo *d,procinfov p)
213{
214  ssiWriteString(d,p->data.s.body);
215}
216
217void ssiWriteList(si_link l,lists dd)
218{
219  ssiInfo *d=(ssiInfo*)l->data;
220  fprintf(d->f_write,"%d ",dd->nr+1);
221  int i;
222  for(i=0;i<=dd->nr;i++)
223  {
224    ssiWrite(l,&(dd->m[i]));
225  }
226}
227
228char *ssiReadString(ssiInfo *d)
229{
230  char *buf;
231  int l;
232  fscanf(d->f_read,"%d ",&l);
233  buf=(char*)omAlloc(l+1);
234  fread(buf,1,l,d->f_read);
235  buf[l]='\0';
236  return buf;
237}
238
239int ssiReadInt(FILE *fich)
240{
241  int d;
242  fscanf(fich,"%d",&d);
243  return d;
244}
245
246number ssiReadBigInt(ssiInfo *d)
247{
248   int sub_type=-1;
249   fscanf(d->f_read,"%d",&sub_type);
250   switch(sub_type)
251   {
252   case 3:
253     {// read int or mpz_t or mpz_t, mpz_t
254       number n=nlRInit(0);
255       mpz_inp_str(n->z,d->f_read,0);
256       n->s=sub_type;
257       return n;
258     }
259   case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
260   default: Werror("error in reading number: invalid subtype %d",sub_type);
261            return NULL;
262   }
263}
264
265number ssiReadNumber(ssiInfo *d)
266{
267  if (rField_is_Q(d->r))
268  {
269     int sub_type=-1;
270     fscanf(d->f_read,"%d",&sub_type);
271     switch(sub_type)
272     {
273     case 0:
274     case 1:
275       {// read int or mpz_t or mpz_t, mpz_t
276        number n=nlRInit(0);
277        mpz_init(n->n);
278        gmp_fscanf(d->f_read,"%Zd %Zd",n->z,n->n);
279        n->s=sub_type;
280        return n;
281       }
282
283     case 3:
284       {// read int or mpz_t or mpz_t, mpz_t
285         number n=nlRInit(0);
286         gmp_fscanf(d->f_read,"%Zd",n->z);
287         n->s=sub_type;
288         return n;
289       }
290     case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
291     default: Werror("error in reading number: invalid subtype %d",sub_type);
292              return NULL;
293     }
294  }
295  else if (rField_is_Zp(d->r))
296  {
297    // read int
298    int dd;
299    fscanf(d->f_read,"%d",&dd);
300    return (number)dd;
301  }
302  else Werror("coeffs not implemented");
303  return NULL;
304}
305
306ring ssiReadRing(ssiInfo *d)
307{
308/* syntax is <ch> <N> <l1> <s1> ....<lN> <sN> */
309  int ch, N,i,l;
310  char **names;
311  fscanf(d->f_read,"%d %d ",&ch,&N);
312  names=(char**)omAlloc(N*sizeof(char*));
313  for(i=0;i<N;i++)
314  {
315    names[i]=ssiReadString(d);
316  }
317  // read the orderings:
318  int num_ord; // number of orderings
319  fscanf(d->f_read,"%d",&num_ord);
320  int *ord=(int *)omAlloc0((num_ord+1)*sizeof(int));
321  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
322  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
323  for(i=0;i<num_ord;i++)
324  {
325     fscanf(d->f_read,"%d %d %d",&ord[i],&block0[i],&block1[i]);
326  }
327  return rDefault(ch,N,names,num_ord,ord,block0,block1);
328}
329
330poly ssiReadPoly(ssiInfo *D)
331{
332// < # of terms> < term1> < .....
333  int n,i,l;
334  n=ssiReadInt(D->f_read);
335  //Print("poly: terms:%d\n",n);
336  poly p;
337  int j;
338  j=0;
339  poly ret=NULL;
340  poly prev=NULL;
341  for(l=0;l<n;l++) // read n terms
342  {
343// coef,comp.exp1,..exp N
344    p=p_Init(D->r);
345    pGetCoeff(p)=ssiReadNumber(D);
346    int d;
347    fscanf(D->f_read,"%d",&d);
348    p_SetComp(p,d,D->r);
349    for(i=1;i<=rVar(D->r);i++)
350    {
351      fscanf(D->f_read,"%d",&d);
352      p_SetExp(p,i,d,D->r);
353    }
354    p_Setm(p,D->r);
355    p_Test(p,D->r);
356    if (ret==NULL) ret=p;
357    else           pNext(prev)=p;
358    prev=p;
359 }
360 return ret;
361}
362
363ideal ssiReadIdeal(ssiInfo *d)
364{
365  int n,i;
366  ideal I;
367  fscanf(d->f_read,"%d",&n);
368  I=idInit(n,1);
369  for(i=0;i<IDELEMS(I);i++) // read n terms
370  {
371    I->m [i]=ssiReadPoly(d);
372  }
373  return I;
374}
375
376matrix ssiReadMatrix(ssiInfo *d)
377{
378  int n,m,i,j;
379  fscanf(d->f_read,"%d %d",&m,&n);
380  matrix M=mpNew(m,n);
381  poly p;
382  for(int i=1;i<=MATROWS(M);i++)
383    for(int j=1;j<=MATCOLS(M);j++)
384    {
385      p=ssiReadPoly(d);
386      MATELEM(M,i,j)=p;
387    }
388  return M;
389}
390
391command ssiReadCommand(si_link l)
392{
393  ssiInfo *d=(ssiInfo*)l->data;
394  // syntax: <num ops> <operation> <op1> <op2> ....
395  command D=(command)omAlloc0(sizeof(*D));
396  int argc,op;
397  fscanf(d->f_read,"%d %d",&argc,&op);
398  D->argc=argc; D->op=op;
399  leftv v;
400  if (argc >0)
401  {
402    v=ssiRead1(l);
403    memcpy(&(D->arg1),v,sizeof(*v));
404    omFreeBin(v,sleftv_bin);
405  }
406  if (argc <4)
407  {
408    if (D->argc >1)
409    {
410      v=ssiRead1(l);
411      memcpy(&(D->arg2),v,sizeof(*v));
412      omFreeBin(v,sleftv_bin);
413    }
414    if (D->argc >2)
415    {
416      v=ssiRead1(l);
417      memcpy(&(D->arg3),v,sizeof(*v));
418      omFreeBin(v,sleftv_bin);
419    }
420  }
421  else
422  {
423    leftv prev=&(D->arg1);
424    argc--;
425    while(argc >0)
426    {
427      v=ssiRead1(l);
428      prev->next=v;
429      prev=v;
430      argc--;
431    }
432  }
433  return D;
434}
435
436procinfov ssiReadProc(ssiInfo *d)
437{
438  char *s=ssiReadString(d);
439  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
440  p->language=LANG_SINGULAR;
441  p->libname=omStrDup("");
442  p->procname=omStrDup("");
443  p->data.s.body=s;
444  return p;
445}
446lists ssiReadList(si_link l)
447{
448  ssiInfo *d=(ssiInfo*)l->data;
449  int nr;
450  fscanf(d->f_read,"%d",&nr);
451  lists L=(lists)omAlloc(sizeof(*L));
452  L->Init(nr);
453
454  int i;
455  leftv v;
456  for(i=0;i<nr;i++)
457  {
458    v=ssiRead1(l);
459    memcpy(&(L->m[i]),v,sizeof(*v));
460    omFreeBin(v,sleftv_bin);
461  }
462  return L;
463}
464
465//**************************************************************************/
466BOOLEAN ssiOpen(si_link l, short flag)
467{
468  const char *mode;
469  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
470  if (flag & SI_LINK_OPEN)
471  {
472    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
473      flag = SI_LINK_READ;
474    else flag = SI_LINK_WRITE;
475  }
476
477  if (flag == SI_LINK_READ) mode = "r";
478  else if (strcmp(l->mode, "w") == 0) mode = "w";
479  else if (strcmp(l->mode, "fork") == 0) mode = "fork";
480  else if (strcmp(l->mode, "tcp") == 0) mode = "tcp";
481  else if (strcmp(l->mode, "connect") == 0) mode = "connect";
482  else mode = "a";
483
484
485  if (l->name[0] == '\0')
486  {
487    if (strcmp(mode,"fork")==0)
488    {
489      int pc[2];
490      int cp[2];
491      pipe(pc);
492      pipe(cp);
493      pid_t pid=fork();
494      if (pid==0) /*child*/
495      {
496        close(pc[1]); close(cp[0]);
497        d->f_read=fdopen(pc[0],"r");
498        d->fd_read=pc[0];
499        d->f_write=fdopen(cp[1],"w");
500        d->fd_write=cp[1];
501        l->data=d;
502        omFree(l->mode);
503        l->mode = omStrDup(mode);
504        SI_LINK_SET_RW_OPEN_P(l);
505        myynest=0;
506        fe_fgets_stdin=fe_fgets_dummy;
507        loop
508        {
509          leftv h=ssiRead1(l); /*contains an exit.... */
510          if (feErrors != NULL && *feErrors != '\0')
511          {
512            // handle errors:
513            PrintS(feErrors); /* currently quite simple */
514            *feErrors = '\0';
515          }
516          ssiWrite(l,h);
517          h->CleanUp();
518          omFreeBin(h, sleftv_bin);
519        }
520        /* never reached*/
521      }
522      else if (pid>0)
523      {
524        d->pid=pid;
525        close(pc[0]); close(cp[1]);
526        d->f_read=fdopen(cp[0],"r");
527        d->fd_read=cp[0];
528        d->f_write=fdopen(pc[1],"w");
529        d->fd_write=pc[1];
530        SI_LINK_SET_RW_OPEN_P(l);
531      }
532      else
533      {
534        Werror("fork failed (%d)",errno);
535      }
536    }
537    else if (strcmp(mode,"tcp")==0)
538    {
539      int sockfd, newsockfd, portno, clilen;
540      struct sockaddr_in serv_addr, cli_addr;
541      int n;
542      sockfd = socket(AF_INET, SOCK_STREAM, 0);
543      if(sockfd < 0)
544      {
545        WerrorS("ERROR opening socket");
546        return TRUE;
547      }
548      memset((char *) &serv_addr,0, sizeof(serv_addr));
549      portno = 1024;
550      serv_addr.sin_family = AF_INET;
551      serv_addr.sin_addr.s_addr = INADDR_ANY;
552      do
553      {
554        portno++;
555        serv_addr.sin_port = htons(portno);
556        if(portno > 50000)
557        {
558          WerrorS("ERROR on binding (no free port available?)");
559          return TRUE;
560        }
561      }
562      while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
563      Print("waiting on port %d\n", portno);mflush();
564      listen(sockfd,5);
565      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
566      if(newsockfd < 0)
567      {
568        WerrorS("ERROR on accept");
569        return TRUE;
570      }
571      PrintS("client accepted\n");
572      d->fd_read = newsockfd;
573      d->fd_write = newsockfd;
574      d->f_read = fdopen(newsockfd, "r");
575      d->f_write = fdopen(newsockfd, "w");
576      SI_LINK_SET_RW_OPEN_P(l);
577      close(sockfd);
578    }
579    // stdin or stdout
580    else if (flag == SI_LINK_READ)
581    {
582      d->f_read = stdin;
583      mode = "r";
584    }
585    else
586    {
587      d->f_write = stdout;
588      mode = "a";
589    }
590  }
591  else /*l->name=NULL*/
592  {
593    // tcp mode
594    if(strcmp(mode,"tcp")==0)
595    {
596      int sockfd, newsockfd, portno, clilen;
597      struct sockaddr_in serv_addr, cli_addr;
598      int n;
599      sockfd = socket(AF_INET, SOCK_STREAM, 0);
600      if(sockfd < 0)
601      {
602        WerrorS("ERROR opening socket");
603        return TRUE;
604      }
605      memset((char *) &serv_addr,0, sizeof(serv_addr));
606      portno = 1024;
607      serv_addr.sin_family = AF_INET;
608      serv_addr.sin_addr.s_addr = INADDR_ANY;
609      do
610      {
611        portno++;
612        serv_addr.sin_port = htons(portno);
613        if(portno > 50000)
614        {
615          WerrorS("ERROR on binding (no free port available?)");
616          return TRUE;
617        }
618      }
619      while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
620      //Print("waiting on port %d\n", portno);mflush();
621      listen(sockfd,5);
622      char* cli_host = (char*)omAlloc(256);
623      char* path = (char*)omAlloc(1024);
624      int r = sscanf(l->name,"%255[^:]:%s",cli_host,path);
625      if(r == 0)
626      {
627        WerrorS("ERROR: no host specified");
628        return TRUE;
629      }
630      else if(r == 1)
631      {
632        path = "Singular";
633      }
634      char* ssh_command = (char*)omAlloc(256);
635      char* ser_host = (char*)omAlloc(64);
636      gethostname(ser_host,64);
637      sprintf(ssh_command,"ssh %s %s -q --batch --link=ssi --MPhost=%s --MPport=%d &",cli_host,path,ser_host,portno);
638      system(ssh_command);
639      //Print("client on %s started:%s\n",cli_host,path);
640      clilen = sizeof(cli_addr);
641      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
642      if(newsockfd < 0)
643      {
644        WerrorS("ERROR on accept");
645        return TRUE;
646      }
647      //PrintS("client accepted\n");
648      d->fd_read = newsockfd;
649      d->fd_write = newsockfd;
650      d->f_read = fdopen(newsockfd, "r");
651      d->f_write = fdopen(newsockfd, "w");
652      SI_LINK_SET_RW_OPEN_P(l);
653      close(sockfd);
654    }
655    else if(strcmp(mode,"connect")==0)
656    {
657      char* host = (char*)omAlloc(256);
658      int sockfd, portno, n;
659      struct sockaddr_in serv_addr;
660      struct hostent *server;
661 
662      sscanf(l->name,"%255[^:]:%d",host,&portno);
663      //Print("connect to host %s, port %d\n",host,portno);mflush();
664      if (portno!=0)
665      {
666        sockfd = socket(AF_INET, SOCK_STREAM, 0);
667        if (sockfd < 0) { WerrorS("ERROR opening socket"); return TRUE; }
668        server = gethostbyname(host);
669        if (server == NULL) {  WerrorS("ERROR, no such host");  return TRUE; }
670        memset((char *) &serv_addr, 0, sizeof(serv_addr));
671        serv_addr.sin_family = AF_INET;
672        memcpy((char *)&serv_addr.sin_addr.s_addr,
673              (char *)server->h_addr,
674              server->h_length);
675        serv_addr.sin_port = htons(portno);
676        if (connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
677        { WerrorS("ERROR connecting"); return TRUE; }
678        //PrintS("connected\n");mflush();
679        d->f_read=fdopen(sockfd,"r");
680        d->fd_read=sockfd;
681        d->f_write=fdopen(sockfd,"w");
682        d->fd_write=sockfd;
683        l->data=d;
684        SI_LINK_SET_RW_OPEN_P(l);
685        omFree(host);
686      }
687      else return TRUE;
688    }
689    else
690    {
691      // normal ascii link to a file
692      FILE *outfile;
693      char *filename=l->name;
694
695      if(filename[0]=='>')
696      {
697        if (filename[1]=='>')
698        {
699          filename+=2;
700          mode = "a";
701        }
702        else
703        {
704          filename++;
705          mode="w";
706        }
707      }
708      outfile=myfopen(filename,mode);
709      if (outfile!=NULL)
710      {
711        if (strcmp(l->mode,"r")==0) d->f_read = outfile;
712        else d->f_write = outfile;
713      }
714      else
715      {
716        omFree(d);
717        return TRUE;
718      }
719    }
720  }
721  l->data=d;
722
723  omFree(l->mode);
724  l->mode = omStrDup(mode);
725  SI_LINK_SET_OPEN_P(l, flag);
726  return FALSE;
727}
728
729//**************************************************************************/
730LINKAGE BOOLEAN ssiClose(si_link l)
731{
732  ssiInfo *d = (ssiInfo *)l->data;
733  if (d!=NULL)
734  {
735    if ((strcmp(l->mode,"tcp")==0)
736    || (strcmp(l->mode,"fork")==0))
737    {
738      fprintf(d->f_write,"99\n");fflush(d->f_write);
739    }
740    if (d->f_read!=NULL) fclose(d->f_read);
741    if (d->f_write!=NULL) fclose(d->f_write);
742    if (d->r!=NULL) rKill(d->r);
743    if (d->pid!=0) { kill(d->pid,15); kill(d->pid,9); }
744    omFreeSize((ADDRESS)d,(sizeof *d));
745  }
746  l->data=NULL;
747  SI_LINK_SET_CLOSE_P(l);
748  return FALSE;
749}
750
751//**************************************************************************/
752LINKAGE leftv ssiRead1(si_link l)
753{
754  ssiInfo *d = (ssiInfo *)l->data;
755  leftv res=(leftv)omAlloc0(sizeof(sleftv));
756  int t=0;
757  fscanf(d->f_read,"%d",&t);
758  //Print("got type %d\n",t);
759  switch(t)
760  {
761    case 1:res->rtyp=INT_CMD;
762           res->data=(char *)ssiReadInt(d->f_read);
763           break;
764    case 2:res->rtyp=STRING_CMD;
765           res->data=(char *)ssiReadString(d);
766           break;
767    case 3:res->rtyp=NUMBER_CMD;
768           res->data=(char *)ssiReadNumber(d);
769           break;
770    case 4:res->rtyp=BIGINT_CMD;
771           res->data=(char *)ssiReadBigInt(d);
772           break;
773    case 15:
774    case 5:{
775             d->r=ssiReadRing(d);
776             d->r->ref++;
777             res->rtyp=RING_CMD;
778             res->data=(char*)d->r;
779             // we are in the top-level, so set the basering to d->r:
780             ssiSetCurrRing(d->r);
781             if (t==15) return ssiRead1(l);
782           }
783           break;
784    case 6:res->rtyp=POLY_CMD;
785           if (d->r==NULL) goto no_ring;
786           res->data=(char*)ssiReadPoly(d);
787           break;
788    case 7:res->rtyp=IDEAL_CMD;
789           if (d->r==NULL) goto no_ring;
790           res->data=(char*)ssiReadIdeal(d);
791           break;
792    case 8:res->rtyp=MATRIX_CMD;
793           if (d->r==NULL) goto no_ring;
794           res->data=(char*)ssiReadMatrix(d);
795           break;
796    case 9:res->rtyp=VECTOR_CMD;
797           if (d->r==NULL) goto no_ring;
798           res->data=(char*)ssiReadPoly(d);
799           break;
800    case 10:res->rtyp=MODUL_CMD;
801           if (d->r==NULL) goto no_ring;
802           res->data=(char*)ssiReadIdeal(d);
803           break;
804    case 11:
805           {
806             res->rtyp=COMMAND;
807             res->data=ssiReadCommand(l);
808             int nok=res->Eval();
809             if (nok) WerrorS("error in eval");
810             break;
811           }
812    case 12: /*DEF_CMD*/
813           {
814             res->rtyp=0;
815             res->name=(char *)ssiReadString(d);
816             int nok=res->Eval();
817             if (nok) WerrorS("error in name lookup");
818             break;
819           }
820    case 13: res->rtyp=PROC_CMD;
821             res->data=ssiReadProc(d);
822             break;
823    case 14: res->rtyp=LIST_CMD;
824             res->data=ssiReadList(l);
825             break;
826    case 16: res->rtyp=NONE; res->data=NULL;
827             break;
828    case 99: ssiClose(l); exit(0);
829    case 0: if (feof(d->f_read))
830            {
831              ssiClose(l);
832              res->rtyp=DEF_CMD;
833              break;
834            }
835    default: Werror("not implemented (t:%d)",t);
836             omFreeSize(res,sizeof(sleftv));
837             res=NULL;
838             break;
839  }
840  return res;
841no_ring: WerrorS("no ring");
842  return NULL;
843}
844//**************************************************************************/
845LINKAGE BOOLEAN ssiWrite(si_link l, leftv data)
846{
847  if(!SI_LINK_W_OPEN_P(l)) slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE);
848  ssiInfo *d = (ssiInfo *)l->data;
849  d->level++;
850  //FILE *fich=d->f;
851  while (data!=NULL)
852  {
853    int tt=data->Typ();
854    void *dd=data->Data();
855
856    switch(tt /*data->Typ()*/)
857    {
858          case NONE/* nothing*/:fprintf(d->f_write,"16 ");
859                          break;
860          case STRING_CMD: fprintf(d->f_write,"2 ");
861                           ssiWriteString(d,(char *)dd);
862                           break;
863          case INT_CMD: fprintf(d->f_write,"1 ");
864                        ssiWriteInt(d,(int)(long)dd);
865                        break;
866          case BIGINT_CMD:fprintf(d->f_write,"4 ");
867                        ssiWriteBigInt(d,(number)dd);
868                        break;
869          case NUMBER_CMD:
870                          if (d->r!=currRing)
871                          {
872                            fprintf(d->f_write,"15 ");
873                            ssiWriteRing(d,currRing);
874                            if (d->level<=1) fprintf(d->f_write,"\n");
875                          }
876                          fprintf(d->f_write,"3 ");
877                          ssiWriteNumber(d,(number)dd);
878                        break;
879          case RING_CMD:fprintf(d->f_write,"5 ");
880                        ssiWriteRing(d,(ring)dd);
881                        break;
882          case POLY_CMD:
883          case VECTOR_CMD:
884                        if (d->r!=currRing)
885                        {
886                          fprintf(d->f_write,"15 ");
887                          ssiWriteRing(d,currRing);
888                          if (d->level<=1) fprintf(d->f_write,"\n");
889                        }
890                        if(tt==POLY_CMD) fprintf(d->f_write,"6 ");
891                        else             fprintf(d->f_write,"9 ");
892                        ssiWritePoly(d,tt,(poly)dd);
893                        break;
894          case IDEAL_CMD:
895          case MODUL_CMD:
896          case MATRIX_CMD:
897                        if (d->r!=currRing)
898                        {
899                          fprintf(d->f_write,"15 ");
900                          ssiWriteRing(d,currRing);
901                          if (d->level<=1) fprintf(d->f_write,"\n");
902                        }
903                        if(tt==IDEAL_CMD)       fprintf(d->f_write,"7 ");
904                        else if(tt==MATRIX_CMD) fprintf(d->f_write,"8 ");
905                        else                    fprintf(d->f_write,"10 ");
906                        ssiWriteIdeal(d,tt,(ideal)dd);
907                        break;
908          case COMMAND:
909                   fprintf(d->f_write,"11 ");
910                   ssiWriteCommand(l,(command)dd);
911                   break;
912          case DEF_CMD: /* not evaluated stuff in quotes */
913                   fprintf(d->f_write,"12 ");
914                   ssiWriteString(d,data->Name());
915                   break;
916          case PROC_CMD:
917                   fprintf(d->f_write,"13 ");
918                   ssiWriteProc(d,(procinfov)dd);
919                   break;
920          case LIST_CMD:
921                   fprintf(d->f_write,"14 ");
922                   ssiWriteList(l,(lists)dd);
923                   break;
924          default: Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
925                   d->level=0;
926                   return TRUE;
927    }
928    if (d->level<=1) { fprintf(d->f_write,"\n"); fflush(d->f_write); }
929    data=data->next;
930  }
931  d->level--;
932  return FALSE;
933}
934
935si_link_extension slInitSsiExtension(si_link_extension s)
936{
937  s->Open=(slOpenProc)ssiOpen;
938  s->Close=(slCloseProc)ssiClose;
939  s->Kill=(slKillProc)ssiClose;
940  s->Read=(slReadProc)ssiRead1;
941  s->Read2=(slRead2Proc)NULL;
942  s->Write=(slWriteProc)ssiWrite;
943
944  s->Status=slStatusSsi;
945  s->type="ssi";
946  return s;
947}
948const char* slStatusSsi(si_link l, const char* request)
949{
950  ssiInfo *d=(ssiInfo*)l->data;
951  if (d==NULL) return "not open";
952  if (((strcmp(l->mode,"fork")==0)||(strcmp(l->mode,"tcp")==0))
953  && (strcmp(request, "read") == 0))
954  {
955    fd_set  mask, fdmask;
956    struct timeval wt;
957    loop
958    {
959      /* Don't block. Return socket status immediately. */
960      wt.tv_sec  = 0;
961      wt.tv_usec = 0;
962
963      FD_ZERO(&mask);
964      FD_SET(d->fd_read, &mask);
965      //Print("test fd %d\n",d->fd_read);
966    /* check with select: chars waiting: no -> not ready */
967      switch (select(d->fd_read+1, &mask, NULL, NULL, &wt))
968      {
969        case 0: /* not ready */ return "not ready";
970        case -1: /*error*/      return "error";
971        case 1: /*ready ? */    break;
972      }
973    /* yes: read 1 char*/
974    /* if \n, check again with select else ungetc(c), ready*/
975      int c=fgetc(d->f_read);
976      //Print("try c=%d\n",c);
977      if (c== -1) return "eof";
978      else if (isdigit(c))
979      { ungetc(c,d->f_read); return "ready"; }
980      else if (c>' ')
981      {
982        Werror("unknown char in ssiLink(%d)",c);
983        return "error";
984      }
985      /* else: next char */
986    }
987  }
988  else if (strcmp(request, "read") == 0)
989  {
990    if (SI_LINK_R_OPEN_P(l) && (!feof(d->f_read))) return "ready";
991    else return "not ready";
992  }
993  else if (strcmp(request, "write") == 0)
994  {
995    if (SI_LINK_W_OPEN_P(l)) return "ready";
996    else return "not ready";
997  }
998  else return "unknown status request";
999}
1000
1001int ssiBatch(const char *host, const char * port)
1002/* return 0 on success, >0 else*/
1003{
1004  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
1005  char *buf=(char*)omAlloc(256);
1006  sprintf(buf,"ssi:connect %s:%s",host,port);
1007  slInit(l, buf);
1008  slOpen(l,SI_LINK_OPEN);
1009  SI_LINK_SET_RW_OPEN_P(l);
1010  loop
1011  {
1012    leftv h=ssiRead1(l); /*contains an exit.... */
1013    if (feErrors != NULL && *feErrors != '\0')
1014    {
1015      // handle errors:
1016      PrintS(feErrors); /* currently quite simple */
1017      *feErrors = '\0';
1018    }
1019    ssiWrite(l,h);
1020    h->CleanUp();
1021    omFreeBin(h, sleftv_bin);
1022  }
1023  /* never reached*/
1024  exit(0);
1025}
1026
1027// ----------------------------------------------------------------
1028// format
1029// 1 int %d
1030// 2 string <len> %s
1031// 3 number
1032// 4 bigint 4 %d or 3 <mpz_t>
1033// 5 ring
1034// 6 poly
1035// 7 ideal
1036// 8 matrix
1037// 9 vector
1038// 10 module
1039// 11 command
1040// 12 def <len> %s
1041// 13 proc <len> %s
1042// 14 list %d <elem1> ....
1043// 15 setring .......
1044// 16 nothing
1045//
1046// 99: quit Singular
Note: See TracBrowser for help on using the repository browser.