source: git/Singular/links/pipeLink.cc @ 117e00e

fieker-DuValspielwiese
Last change on this file since 117e00e was 117e00e, checked in by Hans Schoenemann <hannes@…>, 6 years ago
removed unused system includes, math.h ->cmath for .cc files
  • Property mode set to 100644
File size: 5.1 KB
Line 
1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    pipeLink.h
6 *  Purpose: declaration of sl_link routines for pipe
7 ***************************************************************/
8
9#include "kernel/mod2.h"
10
11#include "omalloc/omalloc.h"
12#include "reporter/si_signals.h"
13
14#include "tok.h"
15#include "ipid.h"
16#include "subexpr.h"
17#include "links/silink.h"
18#include "lists.h"
19#include "pipeLink.h"
20
21#include <errno.h>
22#include <sys/types.h>          /* for portability */
23
24typedef struct
25{
26  FILE *f_read;
27  FILE *f_write;
28  pid_t pid; /* only valid for fork/tcp mode*/
29  int fd_read,fd_write; /* only valid for fork/tcp mode*/
30  char level;
31} pipeInfo;
32
33//**************************************************************************/
34BOOLEAN pipeOpen(si_link l, short flag, leftv /*u*/)
35{
36  pipeInfo *d=(pipeInfo*)omAlloc0(sizeof(pipeInfo));
37  if (flag & SI_LINK_OPEN)
38  {
39      flag = SI_LINK_READ| SI_LINK_WRITE;
40  }
41  int pc[2];
42  int cp[2];
43  pipe(pc);
44  pipe(cp);
45  pid_t pid=fork();
46  if (pid==0) /*child*/
47  {
48    /* close unnecessary pipe descriptors for a clean environment */
49    si_close(pc[1]); si_close(cp[0]);
50    /* dup pipe read/write to stdin/stdout */
51    si_dup2( pc[0], STDIN_FILENO );
52    si_dup2( cp[1], STDOUT_FILENO  );
53    int r=system(l->name);
54    si_close(pc[0]);
55    si_close(cp[1]);
56    exit(r);
57        /* never reached*/
58  }
59  else if (pid>0)
60  {
61    d->pid=pid;
62    si_close(pc[0]); si_close(cp[1]);
63    d->f_read=fdopen(cp[0],"r");
64    d->fd_read=cp[0];
65    d->f_write=fdopen(pc[1],"w");
66    d->fd_write=pc[1];
67    SI_LINK_SET_RW_OPEN_P(l);
68  }
69  else
70  {
71    Werror("fork failed (%d)",errno);
72    omFreeSize(d,sizeof(*d));
73    return TRUE;
74  }
75  l->data=d;
76  return FALSE;
77}
78
79//**************************************************************************/
80LINKAGE BOOLEAN pipeClose(si_link l)
81{
82  pipeInfo *d = (pipeInfo *)l->data;
83  if (d!=NULL)
84  {
85    BOOLEAN unidirectional=TRUE;
86    if ( (d->f_read!=NULL) &&  (d->f_write!=NULL))
87      unidirectional=FALSE;
88
89    if (d->f_read!=NULL)
90    {
91      fclose(d->f_read);
92      d->f_read=NULL;
93      SI_LINK_SET_CLOSE_P(l);
94      SI_LINK_SET_R_OPEN_P(l);
95    }
96    if (unidirectional && (d->f_write!=NULL))
97    {
98      fclose(d->f_write);
99      d->f_write=NULL;
100      SI_LINK_SET_CLOSE_P(l);
101    }
102    if (unidirectional && (d->pid!=0))
103    { kill(d->pid,15); kill(d->pid,9); }
104  }
105  else SI_LINK_SET_CLOSE_P(l);
106  return FALSE;
107}
108
109//**************************************************************************/
110LINKAGE BOOLEAN pipeKill(si_link l)
111{
112  if(SI_LINK_OPEN_P(l)) pipeClose(l);
113  pipeInfo *d = (pipeInfo *)l->data;
114  if (d!=NULL)
115  {
116    omFreeSize((ADDRESS)d,(sizeof *d));
117  }
118  l->data=NULL;
119  return FALSE;
120}
121
122//**************************************************************************/
123LINKAGE leftv pipeRead1(si_link l)
124{
125  pipeInfo *d = (pipeInfo *)l->data;
126  leftv res=(leftv)omAlloc0(sizeof(sleftv));
127  char *s=(char *)omAlloc0(1024);
128  char *ss=fgets(s,1024,d->f_read);
129  if (ss==NULL) { omFreeSize(s,1024); pipeClose(l);return NULL; }
130  int i=strlen(s)-1;
131  if ((i>=0) && (s[i]=='\n')) s[i]='\0';
132  res->rtyp=STRING_CMD;
133  res->data=s;
134  return res;
135}
136//**************************************************************************/
137extern si_link pipeLastLink;
138LINKAGE BOOLEAN pipeWrite(si_link l, leftv data)
139{
140  if(!SI_LINK_W_OPEN_P(l)) slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL);
141  pipeInfo *d = (pipeInfo *)l->data;
142  FILE *outfile=d->f_write;;
143  BOOLEAN err=FALSE;
144  char *s;
145  pipeLastLink=l;
146  while (data!=NULL)
147  {
148    s = data->String();
149    // free data ??
150    if (s!=NULL)
151    {
152      fprintf(outfile,"%s\n",s);
153      omFree((ADDRESS)s);
154    }
155    else
156    {
157      WerrorS("cannot convert to string");
158      err=TRUE;
159    }
160    if (pipeLastLink==NULL) return TRUE;
161    data = data->next;
162  }
163  fflush(outfile);
164  pipeLastLink=NULL;
165  return err;
166}
167
168const char* slStatusPipe(si_link l, const char* request)
169{
170  pipeInfo *d=(pipeInfo*)l->data;
171  if (d==NULL) return "not open";
172  if(strcmp(request, "read") == 0)
173  {
174    int s;
175    if ((!SI_LINK_R_OPEN_P(l)) || (feof(d->f_read))) s=0;
176    else
177    {
178      fd_set  mask/*, fdmask*/;
179      struct timeval wt;
180      /* Don't block. Return socket status immediately. */
181      wt.tv_sec  = 0;
182      wt.tv_usec = 0;
183
184      FD_ZERO(&mask);
185      FD_SET(d->fd_read, &mask);
186      //Print("test fd %d\n",d->fd_read);
187      /* check with select: chars waiting: no -> not ready */
188      s=si_select(d->fd_read+1, &mask, NULL, NULL, &wt);
189    }
190    switch (s)
191    {
192      case 0: /* not ready */ return "not ready";
193      case -1: /*error*/      return "error";
194      default: /*1: ready ? */return "ready";
195    }
196  }
197  else if (strcmp(request, "write") == 0)
198  {
199    if (SI_LINK_W_OPEN_P(l)) return "ready";
200    return "not ready";
201  }
202  return "unknown status request";
203}
204
205si_link_extension slInitPipeExtension(si_link_extension s)
206{
207  s->Open=pipeOpen;
208  s->Close=pipeClose;
209  s->Kill=pipeKill;
210  s->Read=pipeRead1;
211  s->Read2=(slRead2Proc)NULL;
212  s->Write=pipeWrite;
213
214  s->Status=slStatusPipe;
215  s->type="pipe";
216  return s;
217}
Note: See TracBrowser for help on using the repository browser.