Daemon Mode spec

run spec as a background daemon

DESCRIPTION

(Note, daemon-mode spec is currently an experimental feature, with behavior subject to change. If you use this feature, please send feedback to CSS.)

With the -S3 or -S4 command line flags, spec starts in server mode and completely disconnects from the current terminal session. The current directory is changed to root (/). Keyboard input is replaced with reads from /dev/null. Any built-in functions that read the keyboard (input(), getval(), getsval(), yesno(), spec_menu()) will get an end-of-file EOF return. Keyboard generated signals, such as from a ^C, no longer reach daemon-mode spec.

The difference between -S3 and -S4 is the same as the difference between -S1 and -S2 in interactive server mode. The difference is that a mode-1 server (the default) doesn't stop other motors and reset to the main command prompt when a motor hits a limit. A mode-2 server will stop all motors when any motor hits a limit, even if the move was initiated by a different client, and a mode-2 server will reset to the main command prompt. The limit behavior for a mode-2 server is the same as for non server-mode spec. See the server help file for server-mode details.

Screen output for daemon-mode spec is redirected to an automatically created log file. Commands that would draw on the screen (tty_cntl(), tty_fmt(), tty_move()) will only output printable text strings associated with the commands and will not include terminal control sequences.

The logfile name is taken from the spec_par() parameter "daemon_logfile". The string variable can contain formatting sequences from the C library strftime() function (just as with spec's date() function). In addition, the sequence "%N" is replaced with the name by which spec was invoked. The default value for "daemon_logfile" is "/tmp/%Y_%m_%d_%N-daemonlog" (subject to change), which on February 26, 2023 becomes:

/tmp/2023_02_26_fourc-daemonlog

The logfile can be passed as a start-up option using -o, as in:

spec -S3 -o daemon_logfile="/tmp/%Y_%m_%d_%N-daemonlog"

If the file exists, it will be opened to append. If the file can't be opened for writing, daemon-mode spec will exit. Note, the daemon log file can't be closed or have output turned off with close() or off().

The output of the log file will very much resemble the screen of an interactive spec session with prompts and the text of commands received from any clients.

When in daemon-mode, only dofile() and qdofile() are disallowed in queue() commands. Unlike interactive-mode spec, moving and counting commands can be included in queue() function sequences. See the queue help file for queue() function usage.

Commands received by daemon-mode spec are placed on the command history list, and the history will be saved to the session's history state file when daemon-mode spec quits. Although the history command functions as normal with the requested command history appearing in the daemon-mode log file, it is not possible to recall previous commands for execution in the daemon-mode session. If spec is restarted in interactive mode, the commands received while daemonized are accessible for recall.

The spec variables USER, HOME and DISPLAY are taken from the environment when daemon-mode spec starts up. USER and HOME, as with non daemon-mode spec, cannot be altered. (Immutability subject to change.)

An SV_CMD packet sent to the server with the quit command will cause daemon-mode spec to exit. From a spec client, one can use:

remote_cmd(spec_server, "quit")

When daemonized, spec accepts the quit command even if the spec_par() "confirm_quit" parameter is set.

Note, if a motor discrepancy message is generated, daemon-mode spec requires an answer via an SV_CHAN_SEND message of the property motor/mne/sync_check. If such messages can be generated, the client should register for events on that property and be prepared to respond. Alternatively, the hardware read_mode motor parameter can be set to "no query" mode such that spec always accepts the position reported by the motor controller.

To respond to a motor discrepancy event from a spec client, one can use:

prop_put(spec_server, "motor/mne/sync_check", 1|0)

where mne is the associated motor mnemonic and a 1 means yes while 0 means no to the discrepancy question. The discrepancy question will be of the form:

Should the controller be changed?

or if the controller doesn't allow changes to position registers:

Should the user offset be changed?

In the first case, a yes means change the controller to match the software position, while a no means to change the software position to match the controller. In the second case, a yes means to change the user offset to match the controller dial position, while a no means to change the user dial position to match the controller.