source: git/Singular/mpsr_sl.cc @ 6ce030f

jengelh-datetimespielwiese
Last change on this file since 6ce030f was 6ce030f, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
removal of the $Id$ svn tag from everywhere NOTE: the git SHA1 may be used instead (only on special places) NOTE: the libraries Singular/LIB/*.lib still contain the marker due to our current use of svn
  • 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 *******************************************************************/
10
11#include "config.h"
12#include <kernel/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 <sys/wait.h>
23#include <Singular/mpsr.h>
24#include <Singular/tok.h>
25#include <omalloc/omalloc.h>
26#include <kernel/febase.h>
27#include <Singular/subexpr.h>
28#include <Singular/ipid.h>
29#include <Singular/silink.h>
30#include <Singular/cntrlc.h>
31#include "feOpt.h"
32
33
34static int Batch_ReadEval(si_link silink);
35
36#ifdef MPSR_DEBUG
37#define MP_SET_LINK_OPTIONS(link) \
38  if (link != NULL) \
39     MP_SetLinkOption(link,MP_LINK_LOG_MASK_OPT,MP_LOG_ALL_EVENTS)
40#else
41#define MP_SET_LINK_OPTIONS(link) ((void *) 0)
42#endif
43
44static MP_Env_pt mp_Env=NULL;
45extern void (*MP_Exit_Env_Ptr)();
46
47/* =============== general utilities ====================================== */
48static void MP_Exit_Env_sl()
49{ MP_ReleaseEnv(mp_Env); mp_Env=NULL; }
50static void FreeCmdArgs(int argc, char** argv)
51{
52  int i;
53  for (i=0; i<argc; i++)
54    omFree(argv[i]);
55
56  if (argv) omFreeSize(argv, argc*sizeof(char *));
57}
58
59static void GetCmdArgs(int *argc, char ***argv, char *str)
60{
61  if (str == NULL || str[0] == '\0')
62  {
63    *argc = 0;
64    *argv = NULL;
65  }
66  else
67  {
68    int i = 0, sl = strlen(str)+1, j;
69    char *s2=omStrDup(str);
70
71    char *appl = strstr(s2, "--MPapplication");
72    if (appl != NULL)
73    {
74      if (appl != s2) *(appl-1) = '\0';
75      i = 2;
76    }
77
78    if (appl != s2)
79    {
80      if (strtok(s2, " ") != NULL)
81      {
82        i++;
83        while (strtok(NULL," ") != NULL) i++;
84      }
85    }
86
87    *argc = i;
88    if (i>0)
89    {
90      *argv = (char **) omAlloc0(i*sizeof(char *));
91      if (appl != NULL) i -= 2;
92      if (i>0)
93      {
94        strcpy(s2,str);
95        *argv[0] = omStrDup(strtok(s2, " "));
96        for(j = 1; j <i; j++)
97          (*argv)[j] = omStrDup(strtok(NULL, " "));
98      }
99    }
100    else
101      *argv = NULL;
102
103    if (appl != NULL)
104    {
105      (*argv)[*argc -2] = omStrDup("--MPapplication");
106      (*argv)[*argc -1] = omStrDup(&(appl[15]));
107    }
108
109    omFree(s2);
110  }
111
112}
113
114/***************************************************************
115 *
116 * MPfile  specific stuff
117 *
118 ***************************************************************/
119LINKAGE BOOLEAN slOpenMPFile(si_link l, short flag, leftv u)
120{
121  const char *argv[] = {"--MPtransp", "FILE", "--MPmode", "append",
122                        "--MPfile", "/tmp/mpout"};
123  const char *mode;
124
125  MP_Link_pt link = NULL;
126
127  if (flag == SI_LINK_OPEN)
128  {
129   if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
130      flag = SI_LINK_READ;
131    else flag = SI_LINK_WRITE;
132  }
133
134  if (l->name[0] != '\0') argv[5] = l->name;
135  else l->name = omStrDup(argv[5]);
136
137
138  if (flag == SI_LINK_READ)
139  {
140    argv[3] = "read";
141    mode = "r";
142  }
143  else if (strcmp(l->mode, "w") == 0)
144  {
145    argv[3] = "write";
146    mode = "w";
147  }
148  else
149  {
150    mode = "a";
151  }
152
153  if (mp_Env == NULL)
154    mp_Env = MP_InitializeEnv(MP_AllocateEnv());
155
156  if (mp_Env == NULL || (MPT_Init(mp_Env) != MPT_Success))
157  {
158    WerrorS("Open: Error in initialization of MP environment");
159    return TRUE;
160  }
161  MP_Exit_Env_Ptr=MP_Exit_Env_sl;
162
163
164  if ((link = MP_OpenLink(mp_Env, 6, argv)) == NULL)
165    return TRUE;
166
167  MP_SET_LINK_OPTIONS(link);
168  l->data = (void *) link;
169  SI_LINK_SET_OPEN_P(l, flag);
170  omFree(l->mode);
171  l->mode = omStrDup(mode);
172  return FALSE;
173}
174
175/***************************************************************
176 *
177 * MPtcp  specific stuff
178 *
179 ***************************************************************/
180
181LINKAGE MP_Link_pt slOpenMPConnect(int n_argc, char **n_argv)
182{
183  const char *argv[] = {"--MPtransp", "TCP", "--MPmode", "connect", "--MPport",
184                       "1025",  "--MPhost", "localhost","--MPrsh","ssh"};
185
186  const char *port = IMP_GetCmdlineArg(n_argc, n_argv, "--MPport");
187  const char *host = IMP_GetCmdlineArg(n_argc, n_argv, "--MPhost");
188  const char *rsh = IMP_GetCmdlineArg(n_argc, n_argv, "--MPrsh");
189
190  if (port == NULL) port = (char*) feOptValue(FE_OPT_MPPORT);
191  if (host == NULL) host = (char*) feOptValue(FE_OPT_MPHOST);
192  if (rsh == NULL) rsh = (char*) feOptValue(FE_OPT_MPRSH);
193
194  if (port != NULL)
195    argv[5] = port;
196  if (host != NULL)
197    argv[7] = host;
198  else
199    argv[7] = mp_Env->thishost;
200  if (rsh != NULL)
201    argv[9] = rsh;
202
203  return MP_OpenLink(mp_Env, 10, argv);
204}
205
206LINKAGE MP_Link_pt slOpenMPListen(int n_argc, char **n_argv)
207{
208  const char *argv[] = {"--MPtransp", "TCP", "--MPmode", "listen",
209                       "--MPport", "1025"};
210  char *port = IMP_GetCmdlineArg(n_argc, n_argv, "--MPport");
211
212  if (port == NULL) port = (char*) feOptValue(FE_OPT_MPHOST);
213
214  if (port != NULL) argv[5] = port;
215
216  return MP_OpenLink(mp_Env, 6, argv);
217}
218
219MP_Link_pt slOpenMPLaunch(int n_argc, char **n_argv)
220{
221  const char *argv[] = {"--MPtransp", "TCP", "--MPmode", "launch",
222                       "--MPhost", "localhost",
223                       "--MPapplication", "Singular -bq  --no-warn --no-out --no-rc",
224                       "--MPrsh", "rsh"};
225  const char *appl = IMP_GetCmdlineArg(n_argc, n_argv, "--MPapplication");
226  const char *host = IMP_GetCmdlineArg(n_argc, n_argv, "--MPhost");
227  const char *rsh = IMP_GetCmdlineArg(n_argc, n_argv, "--MPrsh");
228  char* nappl = NULL;
229  MP_Link_pt link;
230  int argc = 8;
231
232  if (appl == NULL && (host == NULL ||
233                       strcmp(host, "localhost") == 0))
234  {
235    appl = feResource("Singular");
236
237    if (appl != NULL)
238    {
239      nappl = (char*) omAlloc(MAXPATHLEN + 50);
240      strcpy(nappl, appl);
241      strcat(nappl, " -bq --no-warn --no-out --no-rc");
242      appl = nappl;
243    }
244  }
245
246  if ((host == NULL)||(strcmp(host, "localhost") == 0))
247  {
248    argv[5] = mp_Env->thishost;
249  }
250  else
251    argv[5] = host;
252
253  if (appl != NULL)
254    argv[7] = appl;
255
256
257  if (rsh != NULL)
258  {
259    argv[9] = rsh;
260    argc = 10;
261  }
262
263  link = MP_OpenLink(mp_Env, argc, argv);
264  if (nappl != NULL) omFreeSize(nappl, MAXPATHLEN + 50);
265  return link;
266}
267
268LINKAGE MP_Link_pt slOpenMPFork(si_link l, int n_argc, char **n_argv)
269{
270  MP_Link_pt link = NULL;
271  const char *argv[] = {"--MPtransp", "TCP", "--MPmode", "fork", "--MPport", "1703"};
272  char *port = IMP_GetCmdlineArg(n_argc, n_argv, (char *)"--MPport");
273
274  if (port != NULL) argv[5] = port;
275
276  link = MP_OpenLink(mp_Env, 6, argv);
277  if (link != NULL)
278  {
279    if (MP_GetLinkStatus(link, MP_LinkIsParent))
280    {
281    /* parent's business */
282      if (l->name != NULL) omFree(l->name);
283      l->name = omStrDup("parent");
284      return link;
285    }
286    else
287    {
288      /* child's business -- go into batch mode */
289      if (l->name != NULL) omFree(l->name);
290      l->name = omStrDup("child");
291      MP_SET_LINK_OPTIONS(link);
292      SI_LINK_SET_RW_OPEN_P(l);
293      l->data = (void *) link;
294      fe_fgets_stdin=fe_fgets_dummy;
295      WerrorS_callback=WerrorS_batch;
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.