source: git/Singular/links/silink.cc @ 6b288b

jengelh-datetimespielwiese
Last change on this file since 6b288b was 6b288b, checked in by Andreas Steenpass <steenpass@…>, 9 years ago
chg: defer shutdown in slClose() (cherry picked from commit 96d98ec5e074988d6acae83de7646fc65aa7382b) Signed-off-by: Andreas Steenpass <steenpass@mathematik.uni-kl.de> Conflicts: Singular/silink.cc
  • Property mode set to 100644
File size: 9.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/*
6* ABSTRACT: general interface to links
7*/
8
9#include <stdio.h>
10#include <string.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <unistd.h>
14
15#ifdef HAVE_CONFIG_H
16#include "singularconfig.h"
17#endif /* HAVE_CONFIG_H */
18#include <kernel/mod2.h>
19#include <Singular/tok.h>
20#include <misc/options.h>
21#include <omalloc/omalloc.h>
22#include <kernel/febase.h>
23#include <Singular/subexpr.h>
24#include <Singular/ipid.h>
25#include <Singular/links/silink.h>
26#include <Singular/ipshell.h>
27#include <polys/matpol.h>
28#include <polys/monomials/ring.h>
29#include <Singular/lists.h>
30#include <kernel/ideals.h>
31#include <coeffs/numbers.h>
32#include <misc/intvec.h>
33#include <Singular/cntrlc.h>
34#include <Singular/links/ssiLink.h>
35#include <Singular/links/pipeLink.h>
36#include <Singular/si_signals.h>
37#include "feOpt.h"
38
39// #ifdef HAVE_DBM
40// #ifdef ix86_Win
41// #define USE_GDBM
42// #endif
43// #endif
44
45omBin s_si_link_extension_bin = omGetSpecBin(sizeof(s_si_link_extension));
46omBin sip_link_bin = omGetSpecBin(sizeof(sip_link));
47omBin ip_link_bin = omGetSpecBin(sizeof(ip_link));
48
49/* ====================================================================== */
50static si_link_extension slTypeInit(si_link_extension s, const char* type);
51si_link_extension si_link_root=NULL;
52
53BOOLEAN slInit(si_link l, char *istr)
54{
55  char *type = NULL, *mode = NULL, *name = NULL;
56  int i = 0, j;
57
58  // set mode and type
59  if (istr != NULL)
60  {
61    // find the first colon char in istr
62    i = 0;
63    while (istr[i] != ':' && istr[i] != '\0') i++;
64    if (istr[i] == ':')
65    {
66      // if found, set type
67      if (i > 0)
68      {
69        istr[i] = '\0';
70        type = omStrDup(istr);
71        istr[i] = ':';
72      }
73      // and check for mode
74      j = ++i;
75      while (istr[j] != ' ' && istr[j] != '\0') j++;
76      if (j > i)
77      {
78        mode = omStrDup(&(istr[i]));
79        mode[j - i] = '\0';
80      }
81      // and for the name
82      while (istr[j] == ' '&& istr[j] != '\0') j++;
83      if (istr[j] != '\0') name = omStrDup(&(istr[j]));
84    }
85    else // no colon find -- string is entire name
86    {
87      j=0;
88      while (istr[j] == ' '&& istr[j] != '\0') j++;
89      if (istr[j] != '\0') name = omStrDup(&(istr[j]));
90    }
91  }
92
93  // set the link extension
94  if (type != NULL)
95  {
96    si_link_extension s = si_link_root;
97    si_link_extension prev = s;
98
99    while (strcmp(s->type, type) != 0)
100    {
101      if (s->next == NULL)
102      {
103        prev = s;
104        s = NULL;
105        break;
106      }
107      else
108      {
109        s = s->next;
110      }
111    }
112
113    if (s != NULL)
114      l->m = s;
115    else
116    {
117      l->m = slTypeInit(prev, type);
118    }
119    omFree(type);
120  }
121  else
122    l->m = si_link_root;
123
124  if (l->m == NULL) return TRUE;
125
126  l->name = (name != NULL ? name : omStrDup(""));
127  l->mode = (mode != NULL ? mode : omStrDup(""));
128  l->ref = 1;
129  return FALSE;
130}
131
132void slCleanUp(si_link l)
133{
134  defer_shutdown++;
135  (l->ref)--;
136  if (l->ref == 0)
137  {
138    if (SI_LINK_OPEN_P(l))
139    {
140      if (l->m->Close != NULL) l->m->Close(l);
141    }
142    if ((l->data != NULL) && (l->m->Kill != NULL)) l->m->Kill(l);
143    omFree((ADDRESS)l->name);
144    omFree((ADDRESS)l->mode);
145    memset((void *) l, 0, sizeof(ip_link));
146  }
147  defer_shutdown--;
148  if (!defer_shutdown && do_shutdown) m2_end(1);
149}
150
151void slKill(si_link l)
152{
153  defer_shutdown++;
154  slCleanUp(l);
155  if ((l!=NULL) &&(l->ref == 0))
156    omFreeBin((ADDRESS)l,  ip_link_bin);
157  defer_shutdown--;
158  if (!defer_shutdown && do_shutdown) m2_end(1);
159}
160
161const char* slStatus(si_link l, const char *request)
162{
163  if (l == NULL) return "empty link";
164  else if (l->m == NULL) return "unknown link type";
165  else if (strcmp(request, "type") == 0) return l->m->type;
166  else if (strcmp(request, "mode") == 0) return l->mode;
167  else if (strcmp(request, "name") == 0) return l->name;
168  else if (strcmp(request, "exists") ==0)
169  {
170    struct stat buf;
171    if (si_lstat(l->name,&buf)==0) return "yes";
172    else return "no";
173  }
174  else if (strcmp(request, "open") == 0)
175  {
176    if (SI_LINK_OPEN_P(l)) return "yes";
177    else return "no";
178  }
179  else if (strcmp(request, "openread") == 0)
180  {
181    if (SI_LINK_R_OPEN_P(l)) return "yes";
182    else return "no";
183  }
184  else if (strcmp(request, "openwrite") == 0)
185  {
186    if (SI_LINK_W_OPEN_P(l)) return "yes";
187    else return "no";
188  }
189  else if (l->m->Status == NULL) return "unknown status request";
190  else return l->m->Status(l, request);
191}
192
193//--------------------------------------------------------------------------
194BOOLEAN slOpen(si_link l, short flag, leftv h)
195{
196  BOOLEAN res = TRUE;
197  if (l!=NULL)
198  {
199
200    if (l->m == NULL) slInit(l, ((char*)""));
201
202    if (feOptValue(FE_OPT_NO_SHELL)) {WerrorS("no links allowed");return TRUE;}
203
204    const char *c="_";;
205    if (h!=NULL) c=h->Name();
206
207    if (SI_LINK_OPEN_P(l))
208    {
209      Warn("open: link of type: %s, mode: %s, name: %s is already open",
210         l->m->type, l->mode, l->name);
211      return FALSE;
212    }
213    else if (l->m->Open != NULL)
214    {
215      res = l->m->Open(l, flag, h);
216      if (res)
217        Werror("open: Error for link %s of type: %s, mode: %s, name: %s",
218             c, l->m->type, l->mode, l->name);
219    }
220  }
221  return res;
222}
223
224BOOLEAN slPrepClose(si_link l)
225{
226
227  if(! SI_LINK_OPEN_P(l))
228    return FALSE;
229
230  BOOLEAN res = TRUE;
231  if (l->m->PrepClose != NULL)
232  {
233    res = l->m->PrepClose(l);
234    if (res)
235      Werror("close: Error for link of type: %s, mode: %s, name: %s",
236           l->m->type, l->mode, l->name);
237  }
238  return res;
239}
240
241BOOLEAN slClose(si_link l)
242{
243
244  if(! SI_LINK_OPEN_P(l))
245    return FALSE;
246
247  defer_shutdown++;
248  BOOLEAN res = TRUE;
249  if (l->m->Close != NULL)
250  {
251    res = l->m->Close(l);
252    if (res)
253      Werror("close: Error for link of type: %s, mode: %s, name: %s",
254           l->m->type, l->mode, l->name);
255  }
256  defer_shutdown--;
257  if (!defer_shutdown && do_shutdown) m2_end(1);
258  return res;
259}
260
261leftv slRead(si_link l, leftv a)
262{
263  leftv v = NULL;
264  if( ! SI_LINK_R_OPEN_P(l)) // open r ?
265  {
266#ifdef HAVE_DBM
267#ifdef USE_GDBM
268    if (! SI_LINK_CLOSE_P(l))
269      {
270        if (slClose(l)) return NULL;
271      }
272#endif
273#endif
274    if (slOpen(l, SI_LINK_READ,NULL)) return NULL;
275  }
276
277  if (SI_LINK_R_OPEN_P(l))
278  { // open r
279    if (a==NULL)
280    {
281      if (l->m->Read != NULL) v = l->m->Read(l);
282    }
283    else
284    {
285      if (l->m->Read2 != NULL) v = l->m->Read2(l,a);
286    }
287  }
288  else
289  {
290    Werror("read: Error to open link of type %s, mode: %s, name: %s for reading",
291           l->m->type, l->mode, l->name);
292    return NULL;
293  }
294
295  // here comes the eval:
296  if (v != NULL)
297  {
298    if (v->Eval() && !errorreported)
299      WerrorS("eval: failed");
300  }
301  else
302    Werror("read: Error for link of type %s, mode: %s, name: %s",
303           l->m->type, l->mode, l->name);
304  return v;
305}
306
307BOOLEAN slWrite(si_link l, leftv v)
308{
309  BOOLEAN res;
310
311  if(! SI_LINK_W_OPEN_P(l)) // open w ?
312  {
313#ifdef HAVE_DBM
314#ifdef USE_GDBM
315    if (! SI_LINK_CLOSE_P(l))
316      {
317        if (slClose(l)) return TRUE;
318      }
319#endif
320#endif
321    if (slOpen(l, SI_LINK_WRITE,NULL)) return TRUE;
322  }
323
324  if (SI_LINK_W_OPEN_P(l))
325  { // now open w
326    if (l->m->Write != NULL)
327      res = l->m->Write(l,v);
328    else
329      res = TRUE;
330
331    if (res)
332      Werror("write: Error for link of type %s, mode: %s, name: %s",
333             l->m->type, l->mode, l->name);
334    return res;
335  }
336  else
337  {
338    Werror("write: Error to open link of type %s, mode: %s, name: %s for writing",
339           l->m->type, l->mode, l->name);
340    return TRUE;
341  }
342}
343
344BOOLEAN slDump(si_link l)
345{
346  BOOLEAN res;
347
348  if(! SI_LINK_W_OPEN_P(l)) // open w ?
349  {
350    if (slOpen(l, SI_LINK_WRITE,NULL)) return TRUE;
351  }
352
353  if(SI_LINK_W_OPEN_P(l))
354  { // now open w
355    if (l->m->Dump != NULL)
356      res = l->m->Dump(l);
357    else
358      res = TRUE;
359
360    if (res)
361      Werror("dump: Error for link of type %s, mode: %s, name: %s",
362             l->m->type, l->mode, l->name);
363    if (!SI_LINK_R_OPEN_P(l)) slClose(l); // do not close r/w links
364    return res;
365  }
366  else
367  {
368    Werror("dump: Error to open link of type %s, mode: %s, name: %s for writing",
369           l->m->type, l->mode, l->name);
370    return TRUE;
371  }
372}
373
374BOOLEAN slGetDump(si_link l)
375{
376  BOOLEAN res;
377
378  if(! SI_LINK_R_OPEN_P(l)) // open r ?
379  {
380    if (slOpen(l, SI_LINK_READ,NULL)) return TRUE;
381  }
382
383  if(SI_LINK_R_OPEN_P(l))
384  { // now open r
385    if (l->m->GetDump != NULL)
386      res = l->m->GetDump(l);
387    else
388      res = TRUE;
389
390    if (res)
391      Werror("getdump: Error for link of type %s, mode: %s, name: %s",
392             l->m->type, l->mode, l->name);
393    //res|=slClose(l);
394    return res;
395  }
396  else
397  {
398    Werror("dump: Error open link of type %s, mode: %s, name: %s for reading",
399           l->m->type, l->mode, l->name);
400    return TRUE;
401  }
402}
403
404/*------------Initialization at Start-up time------------------------*/
405
406#include <Singular/links/slInit.h>
407
408static si_link_extension slTypeInit(si_link_extension s, const char* type)
409{
410  assume(s != NULL);
411  s->next = NULL;
412  si_link_extension ns = (si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
413
414  if (0) 0; // dummy
415#ifdef HAVE_DBM
416  else if (strcmp(type, "DBM") == 0)
417    s->next = slInitDBMExtension(ns);
418#endif
419#if 1
420  else if (strcmp(type, "ssi") == 0)
421    s->next = slInitSsiExtension(ns);
422#endif
423#if 1
424  else if (strcmp(type, "|") == 0)
425    s->next = slInitPipeExtension(ns);
426#endif
427  else
428  {
429    Warn("Found unknown link type: %s", type);
430    Warn("Use default link type: %s", si_link_root->type);
431    omFreeBin(ns, s_si_link_extension_bin);
432    return si_link_root;
433  }
434
435  if (s->next == NULL)
436  {
437    Werror("Can not initialize link type %s", type);
438    omFreeBin(ns, s_si_link_extension_bin);
439    return NULL;
440  }
441  return s->next;
442}
443
Note: See TracBrowser for help on using the repository browser.