Skip to content

Reference-Standard-M/rsm

Repository files navigation

Reference Standard M

fws logo

ANSI/MDC Standard M X11.1-1995 (ISO/IEC 11756:1999)

Version 1.83.0 - 2026 Jun 8

Developed and maintained by David Wicksell <dlw@linux.com>
Copyright © 2020-2026 Fourth Watch Software LC
https://gitlab.com/Reference-Standard-M/rsm

Derived from MUMPS V1 by Raymond Douglas Newman
Copyright © 1999-2018
https://gitlab.com/Reference-Standard-M/mumpsv1

Reference Standard M (RSM) is free software, licensed under the GNU Affero General Public License version 3 or later (AGPL-3.0-or-later).

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License (AGPL) as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.

Full license text: AGPL-3.0-or-later

Summary and Information

Reference Standard M (RSM) is an implementation of the M programming language and database, which implements the latest M standard that has been released by the M Development Committee (MDC), currently ANSI/MDC X11.1-1995 (ISO/IEC 11756:1999).

RSM is derived from MUMPS V1 (MV1), originally authored by Raymond Douglas Newman, and renamed to better reflect its use as a reference implementation for the MDC. See the Notice for full attribution, provenance, and licensing information.

See the Changelog for more information on the development of Reference Standard M. The RSM documentation is a work-in-progress. This software uses semantic versioning.

This is the post-relational database.

Installation

RSM builds and runs on most UNIX and UNIX-derived platforms, on 64-bit and 32-bit processors, in little-endian or big-endian byte order. The platforms that have been tested, or are known (or suspected) to build and run RSM, are:

  • Linux on x86_64, and i386 where distributions still ship images (see below)

    • Ubuntu on x86_64, and i386 before 19.10

    • Debian on x86_64, and i386 before Debian 13

    • Red Hat on x86_64, and i386 before RHEL 7

    • Fedora on x86_64, and i386 before Fedora 31

    • OpenSUSE on x86_64, and i386 before Leap 15.0

    • Slackware on x86_64 and i386

    • Arch on x86_64, and i386 before 2017

    • Kali on x86_64, and i386 before 2024.4

    • Alma on x86_64

  • Debian Linux on ppc64le

  • Gentoo Linux on IA-64

  • FreeBSD on amd64

  • NetBSD on amd64

  • OpenBSD on amd64

  • macOS 10.4 and newer on LP64 and ILP32 Intel (Clang or GCC)

  • macOS 11.0 and newer on 64-bit Apple Silicon ARMv8 (Clang or GCC)

  • Solaris on i86pc and Sun-4v (SPARC)

  • Tru64 on Alpha

  • AIX on ppc32be and ppc64be

  • HP-UX on IA-64

  • Windows XP on i386, and 7, 10, and 11 on x86_64, under Cygwin

  • Windows 10 and 11 on x86_64, under Windows Subsystem for Linux (WSL) 1 and 2

  • Raspberry Pi on armv7l and armv6l running Raspbian

  • Mobian (Mobile Debian Linux) on aarch64

To build RSM, clone the RSM git repository:

$ git clone https://gitlab.com/Reference-Standard-M/rsm.git

Change to the rsm directory and build the rsm executable:

$ make

or

$ make -j

On Solaris:

$ gmake

The resulting rsm executable will be optimized for your system.

Note
On current versions of Ubuntu and Kali Linux, libcrypt-dev must be installed before building RSM: sudo apt install libcrypt-dev.

Install the rsm executable to the default bin directory [/usr/local/bin], and the utils.rsm utilities to the default rsm directory [/usr/local/share/rsm]:

$ sudo make install

Install the rsm executable to a different bin directory [/usr/bin], and the utils.rsm utilities to a different rsm directory [/usr/share/rsm]:

$ sudo make install prefix=/usr

On Cygwin (as administrator):

$ make install

Clean up the build environment after installation:

$ make clean

Uninstall the rsm executable from the default bin directory [/usr/local/bin], and the utils.rsm utilities from the default rsm directory [/usr/local/share/rsm]:

$ sudo make uninstall

Uninstall the rsm executable from a different bin directory [/usr/bin], and the utils.rsm utilities from a different rsm directory [/usr/share/rsm]:

$ sudo make uninstall prefix=/usr

Install the documentation (asciidoc/man page) to the default rsm and man1 directories [/usr/local/share/doc/rsm, /usr/local/share/man/man1]:

$ sudo make install-docs

Install the documentation (asciidoc/man page) to different rsm and man1 directories [/usr/share/doc/rsm, /usr/share/man/man1]:

$ sudo make install-docs prefix=/usr

On Cygwin (as administrator):

$ make install-docs
Note
On macOS and AIX, you might have to add the path that make install-docs installed the rsm man page in, to the MANPATH environment variable.

Uninstall the documentation (asciidoc/man page) from the default rsm and man1 directories [/usr/local/share/doc/rsm, /usr/local/share/man/man1]:

$ sudo make uninstall-docs

Uninstall the documentation (asciidoc/man page) from different rsm and man1 directories [/usr/share/doc/rsm, /usr/share/man/man1]:

$ sudo make uninstall-docs prefix=/usr

Usage

Output a short version string:

$ rsm -V

Output a helpful options menu:

$ rsm -h
Note
Set the environment variable RSM_DBFILE to the database file path to avoid having to pass it to rsm.

To use RSM, create a database:

# Optional arguments in square brackets
#  -v <volume-name>        Name of volume             (1-32 alpha characters)
#  -b <block-size>         Size of database blocks    (1-256 KiB)
#  -s <database-size>      Initial size of database   (100-2147483647 blocks)
# [-m <map-size>]          Size of map block          (0-262147 KiB)
# [-e <environment-name>]  Name of manager UCI        (1-32 alpha characters)
# [<database-file>]        Name of the database file

$ rsm -v TST -b 16 -s 4096 tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm -v TST -b 16 -s 4096
Note
In order to load the supplied M utilities, use a block size of 14 KiB or larger.

Initialize and start the environment:

# Optional arguments in square brackets
#  -j <max-jobs>          Size of job table in environment  (1-4096 jobs)
# [-g <global-buffers>]   Size of global buffers            (1-131072 MiB)
# [-r <routine-buffers>]  Size of routine buffers           (1-4095 MiB)
# [<database-file>]       Name of the database file

$ rsm -j 12 tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm -j 12

On macOS, you might need to increase the accessible shared memory before starting the environment, if the previous command failed. If so, as root or using sudo, run the following commands, adjusted based on your system resources:

# 2 GiB shared segment max:
$ sudo sysctl -w kern.sysv.shmmax=2147483648

# 8 GiB of system shared memory (in number of pages at 4096 bytes per page):
$ sudo sysctl -w kern.sysv.shmall=2097152

To persist the above configuration changes on macOS, you’ll need to create a property list configuration and load it so the daemon picks it up at boot time. There is a sample plist XML file at sysctl.plist. Run these commands, after adjusting the kern.sysv.shmmax and kern.sysv.shmall settings based on your system resources, and ensuring you aren’t overwriting an existing file with that name:

# Copy plist configuration to the correct system location
$ sudo cp /Users/user/rsm/etc/sysctl.plist /Library/LaunchDaemons/sysctl.plist

# Change its ownership
$ sudo chown root:wheel /Library/LaunchDaemons/sysctl.plist

# Load it for the launch daemon to run at boot
$ sudo launchctl load /Library/LaunchDaemons/sysctl.plist

On Cygwin, you need to configure and start cygserver (as administrator) before starting the RSM environment, as it provides the SysV shared memory support.

$ cygserver-config
$ cygrunsrv -S cygserver

Output a database and environment configuration:

$ rsm -i tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm -i

Load the M utilities (using the bootstrap method):

# Optional arguments in square brackets
# -x <M-command(s)>        String of M commands to execute
# [-e <environment-name>]  Name of initial UCI environment
# [<database-file>]        Name of the database file

$ rsm -x 'open 1:("utils.rsm":"read") use 1 read code xecute code' tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm -x 'open 1:("utils.rsm":"read") use 1 read code xecute code'

Start direct mode:

# Optional arguments in square brackets
# [-e <environment-name>]  Name of initial UCI environment
# [-R]                     Starts in restricted mode
# [<database-file>]        Name of the database file

$ rsm tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm

Run an M routine in indirect mode:

# Start the M Command Language shell
# Optional arguments in square brackets
# -x <M-command(s)>        String of M commands to execute
# [-e <environment-name>]  Name of initial UCI environment
# [-R]                     Starts in restricted mode
# [<database-file>]        Name of the database file

$ rsm -x "do ^%M" tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm -x "do ^%M"

When upgrading to a new version of RSM, you might occasionally run in to an issue executing a routine. If this happens, you might be able to fix it by recompiling the routines:

RSM [MGR,TST]> merge ^$routine("%RECOMP")=^$routine("%RECOMP")
RSM [MGR,TST]> do ^%RECOMP

Stop and shut down environment:

$ rsm -k tst.dat

or

$ export RSM_DBFILE="/home/user/tst.dat"
$ rsm -k

From within an RSM job:

RSM [MGR,TST]> kill ^$job

If utils.rsm has been loaded:

RSM [MGR,TST]> do ^SSD

Docker Container

To download the latest RSM Docker image from Docker Hub:

$ docker pull dlwicksell/rsm

To build the RSM Docker image from source, while in the rsm directory:

$ docker build -t rsm .

or

$ docker buildx build -t rsm .

You can change a few build parameters, by passing them as follows:

# Pass each build argument with a separate --build-arg  - as below
# journal=on       Turns journaling on in the image     - defaults to off
# bsize=<bsize>    The size of a database block in KiB  - defaults to 16
# blocks=<blocks>  The number of blocks in the database - defaults to 16384

$ docker build -t rsm \
      --build-arg journal=on \
      --build-arg bsize=32 \
      --build-arg blocks=32768 .

or

$ docker buildx build -t rsm \
      --build-arg journal=on \
      --build-arg bsize=32 \
      --build-arg blocks=32768 .
Note
If you build the image from source, using the previous example, replace dlwicksell/rsm with rsm below.

To create and run the Docker container with RSM in direct mode:

$ docker run -it --rm --name rsm dlwicksell/rsm

or

$ docker run -it --name rsm dlwicksell/rsm

To create and run it in detached mode:

$ docker run -itd --name rsm dlwicksell/rsm

The RSM Docker container runs with port 80 open. To map an open port on your host machine to the container port (replace 8080 with an available local port):

$ docker run -itd --name rsm -p 8080:80 dlwicksell/rsm

You can change a few runtime parameters, by passing them as follows:

# The first argument [32|2] will set the number of maximum RSM jobs - default 12
# The second argument ['write...'] will run that M code and remove the container

$ docker run -it --rm --name rsm dlwicksell/rsm 32
$ docker run -it --rm --name rsm dlwicksell/rsm 2 'write $system,!'

To run RSM in direct mode while the container is in detached mode:

$ docker exec -it rsm rsm

To run RSM commands while the container is in detached mode:

$ docker exec -it rsm rsm -i
$ docker exec -it rsm rsm -h
$ docker exec -it rsm rsm -V
$ docker exec -it rsm rsm -x 'write $system,!'

To run the Bash shell while the container is in detached mode:

$ docker exec -it rsm bash

To start the container while in detached mode:

$ docker start rsm

To stop the container while in detached mode:

$ docker stop rsm

Consult the Docker documentation to learn about other ways you can run and manage the RSM Docker image and container.

Snap Package

To install the RSM snap from the Snap Store:

$ sudo snap install rsm

The snap installs with three commands: rsm for direct mode, rsm.man for the man page, and rsm.daemon which runs as a background service. The database is created automatically at install time and the utilities are loaded. The daemon is started automatically and will restart on failure.

Note
The database file is managed automatically by the snap at $SNAP_COMMON/rsm.dat.
Note
The snap uses strict confinement, which requires the -U flag to be passed to rsm internally to relax certain file and IPC permissions.

View the RSM man page:

$ rsm.man

Start RSM in direct mode:

$ rsm

Run an M routine in indirect mode:

$ rsm -x "do ^%M"

The environment starts with the following default configuration:

  • max-jobs: 32

  • global-buffers: max-jobs / 2 MiB

  • routine-buffers: max-jobs / 8 MiB

To configure the environment before starting it:

# Optional snap configuration options in square brackets
# [max-jobs]         Size of job table in environment  (1-4096 jobs)
# [global-buffers]   Size of global buffers            (1-131072 MiB)
# [routine-buffers]  Size of routine buffers           (1-4095 MiB)

$ sudo snap set rsm max-jobs=64
$ sudo snap set rsm global-buffers=32
$ sudo snap set rsm routine-buffers=8

To reset the environment configuration option back to its default value:

$ sudo snap unset rsm max-jobs
$ sudo snap unset rsm global-buffers
$ sudo snap unset rsm routine-buffers
Note
Configuration changes require an environment restart to take effect.

To view all user-configured environment options, or the current value of a specific option (only returns a value if the option has been explicitly set by the user):

$ sudo snap get rsm
$ sudo snap get rsm max-jobs
$ sudo snap get rsm global-buffers
$ sudo snap get rsm routine-buffers

To start, stop, or restart the environment:

$ sudo snap start rsm
$ sudo snap stop rsm
$ sudo snap restart rsm

To check the environment status:

$ snap services rsm

To view the environment daemon logs:

$ sudo snap logs rsm

To view detailed environment daemon status information:

$ sudo systemctl status snap.rsm.daemon

To view information about the snap, including version and available channels:

$ snap info rsm

To update the snap to the latest version:

$ sudo snap refresh rsm

To remove the snap:

$ sudo snap remove rsm
Note
Removing the snap does not delete the database file at $SNAP_COMMON/rsm.dat, unless the --purge flag is passed to snap remove.

Consult the Snap documentation to learn about other ways you can run and manage the RSM snap.

Database Upgrade

Version 1.73.0 of RSM introduced a change from 8 character identifiers to 32 character identifiers. This necessitated a change to the database format, the routine bytecode format, and the journal format, which required bumping the database version from 1 to 2, the compiler version from 7 to 8, and the journal version from 1 to 2.

The RSM runtime image will detect a database in the older format, as well as compiled bytecode in the older format, and return an appropriate error. If you would like to move your globals and routines from an old database to a new one, which works with this version of RSM, please follow these database upgrade instructions, or run the upgrade script.

Enjoy!

About

Reference Standard M -- Implementation of ANSI/MDC Standard M X11.1-1995 (ISO/IEC 11756:1999) for Linux, FreeBSD, NetBSD, OpenBSD, macOS, Solaris, AIX, HP-UX, Windows (in Cygwin and WSL 1 & 2), and Raspberry Pi.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors