source: git/Singular/mpsr_sl.cc @ 8c35ba

spielwiese
Last change on this file since 8c35ba was 8c35ba, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: MP_ReleaseEnv git-svn-id: file:///usr/local/Singular/svn/trunk@10601 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    mpsr_sl.cc
6 *  Purpose: implementation of sl_link routines for MP
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 12/00
9 *  Version: $Id: mpsr_sl.cc,v 1.8 2008-02-23 17:55:46 Singular Exp $
10 *******************************************************************/
11
12#include "mod2.h"
13
14#ifdef HAVE_MPSR
15
16#include <stdio.h>
17#include <string.h>
18#include <unistd.h>
19#ifdef HPUX_9
20#include <signal.h>
21#endif
22#include "mpsr.h"
23#include "tok.h"
24#include "omalloc.h"
25#include "febase.h"
26#include "subexpr.h"
27#include "ipid.h"
28#include "silink.h"
29#include "feOpt.h"
30
31
32static int Batch_ReadEval(si_link silink);
33
34#ifdef MPSR_DEBUG
35#define MP_SET_LINK_OPTIONS(link) \
36  if (link != NULL) \
37     MP_SetLinkOption(link,MP_LINK_LOG_MASK_OPT,MP_LOG_ALL_EVENTS)
38#else
39#define MP_SET_LINK_OPTIONS(link) ((void *) 0)
40#endif
41
42static MP_Env_pt mp_Env=NULL;
43extern void (*MP_Exit_Env_Ptr)();
44
45/* =============== general utilities ====================================== */
46static void MP_Exit_Env_sl()
47{ MP_ReleaseEnv(mp_Env); mp_Env=NULL; }
48static void FreeCmdArgs(int argc, char** argv)
49{
50  int i;
51  for (i=0; i<argc; i++)
52    omFree(argv[i]);
53
54  if (argv) omFreeSize(argv, argc*sizeof(char *));
55}
56
57static void GetCmdArgs(int *argc, char ***argv, char *str)
58{
59  if (str == NULL || str[0] == '\0')
60  {
61    *argc = 0;
62    *argv = NULL;
63  }
64  else
65  {
66    int i = 0, sl = strlen(str)+1, j;
67    char *s2=omStrDup(str);
68
69    char *appl = strstr(s2, "--MPapplication");
70    if (appl != NULL)
71    {
72      if (appl != s2) *(appl-1) = '\0';
73      i = 2;
74    }
75
76    if (appl != s2)
77    {
78      if (strtok(s2, " ") != NULL)
79      {
80        i++;
81        while (strtok(NULL," ") != NULL) i++;
82      }
83    }
84
85    *argc = i;
86    if (i>0)
87    {
88      *argv = (char **) omAlloc0(i*sizeof(char *));
89      if (appl != NULL) i -= 2;
90      if (i>0)
91      {
92        strcpy(s2,str);
93        *argv[0] = omStrDup(strtok(s2, " "));
94        for(j = 1; j <i; j++)
95          (*argv)[j] = omStrDup(strtok(NULL, " "));
96      }
97    }
98    else
99      *argv = NULL;
100
101    if (appl != NULL)
102    {
103      (*argv)[*argc -2] = omStrDup("--MPapplication");
104      (*argv)[*argc -1] = omStrDup(&(appl[15]));
105    }
106
107    omFree(s2);
108  }
109
110}
111
112/***************************************************************
113 *
114 * MPfile  specific stuff
115 *
116 ***************************************************************/
117LINKAGE BOOLEAN slOpenMPFile(si_link l, short flag)
118{
119  char *argv[] = {"--MPtransp", "FILE", "--MPmode", "append",
120                  "--MPfile", "/tmp/mpout"};
121  char *mode;
122
123  MP_Link_pt link = NULL;
124
125  if (flag == SI_LINK_OPEN)
126  {
127   if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
128      flag = SI_LINK_READ;
129    else flag = SI_LINK_WRITE;
130  }
131
132  if (l->name[0] != '\0') argv[5] = l->name;
133  else l->name = omStrDup(argv[5]);
134
135
136  if (flag == SI_LINK_READ)
137  {
138    argv[3] = "read";
139    mode = "r";
140  }
141  else if (strcmp(l->mode, "w") == 0)
142  {
143    argv[3] = "write";
144    mode = "w";
145  }
146  else
147  {
148    mode = "a";
149  }
150
151  if (mp_Env == NULL)
152    mp_Env = MP_InitializeEnv(MP_AllocateEnv());
153
154  if (mp_Env == NULL || (MPT_Init(mp_Env) != MPT_Success))
155  {
156    WerrorS("Open: Error in initialization of MP environment");
157    return TRUE;
158  }
159  MP_Exit_Env_Ptr=MP_Exit_Env_sl;
160
161
162  if ((link = MP_OpenLink(mp_Env, 6, argv)) == NULL)
163    return TRUE;
164
165  MP_SET_LINK_OPTIONS(link);
166  l->data = (void *) link;
167  SI_LINK_SET_OPEN_P(l, flag);
168  omFree(l->mode);
169  l->mode = omStrDup(mode);
170  return FALSE;
171}
172
173/***************************************************************
174 *
175 * MPtcp  specific stuff
176 *
177 ***************************************************************/
178
179LINKAGE MP_Link_pt slOpenMPConnect(int n_argc, char **n_argv)
180{
181  char *argv[] = {"--MPtransp", "TCP", "--MPmode", "connect", "--MPport",
182                  "1025",  "--MPhost", "localhost","--MPrsh","ssh"};
183
184  char *port = IMP_GetCmdlineArg(n_argc, n_argv, "--MPport");
185  char *host = IMP_GetCmdlineArg(n_argc, n_argv, "--MPhost");
186  char *rsh = IMP_GetCmdlineArg(n_argc, n_argv, "--MPrsh");
187
188  if (port == NULL) port = (char*) feOptValue(FE_OPT_MPPORT);
189  if (host == NULL) host = (char*) feOptValue(FE_OPT_MPHOST);
190  if (rsh == NULL) rsh = (char*) feOptValue(FE_OPT_MPRSH);
191
192  if (port != NULL)
193    argv[5] = port;
194  if (host != NULL)
195    argv[7] = host;
196  else
197    argv[7] = mp_Env->thishost;
198  if (rsh != NULL)
199    argv[9] = rsh;
200
201  return MP_OpenLink(mp_Env, 10, argv);
202}
203
204LINKAGE MP_Link_pt slOpenMPListen(int n_argc, char **n_argv)
205{
206  char *argv[] = {"--MPtransp", "TCP", "--MPmode", "listen",
207                  "--MPport", "1025"};
208  char *port = IMP_GetCmdlineArg(n_argc, n_argv, "--MPport");
209
210  if (port == NULL) port = (char*) feOptValue(FE_OPT_MPHOST);
211
212  if (port != NULL) argv[5] = port;
213
214  return MP_OpenLink(mp_Env, 6, argv);
215}
216
217MP_Link_pt slOpenMPLaunch(int n_argc, char **n_argv)
218{
219  char *argv[] = {"--MPtransp", "TCP", "--MPmode", "launch",
220                  "--MPhost", "localhost",
221                  "--MPapplication", "Singular -bq  --no-warn --no-out --no-rc",
222                  "--MPrsh", "rsh"};
223  char *appl = IMP_GetCmdlineArg(n_argc, n_argv, "--MPapplication");
224  char *host = IMP_GetCmdlineArg(n_argc, n_argv, "--MPhost");
225  char *rsh = IMP_GetCmdlineArg(n_argc, n_argv, "--MPrsh");
226  char* nappl = NULL;
227  MP_Link_pt link;
228  int argc = 8;
229
230  if (appl == NULL && (host == NULL ||
231                       strcmp(host, "localhost") == 0))
232  {
233    appl = feResource("Singular");
234
235    if (appl != NULL)
236    {
237      nappl = (char*) omAlloc(MAXPATHLEN + 50);
238      strcpy(nappl, appl);
239      strcat(nappl, " -bq --no-warn --no-out --no-rc");
240      appl = nappl;
241    }
242  }
243
244  if ((host == NULL)||(strcmp(host, "localhost") == 0))
245  {
246    argv[5] = mp_Env->thishost;
247  }
248  else
249    argv[5] = host;
250
251  if (appl != NULL)
252    argv[7] = appl;
253
254
255  if (rsh != NULL)
256  {
257    argv[9] = rsh;
258    argc = 10;
259  }
260
261  link = MP_OpenLink(mp_Env, argc, argv);
262  if (nappl != NULL) omFreeSize(nappl, MAXPATHLEN + 50);
263  return link;
264}
265
266LINKAGE MP_Link_pt slOpenMPFork(si_link l, int n_argc, char **n_argv)
267{
268  MP_Link_pt link = NULL;
269  char *argv[] = {"--MPtransp", "TCP", "--MPmode", "fork", "--MPport", "1703"};
270  char *port = IMP_GetCmdlineArg(n_argc, n_argv, "--MPport");
271
272  if (port != NULL) argv[5] = port;
273
274  link = MP_OpenLink(mp_Env, 6, argv);
275  if (link != NULL)
276  {
277    if (MP_GetLinkStatus(link, MP_LinkIsParent))
278    {
279    /* parent's business */
280      if (l->name != NULL) omFree(l->name);
281      l->name = omStrDup("parent");
282      return link;
283    }
284    else
285    {
286      /* child's business -- go into batch mode */
287      if (l->name != NULL) omFree(l->name);
288      l->name = omStrDup("child");
289      MP_SET_LINK_OPTIONS(link);
290      SI_LINK_SET_RW_OPEN_P(l);
291      l->data = (void *) link;
292      fe_fgets_stdin=fe_fgets_dummy;
293      _exit(Batch_ReadEval(slCopy(l)));
294    }
295  }
296  else
297  {
298    /* only parent can get here */
299    return NULL;
300  }
301}
302
303
304
305LINKAGE BOOLEAN slOpenMPTcp(si_link l, short flag)
306{
307  MP_Link_pt link = NULL;
308  char **argv;
309  int argc;
310
311  GetCmdArgs(&argc, &argv, l->name);
312
313  if (mp_Env == NULL)
314    mp_Env = MP_InitializeEnv(MP_AllocateEnv());
315
316  if (mp_Env == NULL)
317  {
318    WerrorS("Open: Error in initialization of MP environment");
319    return TRUE;
320  }
321  MP_Exit_Env_Ptr=MP_Exit_Env_sl;
322
323  if (strcmp(l->mode, "connect") == 0) link = slOpenMPConnect(argc, argv);
324  else if (strcmp(l->mode, "listen") == 0) link = slOpenMPListen(argc, argv);
325  else if (strcmp(l->mode, "launch") == 0) link = slOpenMPLaunch(argc, argv);
326  else
327  {
328    if (strcmp(l->mode, "fork") != 0)
329    {
330      if (l->mode != NULL) omFree(l->mode);
331      l->mode = omStrDup("fork");
332    }
333    link = slOpenMPFork(l, argc, argv);
334  }
335
336  FreeCmdArgs(argc, argv);
337
338  if (link != NULL)
339  {
340    MP_SET_LINK_OPTIONS(link);
341    SI_LINK_SET_RW_OPEN_P(l);
342    l->data = (void *) link;
343    return FALSE;
344  }
345  else return TRUE;
346}
347
348/***************************************************************
349 *
350 * MP general stuff
351 *
352 ***************************************************************/
353
354LINKAGE BOOLEAN slWriteMP(si_link l, leftv v)
355{
356  leftv next = (v != NULL ? v->next : (leftv) NULL);
357  mpsr_ClearError();
358
359  // writing is done with one leftv at a time
360  if (v != NULL) v->next = NULL; // hence, we need to set next to NULL
361  if (mpsr_PutMsg((MP_Link_pt) l->data, v) != mpsr_Success)
362  {
363    mpsr_PrintError((MP_Link_pt) l->data);
364    if (v != NULL) v->next = next;
365    return TRUE;
366  }
367
368  // take care of the remaining leftv's
369  while (next != NULL)
370  {
371    v->next = next;
372    v = next;
373    next = v->next;
374    v->next = NULL;
375    if (mpsr_PutMsg((MP_Link_pt) l->data, v) != mpsr_Success)
376    {
377      mpsr_PrintError((MP_Link_pt) l->data);
378      v->next = next;
379      return TRUE;
380    }
381  }
382  return FALSE;
383}
384
385LINKAGE leftv slReadMP(si_link l)
386{
387  leftv v = NULL;
388  mpsr_ClearError();
389  if (mpsr_GetMsg((MP_Link_pt) l->data, v) != mpsr_Success)
390  {
391    mpsr_PrintError((MP_Link_pt) l->data);
392    return NULL;
393  }
394  else
395    return v;
396}
397
398static void SentQuitMsg(si_link l)
399{
400  leftv v = (leftv) omAlloc0Bin(sleftv_bin);
401
402  v->rtyp = STRING_CMD;
403  v->data = (void *)MPSR_QUIT_STRING;
404  slWriteMP(l, v);
405  omFreeBin(v, sleftv_bin);
406}
407
408LINKAGE BOOLEAN slCloseMP(si_link l)
409{
410#ifdef HPUX_9
411  signal(SIGCHLD, (void (*)(int))SIG_DFL);
412#endif 
413  if ((strcmp(l->mode, "launch") == 0 || strcmp(l->mode, "fork") == 0) &&
414      (MP_GetLinkStatus((MP_Link_pt)l->data,MP_LinkReadyWriting) == MP_TRUE))
415    SentQuitMsg(l);
416  MP_CloseLink((MP_Link_pt) l->data);
417#ifdef HPUX_9
418  signal(SIGCHLD, (void (*)(int))SIG_IGN);
419#endif 
420  SI_LINK_SET_CLOSE_P(l);
421  return FALSE;
422}
423
424LINKAGE BOOLEAN slKillMP(si_link l)
425{
426  MP_KillLink((MP_Link_pt) l->data);
427  SI_LINK_SET_CLOSE_P(l);
428  return FALSE;
429}
430
431LINKAGE BOOLEAN slDumpMP(si_link l)
432{
433  mpsr_ClearError();
434  if (mpsr_PutDump((MP_Link_pt) l->data) != mpsr_Success)
435  {
436    mpsr_PrintError((MP_Link_pt) l->data);
437    return TRUE;
438  }
439  else
440    return FALSE;
441}
442
443LINKAGE BOOLEAN slGetDumpMP(si_link l)
444{
445  mpsr_ClearError();
446  if (mpsr_GetDump((MP_Link_pt) l->data) != mpsr_Success)
447  {
448    mpsr_PrintError((MP_Link_pt) l->data);
449    return TRUE;
450  }
451  else
452    return FALSE;
453}
454
455LINKAGE char* slStatusMP(si_link l, char* request)
456{
457  if (strcmp(request, "read") == 0)
458  {
459    if (SI_LINK_R_OPEN_P(l) &&
460        (MP_GetLinkStatus((MP_Link_pt)l->data,MP_LinkReadyReading) == MP_TRUE))
461        return "ready";
462    else return "not ready";
463  }
464  else if (strcmp(request, "write") == 0)
465  {
466    if (SI_LINK_W_OPEN_P(l) &&
467        (MP_GetLinkStatus((MP_Link_pt)l->data,MP_LinkReadyWriting) == MP_TRUE))
468        return "ready";
469    else return "not ready";
470  }
471  else return "unknown status request";
472}
473
474/***************************************************************
475 *
476 * MP batch stuff
477 *
478 ***************************************************************/
479
480static int Batch_ReadEval(si_link silink)
481{
482  leftv v = NULL;
483  // establish top-level identifier for link
484  idhdl id = enterid(omStrDup("mp_ll"), 0, LINK_CMD, &IDROOT, FALSE);
485  IDLINK(id) = silink;
486
487  // the main read-eval-write loop
488  loop
489  {
490    errorreported = FALSE;
491    v = slRead(silink, v);
492    if (feErrors != NULL && *feErrors != '\0')
493    {
494      if (v != NULL) v->CleanUp();
495      v = mpsr_InitLeftv(STRING_CMD, (void *) omStrDup(feErrors));
496      *feErrors = '\0';
497    }
498
499    // no need to evaluate -- it is done in the read
500    if (v->Typ() == STRING_CMD &&
501        (strcmp((char *)v->Data(), MPSR_QUIT_STRING)  == 0))
502    {
503      slKill(silink);
504      return 0;
505    }
506
507    slWriteMP(silink, v);
508
509    if (v != NULL)
510    {
511      v->CleanUp();
512      omFreeBin(v, sleftv_bin);
513      v = NULL;
514    }
515  }
516  // should never get here
517  return 1;
518}
519
520// #define MPSR_BATCH_DEBUG
521#ifdef MPSR_BATCH_DEBUG
522static BOOLEAN stop = 1;
523#endif
524
525
526LINKAGE int Batch_do(const char* port, const char* host)
527{
528#ifdef MPSR_BATCH_DEBUG
529  fprintf(stderr, "Was started with pid %d\n", getpid());
530  while (stop){};
531#endif
532  si_link silink = (si_link) omAlloc0Bin(sip_link_bin);
533  char *istr;
534
535  // parse argv to get port and host
536  if (port == NULL)
537  {
538    fprintf(stderr,
539            "Need '--MPport portnumber' command line argument in batch modus\n");
540    return 1;
541  }
542  if (host == NULL)
543  {
544    fprintf(stderr,
545            "Need '--MPhost hostname' command line argument in batch modus\n");
546    return 1;
547  }
548
549  // initialize si_link
550  istr = (char *) omAlloc((strlen(port) + strlen(host) + 40)*sizeof(char));
551  sprintf(istr, "MPtcp:connect --MPport %s --MPhost %s", port, host);
552  slInit(silink, istr);
553  omFree(istr);
554  // open link
555  if (slOpen(silink, SI_LINK_OPEN))
556  {
557    fprintf(stderr, "Batch side could not connect on port %s and host %s\n",
558            port, host);
559    return 1;
560  }
561
562  return Batch_ReadEval(silink);
563}
564#endif
Note: See TracBrowser for help on using the repository browser.