Managing Xi-Text Printer States and Operations
The eight states a printer can be in, what moves it between them, and the commands and spq keys that drive it
Every Xi-Text printer is in one of eight states, and what you can do to a printer depends on which one it is in. This article gives the eight states, the commands and spq keys that move a printer between them, and the configuration changes that need the printer halted first.
The eight printer states
The state names below are the words the product itself prints, in lower case, in the state column of splist and in the printer section of spq:
halted startup idle printing a/w oper shutdown offline error
To see the current state of every printer:
splist
ptr1 <lp0> a4.ps idle
ptr2 <srv:910> letter printing 15033 jsmith
ptr3 <lp1> a4 halted
ptr4 <lp2> labels offline
The default listing is printer name, device, form type, state, job number and job owner; the last two columns are filled only while the printer is printing.
Halted
The state a printer is added in, and the state it is put into deliberately. No jobs are sent to it, and it is the state required for changing the form type and for most configuration changes.
How to enter: Press h (halt at the end of the current job) or H (halt at once) in spq, or run sphalt [printer] or spstop [printer]
Every printer is also halted whenever the spooler itself starts. The scheduler reads the saved printer list and sets every entry to halted whatever state it was in when the spooler was stopped, so printers are started again after a restart.
Startup
Transitional, while the printer initialises: the setup files are read by a separate spdinit process, the device is opened, and the setup string and the suffix start string are sent to the device.
How to enter: Automatically when starting a halted printer, and again mid-run whenever a selected job needs a different form type from the one loaded
If it stays here: a fault in the setup files or the device moves the printer to error. A printer that sits in startup is blocked writing the setup string to the device - commonly flow control, where the printer has sent XOFF and never sends XON. Press H a second time to force it out.
Idle
The printer initialised successfully and is waiting for a job with a matching form type, which it will print as soon as one arrives. The form type is displayed, with the (N/A) marker if alignment is required for the next job.
How to enter: Automatically after successful startup, and after each job finishes
Printing
Actively printing a job. The job number and owner are displayed, and the job can be interrupted or aborted. Entered automatically when a job is selected.
a/w oper (awaiting operator)
The printer has paused for operator approval. Two things bring it here:
- An alignment page has just been printed, because the form type in use has an alignment file and the (N/A) marker was set
- Single-job mode, where the operator approves each job
Both are reached from printing, never directly from startup: the printer takes a job first, and pauses part-way through starting it.
Actions available:
- Press y to approve and continue, or run spok [printer]
- Press n to reject, or run spnok [printer]. For an alignment page this prints another alignment page; in single-job mode it continues, the same as y
- Press A to abort the job, which discards it and returns the printer to idle
How to exit: Operator approval, aborting the job, or halting the printer
Privilege: y and n, and spok and spnok, need the Select printer list permission, which is part of the default user privilege set. This is a different permission from the one that starts and stops printers.
Shutdown
Transitional, while the printer stops: it sends the suffix end string and then the halt string, any filter process is closed down, and the device is closed. Entered automatically when the printer is halted.
If it stays here: a long docend, sufend or halt string takes as long as the device accepts it, and a printer taken off line mid-string may hold the port with XOFF. Press H again to force the shutdown through; the filter process group is then killed with SIGTERM.
Offline
The printer stops, as a halt does, and the state records why.
- Triggered by the device signalling hangup, or by the device open or write timing out
- A network or terminal-server filter can also report it, by exiting with a status listed in the setup file's offline directive
- Where the filter supplies a reason, it is shown after the state, as offline:Out of paper
Recovery:
- Fix hardware issue (power, cable, paper)
- Start the printer again - spstart [printer], or G in spq
Error
The printer stopped because Xi-Text could not carry on. A message naming the fault is in the system log, and the printer is recovered by fixing the cause and starting it again, in the same way as offline. The state records that something needs attention.
Common causes:
- Syntax error in the setup files, which makes spdinit exit non-zero
- No setup directory or no setup file for the form type
- The device cannot be opened
- The device is neither a character device nor a FIFO - pointing a printer at an ordinary file gives "Invalid device name"
- A network device with no network filter defined in the setup file, or a network filter defined for a device that is not a network device
- The network filter crashed, dumped core, or was lost
Recovery:
- Check the system log: tail -20 /var/spool/xi/spd/spshed_reps
- Fix underlying issue
- Start the printer again
State transitions
halted --spstart / G--> startup --setup ok--> idle
|
+--setup or device fault--> error
+--setup string interrupted--> halted
idle --job selected--> printing
printing --form type differs--> startup --> printing
printing --alignment required--> a/w oper --y--> printing
--n--> a/w oper (page reprinted)
printing --single-job mode--> a/w oper --y or n--> printing
printing --job done, aborted or interrupted--> idle
idle, printing or a/w oper --sphalt / h--> shutdown --> halted
any running state --spstop / H--> shutdown --> halted
any running state --device hangup or timeout--> offline
any running state --setup, device or filter fault--> error
any state --spooler restarted--> halted
halted, offline and error are the three states in which the printer holds no process and takes no jobs; spstart treats all three alike and starts the printer from any of them.
Starting a printer
From spq
- Press o to switch to printer section
- Navigate to printer with cursor keys
- Press G (Go/start)
Start spq with -p to open on the printer section, and with -P n to give that section n lines so every printer is visible at once. The printer section appears only for a user who holds the Select printer list permission; without it, o does nothing and the printer keys below are unavailable.
From the command line
The printer name is a shell-style pattern. When it matches more than one printer you must add -f, or the command refuses with "Printers match … ".
# Start specific printer
spstart ptr1
# Start all printers
spstart -f '*'
# Start printer, loading a different form type first
spstart ptr1 a4.ps
The form type is the second argument, with no option letter. If the printer is already running with a different paper type - the form type up to its suffix - spstart halts it at the end of the current job, waits, changes the form type and starts it again, so the halt-change-start sequence does not have to be typed out.
Give spstart a first argument that begins with a digit, or no argument at all, and it starts the spooler instead of a printer. That is what the packaged service does, as spstart 2000 50.
Privilege: spstart, sphalt, spstop and spinter need the Halt/restart printers permission, which is part of the default user privilege set, so starting and stopping printers is an ordinary user action unless the permission has been withdrawn.
What happens at startup
- Printer enters startup state
- A spdinit process is run for the printer and the current form type. It changes to the printers directory, then to the directory named after the printer, and reads the first of these that it finds: .device, then the file named after the form type, then the configured default form file
- The device is opened, and checked to be a character device or a FIFO
- The port setup string is sent, if one is defined
- The setup string and the suffix start string are sent to the printer
- If the form type has an alignment file, the printer is marked as needing alignment and the (N/A) marker appears
- Printer enters idle state
Any failure in steps 2 to 4 moves the printer to error. A failure in step 5 returns it to halted. Neither prints anything on the terminal that issued spstart, because the printer is started by the spooler rather than by that command - the reason is written to spshed_reps in the spool directory, and that is the only place it appears. Start a printer and it goes idle; read the log if it does anything else.
Alignment pages at startup
Where an alignment file is configured for the form type, the first job goes like this:
- The (N/A) (not aligned) marker is set at startup
- The printer takes the job and enters printing
- The alignment page prints
- Printer enters a/w oper state
The operator keys are those given under the a/w oper state above; halting the printer instead abandons the alignment and returns it to halted.
If no jobs are waiting: the printer stays idle with the (N/A) marker showing, and the alignment page prints when a job arrives.
Mid-run: changing form type re-arms alignment. When a selected job needs a different form type, the printer goes back through startup, the marker is set again from the new form type's setup file, and the alignment page prints before that job. A printer that stops for the operator in the middle of the working day has usually just changed form type.
Stopping a printer
Halting at the end of the current job
# In spq
Press 'h' on printer
# Command line
sphalt ptr1
A printing printer finishes the current job and then halts; an idle printer, or one awaiting the operator, halts immediately. The printer enters shutdown, sends the suffix end string and then the halt string, and enters halted.
Marker: while the printer is waiting for the job to finish, its line is marked (heoj). Pressing G, or running spstart, before it stops cancels the halt and leaves the printer running.
Stopping immediately
# In spq
Press 'H' on printer
# Command line
spstop ptr1
The printer stops at once, even mid-job. The abort string is sent, or the message ***ABORTED*** is printed if no abort string is defined. The current job remains in the queue, and the page it reached is recorded so it resumes there. Use this when the printer needs immediate attention.
Marker: the printer's line is marked AB!! while the stop is in progress.
Acting on the job being printed
Interrupt the current job
# In spq
Press '!' on printer
# Command line
spinter ptr1
- The current job stops, as an immediate halt does, and the printer starts again at once - the interrupt is a stop and a start in one command
- The page reached is recorded, less any windback pages set in the setup file
- The job returns to the queue and keeps its place in priority order. If a higher priority job is now waiting, that job prints and the interrupted one waits its turn
- When the interrupted job is selected again it resumes from the recorded page
- Useful for pushing a short urgent job past a long one
On a printer with a large buffer, buffered data may still print: the recorded page is where Xi-Text stopped sending, which is ahead of what the printer has put on paper.
Abort the current job
# In spq
Press 'A' on printer
# Command line
sqdel [job-number]
The current job stops, the abort string is sent to the printer, the job is deleted from the queue permanently, and the next job is selected. A in spq aborts whatever the printer is currently printing; sqdel names a job and works whether or not it is printing.
Restart the current job
# In spq
Press 'r' on printer
The current job stops and restarts from the beginning, and the restart string is sent to the printer, or the message ***RESTARTED*** and a page throw if none is configured. A large printer buffer limits this in the same way as an interrupt. There is no command-line equivalent of r.
Changing a printer's configuration
Every change in this section, apart from the form type, needs the Add/delete printers permission, which is outside the default user privilege set. The form type needs no special permission.
Change the form type
⚠️ In spq the printer must be halted
# In spq
1. Halt printer (H)
2. Press 'f' on halted printer
3. Enter new form type
4. Press '?' to see the form types set up for this printer
# Command line - halts, changes and restarts in one operation
spstart ptr1 letter.ps
In spq the sequence is halt the printer, change the paper if it needs changing, update the form type, start the printer. From the command line spstart does the halting and restarting itself, so only the paper change is manual. spchange sets the form type on a printer that is already halted and leaves it halted.
Change the printer name
⚠️ Printer must be halted
# In spq
Press 'P' on halted printer
This changes which setup file directory is used:
- Old name: /var/spool/xi/printers/old-name/
- New name: /var/spool/xi/printers/new-name/
The printers directory is a compiled-in default and a custom build may put it elsewhere; the setting is sprindir in /etc/xi/textconfig.
Change the device or port
⚠️ Printer must be halted
# In spq
Press 'V' on halted printer
# Command line
spchange -v /dev/ttyS1 ptr1
This changes the device file or network address:
- Local: /dev/lp0, /dev/ttyS0 - must be a character device
- Network: \
(angle brackets). The angle brackets are how spq shows and accepts a network device, and a network device requires a network filter in the setup file - FIFO: /tmp/printfifo - a named pipe is accepted as well as a character device
Change the description
⚠️ Printer must be halted
# In spq
Press 'c' on halted printer
# Command line
spchange -D "Accounts department LaserJet" ptr1
The description is human-readable text and has no effect on operation.
Adding and removing printers
Both need the Add/delete printers permission.
Add a printer
# In spq
Press 'N' in printer section
# Prompts for:
# - Printer name (cycles through available directories)
# - Device/port (cycles through unused /dev entries)
# - Form type (cycles through setup files)
# - Description
# Command line
spadd -l ttyS0 ptr1 a4.ps
# Interactive script, which also creates the setup files
Ptrinstall
spadd requires -l to name the device; without it the command refuses with "When adding a printer you must specify the device name". Adding a printer through spq or spadd registers it with the spooler and leaves the setup files to be created separately, which is what Ptrinstall is for.
Delete a printer
⚠️ Printer must be halted
# In spq
Press 'D' on halted printer
# Command line
spdel ptr1
This removes the printer from the Xi-Text list and leaves its setup files in place. spdel deletes one printer at a time and refuses a pattern that matches several.
Single-job mode
For manual feed or special handling:
# In setup file
single
The printer takes a job and prints its banner, enters a/w oper, waits for operator approval, prints the job, and repeats for the next job. Both y and n release the job; only the alignment case treats them differently. It suits manually fed envelopes, special forms that need checking before they are run, and testing a new configuration.
Managing the alignment marker
When alignment is required
Alignment pages are configured in setup files:
# In setup file
align=.setpage # File containing alignment pattern
Use execalign in place of align to run the named file as a program rather than copy its contents to the printer. Either way, spdinit checks the file when the printer starts - align needs it readable, execalign needs it executable, by the system user - and a file it cannot use puts the printer into error.
Setting and clearing the marker
Approve alignment (when N/A showing):
# In spq
Press 'y' on printer in a/w oper state
# Asks for confirmation if idle
Reject alignment and reprint:
# In spq
Press 'n' on printer in a/w oper state
Clear alignment requirement:
# When printer is Idle
Press 'y' (confirms, clears N/A marker)
Reinstate alignment requirement:
# When printer is Idle
Press 'n' (confirms, adds N/A marker back)
spok and spnok do all four of these - approve, reject, clear and reinstate - according to the printer's state, and without asking for confirmation. On a halted printer they do nothing at all.
Load limits
Load limits control which printers can take large jobs:
⚠️ Printer must be halted
# In spq
Press 'L' # Set lower limit (minimum job size)
Press 'U' # Set upper limit (maximum job size)
Both limits are in bytes, and are the size of the whole job, disregarding any page range or odd/even selection. Zero means no limit. A printer with a lower limit shows \< after its state, and one with an upper limit shows >. Setting them needs the Halt/restart printers permission, and there is no command-line equivalent. They reserve a fast printer for large jobs, route small jobs to a slower one, and keep a long job off a printer that is needed for something else.
Class codes
Class codes control printer access by user group:
⚠️ Printer must be halted
# In spq
Press 'C' to change class code
# Command line
spchange -S 000f ptr1
A job is only selected for a printer where:
job_class_code & printer_class_code != 0
The job's class code comes from the class code of the user who submitted it, so in practice this routes users to printers. Changing a printer's class code needs the Add/delete printers permission.
Watching what the printers are doing
The system log
# In spq
Press 'X'
# Command line
tail -50 /var/spool/xi/spd/spshed_reps
It carries printer start and stop events, errors and warnings, file access issues and setup file problems, and it is the only place a startup failure is reported. The spool directory is a compiled-in default; the setting is spooldir in /etc/xi/textconfig.
The printer display
# In spq, printer section shows:
# - Current state
# - Form type
# - Device/port
# - Description
# - Current job (if printing)
# - Status messages
For a listing rather than a screen, use splist. Its state field carries any message the printer reported, as offline:Out of paper, and the (heoj), AB!!, (N/A), \< and > markers appear in their own fields.
Testing a printer's state from a script
# True (exit 0) if the printer is running at all
spstat ptr1
# True if the printer is in the named state
spstat ptr1 idle
spstat ptr1 'a/w oper'
spstat reports through its exit status - 0 for true, 1 for false - and prints nothing. "Running" means any of startup, idle, printing, a/w oper or shutdown. It names exactly one printer and refuses a pattern that matches more than one. Spaces are removed from both the state name and the argument before they are compared, so a/w oper and a/woper both match, and the state name may itself be a pattern.
A script that has to wait for a printer to finish what it is doing polls that exit status:
#!/bin/sh
# wait-for-idle.sh
PRINTER=$1
while ! spstat $PRINTER idle
do
echo "Waiting for $PRINTER to become idle..."
sleep 5
done
echo "$PRINTER is now idle"
A printer that has gone offline or into error is never idle, so a loop like this waits for ever on a fault. Test for the stopped states as well if it is to run unattended.
To watch every printer rather than test one, poll splist. watch is a Linux utility and is absent on the commercial Unix platforms the product also ships on, so a loop is the portable form; inside spq, -R sets the refresh interval instead.
while true
do
splist
sleep 2
clear
done
Troubleshooting
Printer goes straight to error
spstart itself reports nothing, because the printer is started by the spooler, and the reason is in spshed_reps. Read it, then work through the causes listed under the error state above, and one more that is not among them: any align, execalign, record or log file named in the setup file must be readable, or executable, by the system user.
Printer stays in startup or shutdown
Either a write to the device is blocked - most often flow control, where the printer sent XOFF and has not sent XON - or a long setup, docend, sufend or halt string is still going out.
Press H again, or run spstop, to force it. Take the printer off line after it has halted rather than before, so the port is not left holding an unfinished string.
Jobs not printing from an idle printer
Check:
- Form type matches job form type, comparing only the paper type - the form type up to its suffix
- Alignment required ((N/A) marker) - the alignment page prints before the job
- Class code compatibility - the job's class code and the printer's must share a bit
- Job size within limits, in bytes, for the whole job
- The job has a hold time still in the future
- The job has already been assigned to another printer
- Scheduling is suspended - ssuspend stops jobs being allocated to any printer until it expires or srelease is run
Where the related procedures are
- Xi-Text Printer Setup Files: What They Contain and When They Are Read - Configuration details
- Configuring Xi-Text Form Types, Paper Types and Suffixes - Form type management
- Diagnosing and Clearing the Xi-Text Printer error State - Error recovery
- Distinguishing the Xi-Text offline State From error - Telling the two apart
- Stopping and Starting All Xi-Text Printers at Once - Bulk operations
- Xi-Text File Permissions and Ownership - Who must own the setup files and devices
The full detail is in the Xi-Text Reference Manual, Chapter: Text screen-based Programs (the spq section) and Chapter: Printer Definitions (setup file keywords), in the User Programs pages for Spstart, Sphalt, Spok, Spinter, Spchange, Spadd, Spstat, Sstop, Ssuspend and Srelease, and in the Xi-Text Administration Guide, Chapter: Defining and Installing Printers.
Related articles
Stopping and Starting All Xi-Text Printers at Once
The pattern form that halts or starts every printer in one command, and the four things a restart does not bring back
Diagnosing and Clearing the Xi-Text Printer error State
What puts a printer into error, the messages Xi-Text writes when it happens, and the one command that starts it again
Distinguishing the Xi-Text offline State From error
What puts a printer offline rather than into error, and why nothing is written to the log when it happens