source: git/Singular/mpsr_sl.cc @ 237b3e4

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