pipeLink.cc
Go to the documentation of this file.
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 "reporter/si_signals.h"
12 
13 #include "tok.h"
14 #include "ipid.h"
15 #include "subexpr.h"
16 #include "links/silink.h"
17 #include "lists.h"
18 #include "pipeLink.h"
19 
20 #include <errno.h>
21 #include <sys/types.h> /* for portability */
22 
23 typedef struct
24 {
25  FILE *f_read;
26  FILE *f_write;
27  pid_t pid; /* only valid for fork/tcp mode*/
28  int fd_read,fd_write; /* only valid for fork/tcp mode*/
29  char level;
30 } pipeInfo;
31 
32 //**************************************************************************/
33 BOOLEAN pipeOpen(si_link l, short flag, leftv /*u*/)
34 {
35  pipeInfo *d=(pipeInfo*)omAlloc0(sizeof(pipeInfo));
36  if (flag & SI_LINK_OPEN)
37  {
39  }
40  int pc[2];
41  int cp[2];
42  pipe(pc);
43  pipe(cp);
44  pid_t pid=fork();
45  if (pid==0) /*child*/
46  {
47  /* close unnecessary pipe descriptors for a clean environment */
48  si_close(pc[1]); si_close(cp[0]);
49  /* dup pipe read/write to stdin/stdout */
50  si_dup2( pc[0], STDIN_FILENO );
51  si_dup2( cp[1], STDOUT_FILENO );
52  int r=system(l->name);
53  si_close(pc[0]);
54  si_close(cp[1]);
55  exit(r);
56  /* never reached*/
57  }
58  else if (pid>0)
59  {
60  d->pid=pid;
61  si_close(pc[0]); si_close(cp[1]);
62  d->f_read=fdopen(cp[0],"r");
63  d->fd_read=cp[0];
64  d->f_write=fdopen(pc[1],"w");
65  d->fd_write=pc[1];
67  }
68  else
69  {
70  Werror("fork failed (%d)",errno);
71  omFreeSize(d,sizeof(*d));
72  return TRUE;
73  }
74  l->data=d;
75  return FALSE;
76 }
77 
78 //**************************************************************************/
80 {
81  pipeInfo *d = (pipeInfo *)l->data;
82  if (d!=NULL)
83  {
84  BOOLEAN unidirectional=TRUE;
85  if ( (d->f_read!=NULL) && (d->f_write!=NULL))
86  unidirectional=FALSE;
87 
88  if (d->f_read!=NULL)
89  {
90  fclose(d->f_read);
91  d->f_read=NULL;
94  }
95  if (unidirectional && (d->f_write!=NULL))
96  {
97  fclose(d->f_write);
98  d->f_write=NULL;
100  }
101  if (unidirectional && (d->pid!=0))
102  { kill(d->pid,15); kill(d->pid,9); }
103  }
104  else SI_LINK_SET_CLOSE_P(l);
105  return FALSE;
106 }
107 
108 //**************************************************************************/
110 {
111  if(SI_LINK_OPEN_P(l)) pipeClose(l);
112  pipeInfo *d = (pipeInfo *)l->data;
113  if (d!=NULL)
114  {
115  omFreeSize((ADDRESS)d,(sizeof *d));
116  }
117  l->data=NULL;
118  return FALSE;
119 }
120 
121 //**************************************************************************/
123 {
124  pipeInfo *d = (pipeInfo *)l->data;
125  leftv res=(leftv)omAlloc0(sizeof(sleftv));
126  char *s=(char *)omAlloc0(1024);
127  char *ss=fgets(s,1024,d->f_read);
128  if (ss==NULL) { omFreeSize(s,1024); pipeClose(l);return NULL; }
129  int i=strlen(s)-1;
130  if ((i>=0) && (s[i]=='\n')) s[i]='\0';
131  res->rtyp=STRING_CMD;
132  res->data=s;
133  return res;
134 }
135 //**************************************************************************/
136 extern si_link pipeLastLink;
138 {
140  pipeInfo *d = (pipeInfo *)l->data;
141  FILE *outfile=d->f_write;;
142  BOOLEAN err=FALSE;
143  char *s;
144  pipeLastLink=l;
145  while (data!=NULL)
146  {
147  s = data->String();
148  // free data ??
149  if (s!=NULL)
150  {
151  fprintf(outfile,"%s\n",s);
152  omFree((ADDRESS)s);
153  }
154  else
155  {
156  WerrorS("cannot convert to string");
157  err=TRUE;
158  }
159  if (pipeLastLink==NULL) return TRUE;
160  data = data->next;
161  }
162  fflush(outfile);
164  return err;
165 }
166 
167 const char* slStatusPipe(si_link l, const char* request)
168 {
169  pipeInfo *d=(pipeInfo*)l->data;
170  if (d==NULL) return "not open";
171  if(strcmp(request, "read") == 0)
172  {
173  int s;
174  if ((!SI_LINK_R_OPEN_P(l)) || (feof(d->f_read))) s=0;
175  else
176  {
177  fd_set mask/*, fdmask*/;
178  struct timeval wt;
179  /* Don't block. Return socket status immediately. */
180  wt.tv_sec = 0;
181  wt.tv_usec = 0;
182 
183  FD_ZERO(&mask);
184  FD_SET(d->fd_read, &mask);
185  //Print("test fd %d\n",d->fd_read);
186  /* check with select: chars waiting: no -> not ready */
187  s=si_select(d->fd_read+1, &mask, NULL, NULL, &wt);
188  }
189  switch (s)
190  {
191  case 0: /* not ready */ return "not ready";
192  case -1: /*error*/ return "error";
193  default: /*1: ready ? */return "ready";
194  }
195  }
196  else if (strcmp(request, "write") == 0)
197  {
198  if (SI_LINK_W_OPEN_P(l)) return "ready";
199  return "not ready";
200  }
201  return "unknown status request";
202 }
203 
204 si_link_extension slInitPipeExtension(si_link_extension s)
205 {
206  s->Open=pipeOpen;
207  s->Close=pipeClose;
208  s->Kill=pipeKill;
209  s->Read=pipeRead1;
210  s->Read2=(slRead2Proc)NULL;
211  s->Write=pipeWrite;
212 
213  s->Status=slStatusPipe;
214  s->type="pipe";
215  return s;
216 }
#define STDOUT_FILENO
Definition: feread.cc:45
const CanonicalForm int s
Definition: facAbsFact.cc:55
Class used for (list of) interpreter objects.
Definition: subexpr.h:82
#define FALSE
Definition: auxiliary.h:94
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
#define LINKAGE
Definition: mod2.h:141
#define STDIN_FILENO
Definition: fereadl.c:51
#define TRUE
Definition: auxiliary.h:98
void * ADDRESS
Definition: auxiliary.h:133
void WerrorS(const char *s)
Definition: feFopen.cc:24
char * String(void *d=NULL, BOOLEAN typed=FALSE, int dim=1)
Called for conversion to string (used by string(..), write(..),..)
Definition: subexpr.cc:783
if(yy_init)
Definition: libparse.cc:1418
CanonicalForm res
Definition: facAbsFact.cc:64
#define omFree(addr)
Definition: omAllocDecl.h:261
while(1)
Definition: libparse.cc:1442
void system(sys)
int i
Definition: cfEzgcd.cc:125
leftv next
Definition: subexpr.h:86
#define NULL
Definition: omList.c:12
int BOOLEAN
Definition: auxiliary.h:85
void Werror(const char *fmt,...)
Definition: reporter.cc:189
#define omAlloc0(size)
Definition: omAllocDecl.h:211
int l
Definition: cfEzgcd.cc:93