My Project
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
23typedef 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//**************************************************************************/
33static 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 }
105 return FALSE;
106}
107
108//**************************************************************************/
110{
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//**************************************************************************/
138{
140 pipeInfo *d = (pipeInfo *)l->data;
141 FILE *outfile=d->f_write;;
142 BOOLEAN err=FALSE;
143 char *s;
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
167static 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
204si_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}
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
void * ADDRESS
Definition: auxiliary.h:119
int l
Definition: cfEzgcd.cc:100
int i
Definition: cfEzgcd.cc:132
Class used for (list of) interpreter objects.
Definition: subexpr.h:83
leftv next
Definition: subexpr.h:86
char * String(void *d=NULL, BOOLEAN typed=FALSE, int dim=1)
Called for conversion to string (used by string(..), write(..),..)
Definition: subexpr.cc:761
const CanonicalForm int s
Definition: facAbsFact.cc:51
CanonicalForm res
Definition: facAbsFact.cc:60
void WerrorS(const char *s)
Definition: feFopen.cc:24
if(!FE_OPT_NO_SHELL_FLAG)(void) system(sys)
#define STDOUT_FILENO
Definition: feread.cc:43
#define STDIN_FILENO
Definition: fereadl.c:52
#define EXTERN_VAR
Definition: globaldefs.h:6
while(1)
Definition: libparse.cc:1444
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
#define omFree(addr)
Definition: omAllocDecl.h:261
#define omAlloc0(size)
Definition: omAllocDecl.h:211
#define NULL
Definition: omList.c:12
void Werror(const char *fmt,...)
Definition: reporter.cc:189
@ STRING_CMD
Definition: tok.h:185