source: git/Singular/mpsr_sl.cc @ 60dcbbc

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