version 1.5, 2025/03/09 15:20:18
|
version 1.15, 2025/05/16 04:02:14
|
Line 1
|
Line 1
|
/* |
/* |
* * |
* $Id$ |
* * * |
|
* * * |
|
* *************** |
|
* * * * * |
|
* * MUMPS * |
|
* * * * * |
|
* *************** |
|
* * * |
|
* * * |
|
* * |
|
* |
|
* init.c |
|
* FreeM initialization |
* FreeM initialization |
* |
* |
* |
* |
* Author: Serena Willis <snw@coherent-logic.com> |
* Author: Serena Willis <snw@coherent-logic.com> |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 2020 Coherent Logic Development LLC |
* Copyright (C) 2020, 2025 Coherent Logic Development LLC |
* |
* |
* |
* |
* This file is part of FreeM. |
* This file is part of FreeM. |
Line 35
|
Line 23
|
* You should have received a copy of the GNU Affero Public License |
* You should have received a copy of the GNU Affero Public License |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* |
* |
|
* $Log$ |
|
* Revision 1.15 2025/05/16 04:02:14 snw |
|
* Make FreeM build on macOS on Apple Silicon |
|
* |
|
* Revision 1.14 2025/04/20 03:13:17 snw |
|
* Updates to init_execution_context |
|
* |
|
* Revision 1.13 2025/04/17 14:34:27 snw |
|
* Further logging improvements |
|
* |
|
* Revision 1.12 2025/04/15 14:39:06 snw |
|
* Further improvements to logging |
|
* |
|
* Revision 1.11 2025/04/13 04:22:43 snw |
|
* Fix snprintf calls |
|
* |
|
* Revision 1.10 2025/04/10 01:24:38 snw |
|
* Remove C++ style comments |
|
* |
|
* Revision 1.9 2025/04/03 16:58:34 snw |
|
* Make error message for shm_init error during initialization more friendly |
|
* |
|
* Revision 1.8 2025/03/24 04:44:55 snw |
|
* Don't call ttyname on OS/2 |
|
* |
|
* Revision 1.7 2025/03/24 04:05:36 snw |
|
* Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2 |
|
* |
|
* Revision 1.6 2025/03/09 19:14:25 snw |
|
* First phase of REUSE compliance and header reformat |
|
* |
|
* |
|
* SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC |
|
* SPDX-License-Identifier: AGPL-3.0-or-later |
**/ |
**/ |
|
|
#include <stdio.h> |
#include <stdio.h> |
Line 66
|
Line 88
|
# include <termios.h> |
# include <termios.h> |
#endif |
#endif |
|
|
|
#if defined(__APPLE__) |
|
# define termio termios |
|
# define TCGETA TIOCGETA |
|
# define TCSETA TIOCSETA |
|
#endif |
|
|
#include "config.h" |
#include "config.h" |
|
|
#if defined(HAVE_MWAPI_MOTIF) |
#if defined(HAVE_MWAPI_MOTIF) |
Line 82
|
Line 110
|
#include "jobtab.h" |
#include "jobtab.h" |
#include "datatypes.h" |
#include "datatypes.h" |
#include "objects.h" |
#include "objects.h" |
|
#include "log.h" |
|
|
#ifdef HAVE_LIBREADLINE |
#ifdef HAVE_LIBREADLINE |
# if defined(HAVE_READLINE_READLINE_H) |
# if defined(HAVE_READLINE_READLINE_H) |
Line 155 void init_mwapi(void);
|
Line 184 void init_mwapi(void);
|
short init (char *namespace_name) |
short init (char *namespace_name) |
{ |
{ |
short retval; |
short retval; |
|
int log_level; |
|
|
|
init_log (); |
init_process (); |
init_process (); |
init_devtable (); |
init_devtable (); |
init_signals (); |
init_signals (); |
Line 178 short init (char *namespace_name)
|
Line 209 short init (char *namespace_name)
|
retval = shm_init (shm_init_size); |
retval = shm_init (shm_init_size); |
|
|
if (retval == SHMS_GET_ERR) { |
if (retval == SHMS_GET_ERR) { |
fprintf (stderr, "init: error initializing shared memory [errno %d]\r\n", errno); |
if (errno != 13) { |
exit (1); |
logprintf (FM_LOG_FATAL, "init: error initializing shared memory (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
else { |
|
logprintf (FM_LOG_FATAL, "init: error attaching to environment -- does your user belong to the group that owns environment '%s'?", shm_env); |
|
} |
} |
} |
|
|
symtab_init (); |
symtab_init (); |
Line 188 short init (char *namespace_name)
|
Line 223 short init (char *namespace_name)
|
set_namespace (namespace_name, FALSE); |
set_namespace (namespace_name, FALSE); |
|
|
if (first_process) { |
if (first_process) { |
fprintf (stderr, "init: we are the first process in the environment (pid %d)\r\n", pid); |
log_level = FM_LOG_INFO; |
|
} |
|
else { |
|
log_level = FM_LOG_DEBUG; |
|
} |
|
|
|
if (first_process) { |
|
logprintf (log_level, "init: we are the first process in the environment (pid %d)", pid); |
} |
} |
|
|
if (first_process) fprintf (stderr, "init: initializing job table\r\n"); |
logprintf (log_level, "init: initializing job table"); |
jobtab_init (); |
jobtab_init (); |
|
|
if (first_process) fprintf (stderr, "init: adding job to job table\r\n"); |
logprintf (log_level, "init: adding job to job table"); |
job_init (FALSE); |
job_init (FALSE); |
|
|
if (first_process) fprintf (stderr, "init: initializing structured system variables\r\n"); |
logprintf (log_level, "init: initializing structured system variables"); |
init_ssvn (); |
init_ssvn (); |
|
|
if (first_process) fprintf (stderr, "init: initializing terminal\r\n"); |
logprintf (log_level, "init: initializing terminal"); |
init_terminal (); |
init_terminal (); |
|
|
if (first_process) fprintf (stderr, "init: initializing asynchronous events\r\n"); |
logprintf (log_level, "init: initializing asynchronous events"); |
evt_init (); |
evt_init (); |
|
|
if (first_process) fprintf (stderr, "init: initializing debugger\r\n"); |
logprintf (log_level, "init: initializing debugger"); |
dbg_init (); |
dbg_init (); |
|
|
if (first_process) fprintf (stderr, "init: initializing error stack\r\n"); |
logprintf (log_level, "init: initializing error stack"); |
init_estack(); |
init_estack(); |
|
|
etrap[0] = EOL; |
etrap[0] = EOL; |
Line 229 void init_process (void)
|
Line 271 void init_process (void)
|
{ |
{ |
pid = getpid (); /* get $J = process ID */ |
pid = getpid (); /* get $J = process ID */ |
umask (0); /* protection bits mask to full rights */ |
umask (0); /* protection bits mask to full rights */ |
snprintf (fp_conversion, 9, "%%.%df\201", DBL_DIG); |
snprintf (fp_conversion, sizeof (fp_conversion) - 1, "%%.%df\201", DBL_DIG); |
|
|
if (fp_mode) { |
if (fp_mode) { |
zprecise = DBL_DIG; |
zprecise = DBL_DIG; |
Line 368 void init_timezone (void)
|
Line 410 void init_timezone (void)
|
|
|
long clock; |
long clock; |
|
|
#ifdef __CYGWIN__ |
#if defined(__CYGWIN__) |
|
|
tzset (); /* may be required in order */ |
tzset (); /* may be required in order */ |
/* to guarantee _timezone set */ |
/* to guarantee _timezone set */ |
#else |
#else |
Line 438 void init_readline (void)
|
Line 479 void init_readline (void)
|
pw_buf = (char *) calloc (strlen(pw->pw_dir) + 1, sizeof(char)); |
pw_buf = (char *) calloc (strlen(pw->pw_dir) + 1, sizeof(char)); |
strcpy (pw_buf, pw->pw_dir); |
strcpy (pw_buf, pw->pw_dir); |
|
|
snprintf (history_file, 256, "%s/.freem_history", pw_buf); |
snprintf (history_file, sizeof (history_file) - 1, "%s/.freem_history", pw_buf); |
|
|
free (pw_buf); |
free (pw_buf); |
|
|
Line 457 void init_execution_context (void)
|
Line 498 void init_execution_context (void)
|
|
|
codptr = code; |
codptr = code; |
code[0] = EOL; /* init code_pointer */ |
code[0] = EOL; /* init code_pointer */ |
partition = calloc ((unsigned) (PSIZE + 2), 1); |
|
|
|
if (partition == NULL) exit (2); /* could not allocate stuff... */ |
if ((partition = calloc ((unsigned) (PSIZE + 2), 1)) == NULL) { |
|
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate symbol table (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
|
for (i = 0; i < MAXNO_OF_RBUF; i++) { |
for (i = 0; i < MAXNO_OF_RBUF; i++) { |
rbuf_flags[i].standard = standard; |
rbuf_flags[i].standard = standard; |
Line 473 void init_execution_context (void)
|
Line 515 void init_execution_context (void)
|
s = &partition[PSIZE] - 256; /* pointer to symlen_offset */ |
s = &partition[PSIZE] - 256; /* pointer to symlen_offset */ |
argptr = partition; /* pointer to beg of tmp-storage */ |
argptr = partition; /* pointer to beg of tmp-storage */ |
|
|
svntable = calloc ((unsigned) (UDFSVSIZ + 1), 1); |
if ((svntable = calloc ((unsigned) (UDFSVSIZ + 1), 1)) == NULL) { |
if (svntable == NULL) exit (2); /* could not allocate stuff... */ |
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate user-defined ISV table (error code %d [%s])", errno, strerror (errno)); |
|
} |
svnlen = UDFSVSIZ; /* begin of udf_svn_table */ |
svnlen = UDFSVSIZ; /* begin of udf_svn_table */ |
buff = calloc ((unsigned) NO_OF_RBUF * (unsigned) PSIZE0, 1); /* routine buffer pool */ |
|
if (buff == NULL) exit (2); /* could not allocate stuff... */ |
|
|
|
|
if ((buff = calloc ((unsigned) NO_OF_RBUF * (unsigned) PSIZE0, 1)) == NULL) { |
|
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate routine buffers (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
|
newstack = calloc ((unsigned) NSIZE, 1); |
if ((newstack = calloc ((unsigned) NSIZE, 1)) == NULL) { |
if (newstack == NULL) exit (2); /* could not allocate stuff... */ |
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate NEW stack (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
|
#ifdef DEBUG_NEWPTR |
logprintf (FM_LOG_DEBUG, "allocating newptr stack..."); |
printf("Allocating newptr stack...\r\n"); |
|
#endif |
|
|
|
newptr = newstack; |
newptr = newstack; |
newlimit = newstack + NSIZE - 1024; |
newlimit = newstack + NSIZE - 1024; |
|
|
|
|
namstck = calloc ((unsigned) NESTLEVLS * 13, 1); |
if ((namstck = calloc ((unsigned) NESTLEVLS * 13, 1)) == NULL) { |
if (namstck == NULL) exit (2); /* could not allocate stuff... */ |
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate newptr stack (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
|
*namstck = EOL; |
*namstck = EOL; |
*(namstck + 1) = EOL; |
*(namstck + 1) = EOL; |
namptr = namstck; /* routine name stack pointer */ |
namptr = namstck; /* routine name stack pointer */ |
framstck = calloc ((unsigned) NESTLEVLS * 256, 1); |
|
if (framstck == NULL) exit (2); /* could not allocate stuff... */ |
if ((framstck = calloc ((unsigned) NESTLEVLS * 256, 1)) == NULL) { |
|
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate DO frame stack stack (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
|
*framstck = EOL; |
*framstck = EOL; |
*(framstck + 1) = EOL; |
*(framstck + 1) = EOL; |
dofrmptr = framstck; /* DO_frame stack pointer */ |
dofrmptr = framstck; /* DO_frame stack pointer */ |
cmdstack = calloc ((unsigned) NESTLEVLS * 256, 1); |
|
if (cmdstack == NULL) exit (2); /* could not allocate stuff... */ |
if ((cmdstack = calloc ((unsigned) NESTLEVLS * 256, 1)) == NULL) { |
|
logprintf (FM_LOG_FATAL, "init_execution_context: could not allocate command stack (error code %d [%s])", errno, strerror (errno)); |
|
} |
|
|
cmdptr = cmdstack; /* command stack */ |
cmdptr = cmdstack; /* command stack */ |
|
|
Line 531 void init_mwapi (void)
|
Line 578 void init_mwapi (void)
|
gtk_init (0, NULL); |
gtk_init (0, NULL); |
} |
} |
*/ |
*/ |
//TODO: init Motif/libXt |
/* TODO: init Motif/libXt */ |
} |
} |
#else |
#else |
void init_mwapi (void) |
void init_mwapi (void) |
Line 552 void init_io (void)
|
Line 599 void init_io (void)
|
sq_modes[0] = '+'; |
sq_modes[0] = '+'; |
for (i = 0; i <= MAXDEV; ug_buf[i++][0] = EOL); /* init read-buffers */ |
for (i = 0; i <= MAXDEV; ug_buf[i++][0] = EOL); /* init read-buffers */ |
|
|
crlf[HOME] = frm_filter; |
frm_crlf[HOME] = frm_filter; |
|
|
if (hardcopy) zbreakon = ENABLE; /* enable CTRL/B */ |
if (hardcopy) zbreakon = ENABLE; /* enable CTRL/B */ |
|
|
set_io (MUMPS); /* set i/o parameters */ |
set_io (MUMPS); /* set i/o parameters */ |
|
|
#if !defined(__AMIGA) |
#if !defined(__AMIGA) && !defined(__OS2__) |
if (ttyname (HOME)) { /* for $IO of HOME */ |
if (ttyname (HOME)) { /* for $IO of HOME */ |
strcpy (dev[HOME], ttyname (HOME)); |
strcpy (dev[HOME], ttyname (HOME)); |
dev[HOME][strlen (dev[HOME])] = EOL; |
dev[HOME][strlen (dev[HOME])] = EOL; |
Line 567 void init_io (void)
|
Line 614 void init_io (void)
|
dev[HOME][0] = EOL; /* ...we are in a pipe */ |
dev[HOME][0] = EOL; /* ...we are in a pipe */ |
} |
} |
#else |
#else |
|
#if defined(__AMIGA) |
strcpy (dev[HOME], "CONSOLE:"); |
strcpy (dev[HOME], "CONSOLE:"); |
|
#else |
|
#if defined(__OS2__) |
|
strcpy (dev[HOME], "CON:"); |
|
#endif |
|
#endif |
#endif |
#endif |
|
|
/* init function keys */ |
/* init function keys */ |
Line 640 void cleanup (void)
|
Line 693 void cleanup (void)
|
int ch; |
int ch; |
|
|
/* remove this job's entry from ^$JOB SSVN */ |
/* remove this job's entry from ^$JOB SSVN */ |
snprintf (k_buf, 255, "^$JOB\202%d\201", pid); |
snprintf (k_buf, sizeof (k_buf) - 1, "^$JOB\202%d\201", pid); |
symtab_shm (kill_sym, k_buf, " \201"); |
symtab_shm (kill_sym, k_buf, " \201"); |
|
|
reset_terminal (); |
reset_terminal (); |