My Project
Loading...
Searching...
No Matches
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
24
25typedef struct
26{
27 FILE *f_read;
28 FILE *f_write;
29 pid_t pid; /* only valid for fork/tcp mode*/
30 int fd_read,fd_write; /* only valid for fork/tcp mode*/
31 char level;
32} pipeInfo;
33
34//**************************************************************************/
35static BOOLEAN pipeOpen(si_link l, short flag, leftv /*u*/)
36{
37 if (FE_OPT_NO_SHELL_FLAG) {WerrorS("no links allowed");return TRUE;}
38 pipeInfo *d=(pipeInfo*)omAlloc0(sizeof(pipeInfo));
39 if (flag & SI_LINK_OPEN)
40 {
42 }
43 int pc[2];
44 int cp[2];
45 int err1=pipe(pc);
46 int err2=pipe(cp);
47 if (err1 || err2)
48 {
49 Werror("pipe failed with %d\n",errno);
50 omFreeSize(d,sizeof(*d));
51 return TRUE;
52 }
53 /* else */
54 pid_t pid=fork();
55 if (pid==0) /*child*/
56 {
57 /* close unnecessary pipe descriptors for a clean environment */
58 si_close(pc[1]); si_close(cp[0]);
59 /* dup pipe read/write to stdin/stdout */
60 si_dup2( pc[0], STDIN_FILENO );
61 si_dup2( cp[1], STDOUT_FILENO );
62 int r=system(l->name);
63 si_close(pc[0]);
64 si_close(cp[1]);
65 exit(r);
66 /* never reached*/
67 }
68 else if (pid>0)
69 {
70 d->pid=pid;
71 si_close(pc[0]); si_close(cp[1]);
72 d->f_read=fdopen(cp[0],"r");
73 d->fd_read=cp[0];
74 d->f_write=fdopen(pc[1],"w");
75 d->fd_write=pc[1];
77 }
78 else
79 {
80 Werror("fork failed (%d)",errno);
81 omFreeSize(d,sizeof(*d));
82 return TRUE;
83 }
84 l->data=d;
85 return FALSE;
86}
87
88//**************************************************************************/
90{
91 pipeInfo *d = (pipeInfo *)l->data;
92 if (d!=NULL)
93 {
94 BOOLEAN unidirectional=TRUE;
95 if ( (d->f_read!=NULL) && (d->f_write!=NULL))
96 unidirectional=FALSE;
97
98 if (d->f_read!=NULL)
99 {
100 fclose(d->f_read);
101 d->f_read=NULL;
104 }
105 if (unidirectional && (d->f_write!=NULL))
106 {
107 fclose(d->f_write);
108 d->f_write=NULL;
110 }
111 if (unidirectional && (d->pid!=0))
112 { kill(d->pid,15); kill(d->pid,9); }
113 }
115 return FALSE;
116}
117
118//**************************************************************************/
120{
122 pipeInfo *d = (pipeInfo *)l->data;
123 if (d!=NULL)
124 {
125 omFreeSize((ADDRESS)d,(sizeof *d));
126 }
127 l->data=NULL;
128 return FALSE;
129}
130
131//**************************************************************************/
133{
134 pipeInfo *d = (pipeInfo *)l->data;
135 leftv res=(leftv)omAlloc0(sizeof(sleftv));
136 char *s=(char *)omAlloc0(1024);
137 char *ss=fgets(s,1024,d->f_read);
138 if (ss==NULL) { omFreeSize(s,1024); pipeClose(l);return NULL; }
139 int i=strlen(s)-1;
140 if ((i>=0) && (s[i]=='\n')) s[i]='\0';
141 res->rtyp=STRING_CMD;
142 res->data=s;
143 return res;
144}
145//**************************************************************************/
148{
150 pipeInfo *d = (pipeInfo *)l->data;
151 FILE *outfile=d->f_write;;
152 BOOLEAN err=FALSE;
153 char *s;
155 while (data!=NULL)
156 {
157 s = data->String();
158 // free data ??
159 if (s!=NULL)
160 {
161 fprintf(outfile,"%s\n",s);
162 omFree((ADDRESS)s);
163 }
164 else
165 {
166 WerrorS("cannot convert to string");
167 err=TRUE;
168 }
169 if (pipeLastLink==NULL) return TRUE;
170 data = data->next;
171 }
172 fflush(outfile);
174 return err;
175}
176
177static const char* slStatusPipe(si_link l, const char* request)
178{
179 pipeInfo *d=(pipeInfo*)l->data;
180 if (d==NULL) return "not open";
181 if(strcmp(request, "read") == 0)
182 {
183 int s;
184 if ((!SI_LINK_R_OPEN_P(l)) || (feof(d->f_read))) s=0;
185 else if (FD_SETSIZE<=d->fd_read)
186 {
187 Werror("file descriptor number too high (%d)",d->fd_read);
188 s=-1;
189 }
190 else
191 {
192 fd_set mask/*, fdmask*/;
193 struct timeval wt;
194 /* Don't block. Return socket status immediately. */
195 wt.tv_sec = 0;
196 wt.tv_usec = 0;
197
198 FD_ZERO(&mask);
199 FD_SET(d->fd_read, &mask);
200 //Print("test fd %d\n",d->fd_read);
201 /* check with select: chars waiting: no -> not ready */
202 s=si_select(d->fd_read+1, &mask, NULL, NULL, &wt);
203 }
204 switch (s)
205 {
206 case 0: /* not ready */ return "not ready";
207 case -1: /*error*/ return "error";
208 default: /*1: ready ? */return "ready";
209 }
210 }
211 else if (strcmp(request, "write") == 0)
212 {
213 if (SI_LINK_W_OPEN_P(l)) return "ready";
214 return "not ready";
215 }
216 return "unknown status request";
217}
218
219si_link_extension slInitPipeExtension(si_link_extension s)
220{
221 s->Open=pipeOpen;
222 s->Close=pipeClose;
223 s->Kill=pipeKill;
224 s->Read=pipeRead1;
225 s->Read2=(slRead2Proc)NULL;
226 s->Write=pipeWrite;
227
228 s->Status=slStatusPipe;
229 s->type="pipe";
230 return s;
231}
int BOOLEAN
Definition auxiliary.h:88
#define TRUE
Definition auxiliary.h:101
#define FALSE
Definition auxiliary.h:97
void * ADDRESS
Definition auxiliary.h:120
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:765
VAR si_link pipeLastLink
Definition cntrlc.cc:61
EXTERN_VAR BOOLEAN FE_OPT_NO_SHELL_FLAG
Definition extra.cc:170
const CanonicalForm int s
Definition facAbsFact.cc:51
CanonicalForm res
Definition facAbsFact.cc:60
void WerrorS(const char *s)
Definition feFopen.cc:24
#define STDOUT_FILENO
Definition feread.cc:43
#define STDIN_FILENO
Definition fereadl.c:52
#define EXTERN_VAR
Definition globaldefs.h:6
#define omFreeSize(addr, size)
#define omFree(addr)
#define omAlloc0(size)
#define NULL
Definition omList.c:12
void Werror(const char *fmt,...)
Definition reporter.cc:189
sleftv * leftv
Definition structs.h:53
@ STRING_CMD
Definition tok.h:187