From 40a1a8dcd28779ebdd94e61589a482a836b33064 Mon Sep 17 00:00:00 2001 From: Frank Halasz Date: Mon, 13 May 2024 15:36:33 -0700 Subject: [PATCH] Rationalize the processing of command line args for the sysout. Fixes Issue#1703 (#503) * Rationalize the processing of command line args for the sysout. Remove most of the redundancy between what is done for sysout arg processing in xrdopt.c versus main.c. Move all of the decision making about what sysout_name to use until all args have been processed (both in xrdpopt and main). This is done in main, where the prioritization and checking is done in one place rather than spread in several places in xrdopt and main. // Order of priority: 628 // 1. Value of -sysout command line arg 629 // 2. Value of the first command line arg 630 // 3. Value of LDESRCESYSOUT env variable 631 // 4. Value of LDESOURCESYSOUT env variable 632 // 5. Value as determined by X resource manager, if any 633 // 6. Value of /home/frank/lisp.virtualmem (or lisp.vm for DOS) * In main.c moved check for sysout as first arg to before the call to read_Xoption. This will ensure that we always check the 'true' first argument even when read_Xoption modifies argv. --- src/main.c | 113 +++++++++++++++++++++++++++++++++++---------------- src/xrdopt.c | 28 ++++--------- 2 files changed, 84 insertions(+), 57 deletions(-) diff --git a/src/main.c b/src/main.c index 1d554db..1e316e1 100644 --- a/src/main.c +++ b/src/main.c @@ -229,7 +229,11 @@ int display_max = 65536 * 16 * 2; /* diagnostic flag for sysout dumping */ extern unsigned maxpages; -char sysout_name[MAXPATHLEN]; /* Set by read_Xoption, in the X version. */ +char sysout_name_cl[MAXPATHLEN] = "\0"; /* sysout name as per -sysout command line arg ; Set by read_Xoption, in the X version. */ +char sysout_name_xrm[MAXPATHLEN] = "\0"; /* sysout name as per X resource manager, if any */ +char sysout_name_first_arg[MAXPATHLEN] = "\0"; /* sysout name as per 1st command line arg, if any */ +char sysout_name[MAXPATHLEN] = "\0"; /* "final" sysout name chosen from above */ + unsigned sysout_size = 0; /* ditto */ int flushing = FALSE; /* see dbprint.h if set, all debug/trace printing will call fflush(stdout) after each printf */ @@ -338,6 +342,25 @@ int main(int argc, char *argv[]) } #endif /* MAIKO_ENABLE_FOREIGN_FUNCTION_INTERFACE */ +#ifdef PROFILE + moncontrol(0); /* initially stop sampling */ +#endif /* PROFILE */ + + // + // + // Process Command Line Arguments + // + // + + // First check if the first argument is a sysout name + // and save it away if it is in case the X windows + // arg processing changes argc/argv + if (argc > 1 && argv[1][0] != '-') { + strncpy(sysout_name_first_arg, argv[1], MAXPATHLEN); + i++; + } + + #ifdef XWINDOW read_Xoption(&argc, argv); #endif /* XWINDOW */ @@ -345,17 +368,6 @@ int main(int argc, char *argv[]) save_argc = argc; save_argv = argv; -#ifdef PROFILE - moncontrol(0); /* initially stop sampling */ -#endif /* PROFILE */ - -/* Sysout is found as follows: - If the first argument doesn't begin with '-', assume it's the sysout - Look at the environment variable LDESRCESYSOUT if that fails - Look for ~/lisp.virtualmem if that fails - Barf and print the command line if tha fails -*/ - i = 1; if (argv[i] && ((strcmp(argv[i], "-info") == 0) || (strcmp(argv[i], "-INFO") == 0))) { @@ -368,35 +380,23 @@ int main(int argc, char *argv[]) exit(0); } - if (argc > 1 && argv[1][0] != '-') { - strncpy(sysout_name, argv[1], MAXPATHLEN); - i++; - } else if ((envname = getenv("LDESRCESYSOUT")) != NULL) { - strncpy(sysout_name, envname, MAXPATHLEN); - } else if ((envname = getenv("LDESOURCESYSOUT")) != NULL) - strncpy(sysout_name, envname, MAXPATHLEN); - else { -#ifdef DOS - strncpy(sysout_name, "lisp.vm", MAXPATHLEN); -#else - if ((envname = getenv("HOME")) != NULL) { - strncpy(sysout_name, envname, MAXPATHLEN); - strncat(sysout_name, "/lisp.virtualmem", MAXPATHLEN - 17); - } -#endif /* DOS */ - } - if (access(sysout_name, R_OK)) { - perror("Couldn't find a sysout to run"); - (void)fprintf(stderr, "%s%s", helpstring, nethubHelpstring); - exit(1); - } - /* OK, sysout name is now in sysout_name, and i is moved past a supplied name */ for (; i < argc; i += 1) { /* step by 1 in case of typo */ + // NOTE: in the case of X Windows, some of the args being checked for in this loop + // have already been processed (and removed from argv) by the call to read_Xoption() + // above. (See readXoption() in xrdopt.c) + + /* Check for -sysout arg */ + if (!strcmp(argv[i], "-sysout")) { + if (argc > ++i) { + strncpy(sysout_name_cl, argv[i], MAXPATHLEN); + } + } + /* -t and -m are undocumented and somewhat dangerous... */ - if (!strcmp(argv[i], "-t")) { /**** timer interval ****/ + else if (!strcmp(argv[i], "-t")) { /**** timer interval ****/ if (argc > ++i) { errno = 0; tmpint = strtol(argv[i], (char **)NULL, 10); @@ -610,6 +610,47 @@ int main(int argc, char *argv[]) } } + // + // OK, now we can process the sysout_name + // Order of priority: + // 1. Value of -sysout command line arg + // 2. Value of the first command line arg + // 3. Value of LDESRCESYSOUT env variable + // 4. Value of LDESOURCESYSOUT env variable + // 5. Value as determined by X resource manager, if any + // 6. Value of $HOME/lisp.virtualmem (or lisp.vm for DOS) + // + if (sysout_name_cl[0] != '\0') { strncpy(sysout_name, sysout_name_cl, MAXPATHLEN); } + else if (sysout_name_first_arg[0] != '\0') { strncpy(sysout_name, sysout_name_first_arg, MAXPATHLEN); } + else if ((envname = getenv("LDESRCESYSOUT")) != NULL) { strncpy(sysout_name, envname, MAXPATHLEN); } + else if ((envname = getenv("LDESOURCESYSOUT")) != NULL) { strncpy(sysout_name, envname, MAXPATHLEN); } + else if (sysout_name_xrm[0] != '\0') { strncpy(sysout_name, sysout_name_xrm, MAXPATHLEN); } + else { +#ifdef DOS + strncpy(sysout_name, "lisp.vm", MAXPATHLEN); +#else + if ((envname = getenv("HOME")) != NULL) { + strncpy(sysout_name, envname, MAXPATHLEN); + strncat(sysout_name, "/lisp.virtualmem", MAXPATHLEN - 17); + } +#endif /* DOS */ + } + if ((sysout_name[0] == '\0') || (access(sysout_name, R_OK))) { + perror("Couldn't find a sysout to run"); + fprintf(stderr, "Looking for: %s\n", sysout_name); + (void)fprintf(stderr, "%s%s", helpstring, nethubHelpstring); + exit(1); + } + /* OK, sysout name is now in sysout_name */ + + + // + // + // End of command line arg processing + // + // + + /* Sanity checks. */ #ifdef DOS probemouse(); /* See if the mouse is connected. */ diff --git a/src/xrdopt.c b/src/xrdopt.c index 8f1c3c5..c5a4088 100644 --- a/src/xrdopt.c +++ b/src/xrdopt.c @@ -85,7 +85,8 @@ char Window_Title[255]; extern char Icon_Title[255]; char Icon_Title[255]; -extern char sysout_name[]; +extern char sysout_name_cl[]; +extern char sysout_name_xrm[]; extern unsigned sysout_size; extern int for_makeinit, please_fork, noscroll; /* diagnostic flag for sysout dumping */ @@ -181,20 +182,9 @@ void read_Xoption(int *argc, char *argv[]) print_Xusage(argv[0]); } - sysout_name[0] = '\0'; - if (*argc == 2) { /* There was probably a sysoutarg */ - (void)strncpy(sysout_name, argv[1], PATH_MAX - 1); - } else if ((envname = getenv("LDESRCESYSOUT")) != NULL) { - strncpy(sysout_name, envname, PATH_MAX - 1); - } else if ((envname = getenv("LDESOURCESYSOUT")) != NULL) - strncpy(sysout_name, envname, PATH_MAX - 1); - else { - envname = getenv("HOME"); - (void)strcat(sysout_name, envname); - (void)strcat(sysout_name, "/lisp.virtualmem"); - } - if (access(sysout_name, R_OK) != 0) { - sysout_name[0] = '\0'; + if (XrmGetResource(commandlineDB, "ldex.sysout", "Ldex.Sysout", str_type, &value) == True) { + /* Get Sysout from command line only */ + (void)strncpy(sysout_name_cl, value.addr, value.size); } /* In order to access other DB's we have to open the main display now */ @@ -244,12 +234,8 @@ void read_Xoption(int *argc, char *argv[]) (void)XrmMergeDatabases(commandlineDB, &rDB); if (XrmGetResource(rDB, "ldex.sysout", "Ldex.Sysout", str_type, &value) == True) { - /* Get Sysout */ - (void)strncpy(sysout_name, value.addr, value.size); - } - if (sysout_name[0] == '\0') { - (void)fprintf(stderr, "Couldn't find a sysout to run;\n"); - print_Xusage(argv[0]); + /* Get Sysout from x resource manager */ + (void)strncpy(sysout_name_xrm, value.addr, value.size); } if (XrmGetResource(rDB, "ldex.title", "Ldex.Title", str_type, &value) == True) {