source: git/Singular/mpsr_sl.cc @ a10fdf

spielwiese
Last change on this file since a10fdf was 762407, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
config.h is for sources files only FIX: config.h should only be used by source (not from inside kernel/mod2.h!) NOTE: each source file should better include mod2.h right after config.h, while headers should better not include mod2.h.
  • Property mode set to 100644
File size: 12.9 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      singular_in_batchmode=TRUE;
297      //myynest=0;
298      _exit(Batch_ReadEval(slCopy(l)));
299    }
300  }
301  else
302  {
303    /* only parent can get here */
304    return NULL;
305  }
306}
307
308
309
310LINKAGE BOOLEAN slOpenMPTcp(si_link l, short flag, leftv u)
311{
312  MP_Link_pt link = NULL;
313  char **argv;
314  int argc;
315
316  GetCmdArgs(&argc, &argv, l->name);
317
318  if (mp_Env == NULL)
319    mp_Env = MP_InitializeEnv(MP_AllocateEnv());
320
321  if (mp_Env == NULL)
322  {
323    WerrorS("Open: Error in initialization of MP environment");
324    return TRUE;
325  }
326  MP_Exit_Env_Ptr=MP_Exit_Env_sl;
327
328  if (strcmp(l->mode, "connect") == 0) link = slOpenMPConnect(argc, argv);
329  else if (strcmp(l->mode, "listen") == 0) link = slOpenMPListen(argc, argv);
330  else if (strcmp(l->mode, "launch") == 0) link = slOpenMPLaunch(argc, argv);
331  else
332  {
333    if (strcmp(l->mode, "fork") != 0)
334    {
335      if (l->mode != NULL) omFree(l->mode);
336      l->mode = omStrDup("fork");
337    }
338    link = slOpenMPFork(l, argc, argv);
339  }
340
341  FreeCmdArgs(argc, argv);
342
343  if (link != NULL)
344  {
345    MP_SET_LINK_OPTIONS(link);
346    SI_LINK_SET_RW_OPEN_P(l);
347    l->data = (void *) link;
348    return FALSE;
349  }
350  else return TRUE;
351}
352
353/***************************************************************
354 *
355 * MP general stuff
356 *
357 ***************************************************************/
358
359LINKAGE BOOLEAN slWriteMP(si_link l, leftv v)
360{
361  leftv next = (v != NULL ? v->next : (leftv) NULL);
362  mpsr_ClearError();
363
364  // writing is done with one leftv at a time
365  if (v != NULL) v->next = NULL; // hence, we need to set next to NULL
366  if (mpsr_PutMsg((MP_Link_pt) l->data, v) != mpsr_Success)
367  {
368    mpsr_PrintError((MP_Link_pt) l->data);
369    if (v != NULL) v->next = next;
370    return TRUE;
371  }
372
373  // take care of the remaining leftv's
374  while (next != NULL)
375  {
376    v->next = next;
377    v = next;
378    next = v->next;
379    v->next = NULL;
380    if (mpsr_PutMsg((MP_Link_pt) l->data, v) != mpsr_Success)
381    {
382      mpsr_PrintError((MP_Link_pt) l->data);
383      v->next = next;
384      return TRUE;
385    }
386  }
387  return FALSE;
388}
389
390LINKAGE leftv slReadMP(si_link l)
391{
392  leftv v = NULL;
393  mpsr_ClearError();
394  if (mpsr_GetMsg((MP_Link_pt) l->data, v) != mpsr_Success)
395  {
396    mpsr_PrintError((MP_Link_pt) l->data);
397    return NULL;
398  }
399  else
400    return v;
401}
402
403static void SentQuitMsg(si_link l)
404{
405  leftv v = (leftv) omAlloc0Bin(sleftv_bin);
406
407  v->rtyp = STRING_CMD;
408  v->data = (void *)MPSR_QUIT_STRING;
409  slWriteMP(l, v);
410  omFreeBin(v, sleftv_bin);
411}
412
413LINKAGE BOOLEAN slCloseMP(si_link l)
414{
415#ifdef HPUX_9
416  signal(SIGCHLD, (void (*)(int))SIG_DFL);
417#endif
418  if ((strcmp(l->mode, "launch") == 0 || strcmp(l->mode, "fork") == 0) &&
419      (MP_GetLinkStatus((MP_Link_pt)l->data,MP_LinkReadyWriting) == MP_TRUE))
420  {
421    SentQuitMsg(l);
422    //wait(NULL);
423  }
424  MP_CloseLink((MP_Link_pt) l->data);
425#ifdef HPUX_9
426  signal(SIGCHLD, (void (*)(int))SIG_IGN);
427#endif
428  SI_LINK_SET_CLOSE_P(l);
429  return FALSE;
430}
431
432LINKAGE BOOLEAN slKillMP(si_link l)
433{
434  MP_KillLink((MP_Link_pt) l->data);
435  SI_LINK_SET_CLOSE_P(l);
436  return FALSE;
437}
438
439LINKAGE BOOLEAN slDumpMP(si_link l)
440{
441  mpsr_ClearError();
442  if (mpsr_PutDump((MP_Link_pt) l->data) != mpsr_Success)
443  {
444    mpsr_PrintError((MP_Link_pt) l->data);
445    return TRUE;
446  }
447  else
448    return FALSE;
449}
450
451LINKAGE BOOLEAN slGetDumpMP(si_link l)
452{
453  mpsr_ClearError();
454  if (mpsr_GetDump((MP_Link_pt) l->data) != mpsr_Success)
455  {
456    mpsr_PrintError((MP_Link_pt) l->data);
457    return TRUE;
458  }
459  else
460    return FALSE;
461}
462
463LINKAGE const char* slStatusMP(si_link l, const char* request)
464{
465  if (strcmp(request, "read") == 0)
466  {
467    if (SI_LINK_R_OPEN_P(l) &&
468        (MP_GetLinkStatus((MP_Link_pt)l->data,MP_LinkReadyReading) == MP_TRUE))
469        return "ready";
470    else return "not ready";
471  }
472  else if (strcmp(request, "write") == 0)
473  {
474    if (SI_LINK_W_OPEN_P(l) &&
475        (MP_GetLinkStatus((MP_Link_pt)l->data,MP_LinkReadyWriting) == MP_TRUE))
476        return "ready";
477    else return "not ready";
478  }
479  else return "unknown status request";
480}
481
482/***************************************************************
483 *
484 * MP batch stuff
485 *
486 ***************************************************************/
487
488static int Batch_ReadEval(si_link silink)
489{
490  leftv v = NULL;
491  // establish top-level identifier for link
492  idhdl id = enterid(omStrDup("link_ll"), 0, LINK_CMD, &IDROOT, FALSE);
493  IDLINK(id) = silink;
494
495  // the main read-eval-write loop
496  loop
497  {
498    errorreported = FALSE;
499    v = slRead(silink, v);
500    if (feErrors != NULL && *feErrors != '\0')
501    {
502      if (v != NULL) v->CleanUp();
503      v = mpsr_InitLeftv(STRING_CMD, (void *) omStrDup(feErrors));
504      *feErrors = '\0';
505    }
506
507    // no need to evaluate -- it is done in the read
508    if (v->Typ() == STRING_CMD &&
509        (strcmp((char *)v->Data(), MPSR_QUIT_STRING)  == 0))
510    {
511      slKill(silink);
512      return 0;
513    }
514
515    slWriteMP(silink, v);
516
517    if (v != NULL)
518    {
519      v->CleanUp();
520      omFreeBin(v, sleftv_bin);
521      v = NULL;
522    }
523  }
524  // should never get here
525  return 1;
526}
527
528// #define MPSR_BATCH_DEBUG
529#ifdef MPSR_BATCH_DEBUG
530static BOOLEAN stop = 1;
531#endif
532
533
534LINKAGE int Batch_do(const char* port, const char* host)
535{
536#ifdef MPSR_BATCH_DEBUG
537  fprintf(stderr, "Was started with pid %d\n", getpid());
538  while (stop){};
539#endif
540  si_link silink = (si_link) omAlloc0Bin(sip_link_bin);
541  char *istr;
542
543  // parse argv to get port and host
544  if (port == NULL)
545  {
546    fprintf(stderr,
547            "Need '--MPport portnumber' command line argument in batch modus\n");
548    return 1;
549  }
550  if (host == NULL)
551  {
552    fprintf(stderr,
553            "Need '--MPhost hostname' command line argument in batch modus\n");
554    return 1;
555  }
556
557  // initialize si_link
558  istr = (char *) omAlloc((strlen(port) + strlen(host) + 40)*sizeof(char));
559  sprintf(istr, "MPtcp:connect --MPport %s --MPhost %s", port, host);
560  slInit(silink, istr);
561  omFree(istr);
562  // open link
563  if (slOpen(silink, SI_LINK_OPEN,NULL))
564  {
565    fprintf(stderr, "Batch side could not connect on port %s and host %s\n",
566            port, host);
567    return 1;
568  }
569
570  return Batch_ReadEval(silink);
571}
572#endif
Note: See TracBrowser for help on using the repository browser.