source: git/Singular/pipeLink.cc @ f69c6c

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