source: git/Singular/mpsr_sl.cc @ b5f276e

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