source: git/Singular/mpsr_sl.cc @ 131ab78

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