for connected embedded systems
![]() |
![]() |
![]() |
![]() |
Printing
This chapter includes:
Overview of printing
The simplest way to print a text file is to send it directly to a printer. For example, if your printer is attached to your computer's parallel port, you could simply type:
cat file > /dev/par
but there are a few problems with this:
- You don't get another command prompt until the file has been printed, unless you add an ampersand (&) to the end of the command.
- If the printer is already printing something, or it can't handle the type of file you've sent, the output might be garbled, and you end up just wasting paper.
It's better to use spooling. When you spool a print job, it's placed in a queue until its turn comes up to be printed.
Neutrino provides two separate mechanisms for print spooling:
- the standard UNIX-like lpr utility (see “Printing with lpr”)
- the spooler utility (see “Printing with spooler”)
If you want to use the lpr family, you have to set up the printer-configuration file, /etc/printcap.
You can use lpr, spooler, or both, depending on how you've set up your machine and network:
- If you've attached a USB printer to your machine, you need to run the USB stack and devu-prn (see “USB devices” in the Connecting Hardware chapter), and then you can use either the lpr family or spooler.
- If you've attached your printer to your machine's serial port, you need to use the lpr family.
- If you've attached your printer to your machine's parallel port, you
can use either the lpr family or spooler.
In this case, the device enumeration that the system does when it boots automatically starts spooler (see “Device enumeration” in Controlling How Neutrino Starts). We supply configuration files, in /etc/printers, for the most commonly used printers.
- If you want to use a network printer or a printer that's attached to
another node's parallel port, you need
to use a TCP/IP network for the lpr family; spooler
can use Qnet, SAMBA, NCFTP, or even the lpr family to print on
remote printers.
In order to print remotely, you have to set up some configuration files whether you use the lpr family or spooler.
- If you want to print from a Photon application (e.g. helpviewer), you need to use spooler.
Another difference is that the lpd daemon manages all of the defined printers; spooler manages one printer, but you can run more than one instance of spooler at a time.
Printing with lpr
The lpr line-printer system supports:
- multiple printers
- multiple spooling queues
- both local and remote printers
- printers attached via serial lines that require line initialization (e.g. baud rate)
To print a file using the line-printer system, you need:
- a user interface and a method of organizing and preparing print jobs
- spooling directories, somewhere to store files waiting to be printed
- a way of preventing unauthorized access
- for remote printing, a network manager capable of delivering the files to be printed
- some knowledge about the printer being used
![]() |
You need to log in as root to set up the lpr system. |
User interface
The line-printer system consists mainly of the following files and commands:

Printing with the lpr utilities.
- lpd
- Printer daemon that does all the real work.
- lpr
- Program to enter a job in a printer queue.
- lprq
- Spooling queue examination program.
- lprrm
- Program to delete jobs from a queue.
- lprc
- Program to administer printers and spooling queues; only root can use this utility.
- /etc/printcap
- A master database that describes printers directly attached to a machine and printers accessible across a network. It describes the available printers and how to communicate with them, and it specifies the values for important items (e.g. the spooling directory).
lpd — printer daemon
The lpd program, which you typically invoke at boot time from the /etc/rc.d/rc.local file (see the Controlling How Neutrino Starts chapter), acts as a master server for coordinating and controlling the spooling queues configured in the /etc/printcap file. When it starts, lpd makes a single pass through the /etc/printcap database, restarting any printers that have jobs. In normal operation, lpd listens for service requests on a socket within the Internet domain (under the “printer” service specification) for requests for printer access.
The daemon spawns a copy of itself to process the request; the master daemon continues to listen for new requests. The daemons use simple text files as lock files for synchronization; the parent daemon uses /usr/spool/output/lpd.lock, while its children use a .lock file in the printer's spool directory, as specified in the printcap file.
Clients communicate with lpd using a simple transaction-oriented protocol. Authentication of remote clients is done based on the “privileged port” scheme employed by rshd. See “Access control,” below.
lpr — start a print job
The lpr command lets you put a print job in a local queue and notifies the local lpd daemon that new jobs are waiting in the spooling area. The daemon either schedules the job to be printed locally, or if printing remotely, attempts to forward the job to the appropriate machine. If the printer can't be opened or the destination machine can't be reached, the job remains queued until the work can be completed.
lprq — show printer queue
The lprq program works recursively backwards, displaying the queue of the machine with the printer and then the queue(s) of the machine(s) that lead to it. This utility has these forms of output:
- short format (the default) — gives a single line of output per queued job
- long format (if you specify the -l option) — shows the list and sizes of files that comprise a job
lprrm — remove jobs from a queue
The lprrm command deletes jobs from a spooling queue. If necessary, lprrm first kills a running daemon that's servicing the queue and restarts it after the required files are removed. When removing jobs destined for a remote printer, lprrm acts like lprq, except it first checks locally for jobs to remove and then tries to remove files in queues off-machine.
![]() |
You can remove only your own print jobs from the queue. |
lprc — printer-control program
The lprc program is used to control the operation of the line-printer system. For each printer configured in /etc/printcap, lprc may be used to:
- disable or enable a printer
- disable or enable a printer's spooling queue
- rearrange the order of jobs in a spooling queue
- find the status of printers and their associated spooling queues and printer daemons
The lprc program gives the root user local control over printer activity. Here are the program's major commands and their intended uses (see the Utilities Reference entry for the command format and full list of commands).
- start
- Enable printing and ask lpd to start printing jobs.
- abort
- Terminate an active spooling
daemon on the local host immediately and then disable printing
(preventing new daemons from being started by
lpr).
You typically use the abort command
to forcibly restart a hung printer daemon
(e.g. when lprq
reports that a daemon is present, but nothing is happening).
The abort command doesn't remove any jobs from the spool queue; for this, use lprrm.
- enable and disable
- Turn spooling in the local queue on or off, in order to allow or prevent
lpr
from putting new jobs in the spool queue.
For example, you may want to use the disable command when testing new printer filters, because this lets root print, but prevents anyone else from doing so. The other main use of this option is to prevent users from putting jobs in the queue when the printer is expected to be unavailable for a long time.
- restart
- Allow ordinary users to restart printer daemons when lprq reports that no daemon is present.
- stop
- Halt a spooling daemon after the current job completes; this also disables printing. This is a clean way to shut a printer down for maintenance. Note that users can still enter jobs in a spool queue while a printer is stopped.
- topq
- Place selected jobs at the top of a printer queue. You can use this command to promote high-priority jobs (lpr places jobs in the queue in the order they were received).
Spooling directories
Each node you wish to print from must have a spooling directory to hold the files to be printed. By default, the pathname for this directory is /usr/spool/output/lpd (you can change the pathname of the spooling directory in the /etc/printcap file). If this directory doesn't exist, you must create it on all nodes.
![]() |
The lpd daemon doesn't work without a spooling directory, and it doesn't tell you why. That's why it's a good idea to run the system logger (see syslogd in the Utilities Reference) when you're trying to debug printing problems; then you can check for error messages in /var/log/syslog. |
Access control
The printer system maintains protected spooling areas so that users can't circumvent printer accounting or remove files other than their own:
- Only the print-manager daemon can spool print jobs. The spooling area is writable only by a daemon user and daemon group.
- The lpr program runs with the user ID, root, and the group ID, daemon. Running as root lets lpr read any file required. Accessibility is verified by calling access() (see the Library Reference). The group ID is used in setting up proper ownership of files in the spooling area for lprrm.
- Users can't modify control files. Control files in a spooling area are made with daemon ownership and group ownership daemon. Their mode is 0660. This ensures that users can't modify control files and that no user can remove files except through lprrm.
- Users may alter files in the spool directory only via the print utilities. The spooling programs — lpd, lprq, and lprrm — run setuid to root and setgid to group daemon to access spool files and printers.
- Local access to queues is controlled with the rg entry
in the /etc/printcap file:
:rg=lprgroup:
Users must be in the group lprgroup to submit jobs to the specified printer. The default is to allow all users access. Note that once the files are in the local queue, they can be printed locally or forwarded to another host, depending on the configuration.
- The print manager authenticates all remote clients.
The method used is the same as the authentication scheme for
rshd
(see the Utilities Reference).
The host on which a client resides must be present in /etc/hosts.equiv or /etc/hosts.lpd, and the request message must come from a reserved port number.

Other utilities, such as rlogin, also use /etc/hosts.equiv to determine which hosts are equivalent. The /etc/hosts.lpd file is used only to control which hosts have access to the printers. To allow access only to those remote users with accounts on the local host, use the rs field in the printer's entry in /etc/printcap:
:rs:
Network manager
If you want to print on a remote printer, you need to run the Neutrino network manager, io-pkt*. This manager loads shared objects (DLLs) to provide the protocols and device drivers needed.
For example, to load the TCP/IP stack and a device driver suitable for Ethernet adapters compatible with NE-2000, devn-ne2000.so, start io-pkt* like this:
io-pkt-v4 -dne2000
![]() |
If you're using a TCP/IP stack like this, you might want to configure your network interface to specify the type and number of your NIC, and the IP address and netmask for your TCP/IP interface. For more information, see TCP/IP Networking. |
Printer capabilities: /etc/printcap
Before you can print anything, the nodes must know something about the specific printer being used (as a minimum, where the printer is located). A description of the printer is kept in a file named /etc/printcap on each node. The /etc/printcap database contains one or more entries per printer.
![]() |
This file isn't present when you first install Neutrino; you have to create one to suit your printing needs. |
This section describes the basic fields; for information on the others, see /etc/printcap in the Utilities Reference.
A typical setup
Here's a basic /etc/printcap file that you can modify:
lpt1|tpptr|printer in Docs department:\ :lp=/dev/par1:\ :sd=/usr/spool/output/lpt1:\ :lf=/usr/adm/lpd-errs:\ :mx#0:\ :sh:
Each entry in the /etc/printcap file describes a printer. Comments start with number sign (#). An entry consists of a number of fields delimited by colons (:). In the example above, each field is on a separate line, but you can string the fields together on one line as long as they each start and end with a colon.
Here's what each line means:
- lpt1|tpptr|printer in Docs department:\
- The known names for the printer, separated
by | (bar) characters.
The last name is the only name that can include spaces;
it's a long name that fully identifies the printer.
Entries may continue onto multiple lines by giving a \ (backslash) as the last character of a line. Empty fields may be included for readability.
- :lp=/dev/par1:\
- The name of the device to open for output (the default is /dev/lp).
- :sd=/usr/spool/output/lpt1:\
- The spooling directory (the default is
/usr/spool/output/lpd).
Each printer should have a separate spooling directory; if it doesn't,
jobs are printed on different printers, depending on which printer
daemon starts first. By convention, the name of the spooling directory
has the same name as its associated printer.

Make sure you create the named spooling directory before you print. - :lf=/usr/adm/lpd-errs:\
- A file to take printing error messages
(by default, errors are sent to the console).

Sometimes errors that are sent to standard error output don't appear in the log file. We highly recommend that you use the system-logger daemon, syslogd. - :mx#0:\
- Remove the default limits on the size of the spooling buffer.
- :sh:
- Suppress the printing of the burst header, a page that lists the user ID and job information about the print job.
Printers on serial lines
When you connect a printer via a serial line, you must set the proper baud rate and terminal modes. The following example is for a DecWriter III printer connected locally via a 1200 baud serial line.
lp|LA-180 DecWriter III:\ :lp=/dev/lp:br#1200:fs#06320:\ :tr=\f:of=/usr/lib/lpf:lf=/usr/adm/lpd-errs:
- lp
- The name of the file to open for output.
- br
- The baud rate for the tty line.
- fs
- Flags that set CRMOD, no parity, and XTABS.
- tr=\f
- Print a formfeed character when the queue empties. This is handy when the printer has continuous paper, because you can tear the paper off when the print job finishes instead of first having to take the printer offline and manually advance the paper.
- of=/usr/lib/lpf
- Use a filter program called lpf for printing the files (see “Filters,” below).
- lf=/usr/adm/lpd-errs
- Write any error messages to the file /usr/adm/lpd-errs, instead of to the console.
Remote printers
Printers that reside on remote hosts should have an empty lp entry. For example, the following /etc/printcap entry directs output to the printer named lp on the machine named ucbvax:
lp|default line printer:\ :lp=:rm=ucbvax:rp=lp:sd=/usr/spool/vaxlpd:
The rm entry is the name of the remote machine to connect to; this name must be a known hostname for a machine on the network. The rp capability indicates that the name of the remote printer is lp (you can leave it out in this case, because this is the default value). The sd entry specifies /usr/spool/vaxlpd as the spooling directory instead of the default pathname, /usr/spool/output/lpd.
Filters
Filters are used to handle device dependencies and accounting functions:
- Output filters
- Used when accounting isn't needed
or when all text data must be passed through a filter.
An output filter isn't suitable for accounting purposes because it's started only once, all text files are filtered through it, it doesn't pass owners' login names, and it doesn't identify the beginnings and ends of jobs.
- Input filters
- Started for each file printed and do accounting if there's an af field in the printer's printcap entry. If there are fields for both input and output filters, the output filter is used only to print the banner page; it's then stopped to allow input filters to access the printer.
- Other filters
- Used to convert files from one form to another.
For example:
va|varian|Benson-Varian:\ :lp=/dev/va0:sd=/usr/spool/vad:of=/usr/lib/vpf:\ :tf=/usr/lib/rvcat:mx#2000:pl#58:px=2112:py=1700:tr=\f:
The tf entry specifies /usr/lib/rvcat as the filter to use when printing troff output. This filter is needed to set the device into print mode for text and into plot mode for printing troff files and raster images. Note that the page length is set to 58 lines by the pl entry for 8.5″ by 11″ fanfold paper.
To enable accounting, add an af filter to the varian entry, like this:
va|varian|Benson-Varian:\ :lp=/dev/va0:sd=/usr/spool/vad:of=/usr/lib/vpf:\ :if=/usr/lib/vpf:tf=/usr/lib/rvcat:af=/usr/adm/vaacct:\ :mx#2000:pl#58:px=2112:py=1700:tr=\f:
![]() |
Neutrino doesn't provide print filters; you have to either port them from another UNIX-type OS or write your own. If you don't want to do this, you can use the spooling system, which provides print drivers for specific families of currently popular printers. See spooler in the Utilities Reference and “Printing with spooler,” below). |
The lpd daemon spawns the filters; their standard input is the data to be printed; their standard output is the printer. Standard error is attached to the lf file for logging errors (or you can use syslogd). A filter must return an exit code of 0 if there were no errors, 1 if the job should be reprinted, or 2 if the job should be thrown away.
When lprrm sends a SIGINT signal to the lpd process that controls the printing, lpd sends a SIGINT signal to all filters and their descendants. Filters that need to do cleanup operations, such as deleting temporary files, can trap this signal.
The arguments lpd passes to a filter depend on the filter type:
- Output (of) filters are called with the following arguments:
filter -wwidth -llength
The width and length values come from the pw and pl entries in the /etc/printcap database.
- Input (if) filters are called with the following arguments:
filter [-c] -wwidth -llength -iindent -nlogin -hhost acct_file
The optional -c flag is used only when control characters are to be passed uninterpreted to the printer (when using the -l option of lpr to print the file). The -w and -l parameters are the same as for of filters. The -n and -h parameters specify the login name and hostname of the job owner. The last argument is the name of the accounting file from /etc/printcap.
- All other filters are called with these arguments:
filter -xwidth -ylength -nlogin -hhost acct_file
The -x and -y options specify the horizontal and vertical page size in pixels (from the px and py entries in the /etc/printcap file). The rest of the arguments are the same as for if filters.
Some /etc/printcap examples
This section gives you some examples to show you how to set up your printer descriptions; see also /etc/printcap in the Utilities Reference.
USB printer
If you've attached a USB printer to your machine and started the USB stack and devu-prn as described in “USB devices” in the Connecting Hardware chapter, you should set up the /etc/printcap file to be something like this:
hpps: \ :lp=/dev/usbpar0 :sd=/usr/spool/output/hpps
This file gives the name hpps to the USB printer, identifies the file to open as /dev/usbpar0 (or whatever device devu-prn created), and identifies the spooling directory as /usr/spool/output/hpps.
To access this printer, specify lpr -Phpps or set the PRINTER environment variable to hpps.
![]() |
Make sure that the spooling directory exists. |
Single printer
Let's assume we have two nodes, node1 and node2, and node1 has a printer connected to /dev/par1:
The /etc/printcap file on node1 might be as follows:
lpt1:\ :lp=/dev/par1:
This file simply gives the name lpt1 to the printer connected to /dev/par1. It doesn't need to describe any other capabilities, because the default settings suffice. To access this printer from node1, specify lpr -Plpt1 or set the PRINTER environment variable to lpt1.
![]() |
Make sure the spooling directory exists, and that there's an entry for node2 in the /etc/hosts.lpd file on node1. |
The /etc/printcap file on node2 might be as follows:
rlpt1:\ :rm=node1:rp=lpt1:lp=:
This file specifies the remote host with the printer named lpt1 to be node1. The local printer name, rlpt1, is used by local clients and could be the same as the remote name, lpt1.
Make sure there's an entry for node1 in /etc/hosts.
Multiple printers
Now, let's add another printer to node1, this time connected to /dev/par2:
You should define multiple printers carefully because the default capabilities aren't suitable for all printers. For example, use the sd field to specify a unique spool directory for each printer.
The /etc/printcap file on node1 now looks like this:
lpt1:\ :lp=/dev/par1:sd=/usr/spool/output/lpt1: lpt2:\ :lp=/dev/par2:sd=/usr/spool/output/lpt2:
This specifies the following these printers:
- lpt1 (connected to /dev/par1 and using /usr/spool/output/lpt1 for spooling)
- lpt2 (connected to /dev/par2 and using usr/spool/output/lpt2 for spooling)
Make sure there's an entry for node2 in the /etc/hosts.lpd file on node1.
To refer to these two printers remotely from node2, create a /etc/printcap file on node2 that looks like this:
lpt1:\ :rm=node1:rp=lpt1:sd=/usr/spool/output/lpt1:lp=: lpt2:\ :rm=node1:rp=lpt2:sd=/usr/spool/output/lpt2:lp=:
This specifies the two printers we just located on node1 with the names to be used on node2. Make sure there's an entry for node1 in /etc/hosts.
Local and remote printers
What if we now want to move one of the two printers (say lpt2) from node1 to node2?
We have to change the /etc/printcap file on both nodes. Likewise, we need to change /etc/printcap on any other network nodes we wished to print from:
- On node1:
lpt1:\ :lp=/dev/par1:sd=/usr/spool/output/lpt1: lpt2:\ :rm=node2:rp=lpt2:sd=/usr/spool/output/lpt2:
- On node2:
lpt1:\ :rm=node1:rp=lpt1:sd=/usr/spool/output/lpt1: lpt2:\ :lp=/dev/par1:sd=/usr/spool/output/lpt2:
- On other nodes:
lpt1:\ :rm=node1:rp=lpt1:sd=/usr/spool/output/lpt1: lpt2:\ :rm=node2:rp=lpt2:sd=/usr/spool/output/lpt2:
Make sure you have entries for node1 and node2 in the /etc/hosts file on each node. You also need entries in the /etc/hosts.lpd file on node1 and node2 for each node that you want to be able to use the printers.
If you've set up your remote printing network according to the examples given, you should be able to send a file in /tmp/test on node2 to the printer attached to node1 using a command like this:
lpr -h -Plpt1 /tmp/test
Here's what happens:
- You enter the lpr command to print a file remotely.
- The lpr utility requests printing service.
- The lpd daemon on node2 hears the request, spawns a copy of itself to service the request, and then creates a spooling subdirectory to hold the files to be printed.
- The spawned lpd daemon places the print job in the spooler as two files: a data file containing the file to be printed and a header file containing information about the print job (to be printed as an optional front sheet).
- The spawned lpd daemon processes the spooled print jobs in the order they were received; it starts sending data packets containing the print job to the remote lpd daemon.
- The lpd daemon on node1 receives the packets as a printing request, and after checking that the request is from an approved node, spawns a copy of itself to service the request and also creates a spooling subdirectory to hold the files to be printed. (If the request isn't from an approved source, a refusal message is sent back to the source address.)
- The spawned lpd collects the data packets, places the print job into the spooler queue, and then sends the print jobs, in the order they were received, to the printer you specified.
Remote printing to a printer on another network
Using TCP/IP and lpr, you can print a file on a remote printer connected to a server on another network. You just have to set up your Neutrino network node for remote printing and the remote server for TCP/IP and handling printers compatible with lpr.
For instance, let's suppose you want to print /root/junk.ps, a PostScript file on a node on your Neutrino network, but the only Postscript printer available (windows_printer) is connected to a Windows server with an IP address of 10.2.1.8.
First, make sure that the Windows server is configured for TCP/IP printing and that the printer is compatible with lpr. Then, as root, on your Neutrino node:
- Add a printer description in /etc/printcap,
like this:
rlpt4:\ :rm=windows_server:lp=:rp=windows_printer:\ :sd=/usr/spool/output/lpd/rlpt4:
- Add a new line in /etc/hosts, like this:
10.2.1.8 windows_server
- Create the spool directory:
mkdir /usr/spool/output/lpd/rlpt4
- Start lpd.
To print a PostScript file on the printer, type:
lpr -Prlpt4 junk.ps
Remote printing to a TCP/IP-enabled printer using lpr
A TCP/IP-enabled printer doesn't need an attached computer to provide print services; the printer itself provides the services. So, you use the same basic steps described above, with the following minor alterations:
- Enter the remote printer name and IP address in the
/etc/hosts file on the node you want to print from.
For example:
10.2.0.4 tcpip_printer
- Add an entry to describe the printer in the /etc/printcap
file on the same node:
rlpt2:\ :rm=tcpip_printer:rp=/ps:sd=/usr/spool/output/lpd/rlpt2:
This example shows that the name of the remote machine (in this case, the actual printer) is tcpip_printer and the spool directory is /usr/spool/output/lpd/rlpt2. Note that the remote printer is specified as /ps, which is the name some network printers use for accepting PostScript files. You need to find out the name your printer wants you to use; it may require different names for different types of print file format (e.g. PostScript and text files).
Make sure you've created your spool directory — that's about it. Follow the usual steps described in “Local and remote printers,” and you should be able to print to your remote printer using a command line like this:
lpr -Prlpt2 /root/junk.ps
This sends a PostScript file named /root/junk.ps to the remote printer named tcpip_printer located at the IP address, 10.2.0.4.
![]() |
To keep it simple, we've taken the easy way out in this example by sending a PostScript file to a PostScript printer. It's easy because the formatting is embedded in the PostScript text. You might have to filter the print file to get your printer to work using lpr; you can specify the filter to use in the /etc/printcap entry for the printer (for more information on this, see “Filters”). |
Printing with spooler
Neutrino provides the spooler utility as an alternative printing mechanism to the standard, UNIX-like lp* family. Photon applications use spooler for printing, and use a filter to convert Photon draw-stream (phs) output into the form that the printer understands.
Setting up spooler
The spooler utility is usually started by an enumerator when you start Neutrino (see Controlling How Neutrino Starts). The utility manages one printer, but you can run more than one instance of spooler.
When you start spooler (or the system starts it):
- It sets up an entry for the printer in the /dev
pathname space:
/dev/printers/printer_name/spool
- Next, spooler queries the printer to determine its type, constructs a properties file for the specific printer from the system's general printer-configuration files (see below), and stores the file in the printer's directory under /dev.
- Then, spooler creates a spooling directory:
/var/spool/printers/printer_name.host
- Next, spooler stores the printer-properties file in the spooling directory.
The /etc/printers directory includes general configuration files for the most popular types of printers currently in use, including:
| Printer(s) | Configuration file | Photon filter |
|---|---|---|
| Canon | bjc.cfg | phs-to-bjc |
| Epson | epson.cfg | phs-to-escp2 |
| Epson IJS | epijs.cfg | phs-to-ijs |
| Hewlett-Packard | pcl.cfg | phs-to-pcl |
| PostScript | ps.cfg | phs-to-ps |
There's also a special filter, phs-to-bmp, that converts a Photon draw-stream file into a BMP. The configuration files specify the possible and default settings for the printer, as well as which filter is appropriate for it.
When you print from a Photon application, the application sends the file to be printed to the /dev/printers/printer_name/spool directory. The Photon application may construct another configuration file for the printer that you selected, depending on optional information that you provide.
If you have a file that's already in a form that the printer understands or for which there's a filter, you can print it by copying it into the raw spooling directory:
cp my_file /dev/printers/printer_name/raw
When the spooler sees the print job in /dev/printers/printer_name/raw, it copies the job file to the spooling directory, /var/spool/printers/printer_name.host and invokes the appropriate filter, which prepares the file and then sends it to the printer.

Printing with spooler.
Normally, spooler stores a file to be printed in a directory on disk, then tells the filter where to get the file. If you need to cut down on disk memory, you can use the -F option of spooler to disable the spooling of print files. This option causes the spooler to send sections of a file to be printed directly to a FIFO buffer in piecemeal fashion; the filter receives data to be printed from the FIFO and prints that part of the file. When the buffer has been emptied, spooler loads the next section of the file into the buffer, and so on until the whole file has been printed.
If you ask a Photon application for a print preview, it sends the output to the preview utility. If you want to view or manage the print queue, start prjobs from the command line, or select from the Launch menu. For more information, see the Utilities Reference.
Printing on a USB printer
If you've attached a USB printer to your machine and started the USB stack and devu-prn as described in “USB devices” in the Connecting Hardware chapter, you need to start an instance of spooler to manage it (for example in /etc/rc.d/rc.local).
![]() |
QNX Neutrino doesn't currently enumerate USB printers. |
To set up your USB printer, do the following:
- Create /usr/spool/output/device, where device is the device that devu-prn created for the printer (e.g. usbpar0).
- Start spooler, specifying the printer's device.
For example:
spooler -d /dev/usbpar0
Your printer should now appear in /dev/printers.
Remote printing over Qnet
To print across Qnet, print to /net/nodename/dev/printers/printer_name/spool. The spooler program for the printer must be running on nodename.
Remote printing over TCP/IP
If you want to set up spooler to print on a remote printer, you can pipe the print job to lpr. This takes advantage of the fact that the filter sends the print job to the printer; you just name the remote printer in the filter command line of the configuration file used by spooler.
To try it, first get your remote printer working using lpr (see “Remote printing to a TCP/IP-enabled printer using lpr”), then do the following:
- Copy the configuration file from the printer you want
to use (in this case, a PostScript printer):
cp /etc/printers/ps.cfg /etc/printers/test.cfg
- Find the filter command lines in test.cfg;
they look like this:
Filter = phs:$d:phs-to-ps Filter = raw:$d:cat
These filter command lines are in the form:
source:destination:filter
The phs filter command line tells the filter to process .phs files by sending them through a filter called phs-to-ps before sending them on to the destination passed by spooler. The raw filter command is for utilities that already produce the correct output for the printer.
- Change the phs filter command line from this:
Filter = phs:$d:phs-to-ps
to this:
Filter = phs:ps:phs-to-ps
- Add a line to tell the filter to send all PostScript files
to the remote printer, rlpt2:
Filter ps:$d:lpr -Prlpt2
What you've done is change the destination from that given by spooler to ps, so that after the .phs file has been converted to a ps type by phs-to-ps, it goes to the ps filter. Then the ps filter line you added sends PostScript files to lpr, forcing output to the remote printer (just as you did in “Remote printing to a TCP/IP-enabled printer using lpr”).
You might be wondering what happened to the destination passed by spooler ($d). Well, that is discarded because lpr (unlike phs-to-ps) doesn't return the job to the filter but completes it itself.
- Finally, start a new instance of spooler,
telling it the pathname of your new configuration file
(in this case /etc/printers/test.cfg) and the name
of the printer you want to use (in this case rlpt2),
like this:
spooler -d /dev/null -c /etc/printers/test.cfg -n rlpt2 &
The -n option specifies the name of the printer, which appears in a Photon application's Print dialog.
- If you want to start spooler like this whenever you boot your machine, add the above command to your /etc/rc.d/rc.local file. For more information, see Controlling How Neutrino Starts.
Now, you should be able to print your PostScript file on your remote TCP/IP-enabled printer, either from Photon or from the command line.
- Remote printing from Photon:
Select the correct printer (in this example, rlpt2) in the Select Printer dialog box.
- Remote printing from the command line:
Copy the print file to the directory that spooler uses:
cp /root/my_file.ps /dev/printers/rlpt2/spool/
Troubleshooting
Understanding lpr error messages
The following error messages from the lp* print utilities may help you troubleshoot your printing problems:
lpr error messages
- lpr: filename: copyfile is too large
- The submitted file was larger than the printer's maximum file size, as defined by the mx capability in its printcap entry.
- lpr: printer: unknown printer
- The printer wasn't found in the /etc/printcap database, perhaps because an entry is missing or incorrect.
- lpr: printer: jobs queued, but cannot start daemon
- The connection to lpd
on the local machine failed, probably because the printer server
has died or isn't responding. The superuser can restart lpd
by typing:
/usr/bin/lpd
You can also check the state of the master printer daemon:
sin -P lpd
Another possibility is that the user ID for lpr isn't root and its group ID isn't daemon. You can check by typing:
ls -lg /usr/bin/lpr
- lpr: printer: printer queue is disabled
- This means the queue was turned off with the lprc disable command (see “lprc — printer-control program”) to prevent lpr from putting files in the queue. This is usually done when a printer is going to be down for a long time. The superuser can turn the printer back on using lprc.
lprq error messages
- waiting for printer to become ready (offline ?)
- The daemon couldn't open the printer device. This can happen
for several reasons (e.g. the printer is offline or out of paper,
or the paper is jammed). The actual reason depends on the meaning
of error codes returned by the system device driver; some printers
can't supply enough information to distinguish when a printer
is offline or having trouble, especially if connected through a
serial line.
Another possible cause of this message is that some other process, such as an output filter, has an exclusive open on the device: all you can do in this case is kill off the offending program(s) and restart the printer with lprc.
- printer is ready and printing
- The lprq program checks to see if a daemon process exists for the printer and prints the file status located in the spooling directory. If the daemon isn't responding, the root user can use lprc to abort the current daemon and start a new one.
- waiting for host to come up
- This implies that there's a daemon trying to connect to the remote machine named host to send the files in the local queue. If the remote machine is up, lpd on the remote machine is probably dead or hung and should be restarted.
- sending to host
- The files should be in the process of being transferred to the remote host. If not, root should use lprc to abort and restart the local daemon.
- Warning: printer is down
- The printer has been marked as being unavailable with lprc.
- Warning: no daemon present
- The lpd
process overseeing the spooling queue, as specified in the lock
file in that directory, doesn't exist. This normally occurs only when
the daemon has unexpectedly died. Check the error log file for the
printer and the syslogd
log to diagnose the problem. To restart an lpd, type:
lprc restart printer
- no space on remote; waiting for queue to drain
- This implies that there isn't enough disk space on the remote machine. If the file is large enough, there will never be enough space on the remote (even after the queue on the remote is empty). The solution here is to move the spooling queue or make more free space on the remote machine.
lprrm error messages
- lprrm: printer: cannot restart printer daemon
- This case is the same as when lpr prints that the daemon can't be started.
lprc error messages
- couldn't start printer
- This case is the same as when lpr reports that the daemon can't be started.
- cannot examine spool directory
- Error messages beginning with cannot are usually because of incorrect ownership or protection mode of the lock file, spooling directory, or lprc program.
lpd error messages
The lpd utility can log many different messages using syslogd. Most of these messages are about files that can't be opened and usually imply that the /etc/printcap file or the protection modes of the files are incorrect. Files may also be inaccessible if people bypass the lpr program.
In addition to messages generated by lpd, any of the filters that lpd spawns may log messages to the syslog file or to the error log file (the file specified in the lf entry in /etc/printcap). If you want to debug problems, run syslogd.
Troubleshooting remote printing problems
If the file you send doesn't print, you may get an error message from one of the lp* print utilities; see “Understanding lpr error messages.” If you don't get an error message, check the following:
- Although the spawned lpd program creates spooler subdirectories as required to hold print jobs, you must create the main spooling directory yourself: make sure this directory (default /usr/spool/output/lpd) exists.
- Verify the contents of the /etc/printcap on each node.
- If lpd isn't already running, but you can't start it, check to see if the lock file, /usr/spool/output/lpd.lock, exists. If this file exists when lpd isn't running (e.g after a power failure or system crash), remove it.
- Make sure that the /etc/hosts.lpd on the printing node contains the name of the sending node.
- Make sure that io-pkt* is running with the appropriate shared objects.
- Run syslogd and examine the syslog file for logged system messages.
![]() |
![]() |
![]() |
![]() |

![[Previous]](prev.gif)
![[Contents]](contents.gif)
![[Index]](keyword_index.gif)
![[Next]](next.gif)