Home / Alt manpages / perlplan9(1)

  • perlplan9(1)
  • User command
  • linux

Use perlplan9(1) to Audit Old Plan 9 Perl Code Safely

Somebody hands you a decades-old Perl tree that once ran on Plan 9, and perlplan9(1) is the only clue to what it actually assumed about its world. You will identify the local manual, pull apart its historical assumptions from ordinary Linux Perl behaviour, and end up with a safe next step for a port. This is an audit guide, not a recipe for installing Plan 9 software on Linux.

Allow about 20 minutes. You need a shell and the perl-doc package. The examples below were checked with Perl 5.38.2 on Linux and perl-doc package version 5.38.2-3.2ubuntu0.6. The manual itself describes Plan 9 Perl 5.003_7, revised in 1996, so its feature list is history, not a description of this Linux interpreter.

1. Confirm that you have the right manual

Start with read-only checks. They need no elevated privileges and run no Perl program:

$ dpkg-query -W -f='${Package} ${Version}\n' perl-doc
perl-doc 5.38.2-3.2ubuntu0.6
$ command -v perl
/usr/bin/perl
$ man -w perlplan9
/usr/share/man/man1/perlplan9.1.gz
$ perldoc -l perlplan9
/usr/share/perl/5.38/pod/perlplan9.pod

The two paths do different jobs. man -w tells you which compressed manual the pager will use. perldoc -l locates the POD source used by Perl's own documentation tool. If either lookup fails, install or repair perl-doc through your normal package process; do not fetch a similarly named file into a system directory to paper over it.

Checkpoint

You should have a real path for perlplan9 and a package version recorded beside your audit notes.

2. Read the invocation rules as target-platform notes

Open the relevant section without changing anything:

$ MANWIDTH=100 man perlplan9 | sed -n '/Invoking Perl/,/What.s in Plan 9 Perl/p'

The manual says a directly invoked Plan 9 Perl script should use #!/bin/perl. It also describes Perl, with a capital P, as an Acme-friendly invocation that formats errors like filename:18. Those are Plan 9 execution conventions, not instructions to rename /usr/bin/perl, create a new interpreter path, or assume Linux's shell can use /bin/perl.

For the port itself, search the source for the shebang and for scripts whose names end in .PL. A .PL file may be self-configuring in the old distribution, but that does not make it portable to a modern Linux build. Record the generated interpreter path rather than replacing it blindly:

$ rg -n '^#!|\.PL\b' path/to/old-perl-tree
path/to/old-perl-tree/tool.pl:1:#!/bin/perl
path/to/old-perl-tree/configure.PL:1:#!/usr/bin/perl

Those file names and matches are examples, your own output is the evidence. Do not edit a shebang until you know which interpreter and module set the script actually needs.

3. Record the feature and module boundary

Read the next two sections of the manual:

$ MANWIDTH=100 man perlplan9 | sed -n '/What.s in Plan 9 Perl/,/Perl5 Functions/p'

The documented Plan 9 build provides static loading and names Opcode, FileHandle, Fcntl and POSIX as useful extensions. It says dynamic loading and MakeMaker were unavailable at that point. Treat those as constraints on the old target, not as a reason to strip modern Linux modules out of a working project.

Now compare against the interpreter you will actually use for the port:

$ perl -V:osname -V:osvers -V:archname
osname='linux';
osvers='6.1.0';
archname='x86_64-linux-gnu-thread-multi';

That output proves this is a Linux, threaded, 64-bit Perl build. It does not prove a Plan 9 program will run unchanged. Keep a small table in your notes: source file, its interpreter line, modules loaded, and any Plan 9-specific system calls.

4. Check the unsupported function list before changing code

The manual lists functions absent from Plan 9 Perl, including chown, chroot, umask, several DBM functions, and several network database and socket functions. It also warns the list is not complete and other functions may behave undefined.

Search the project for those high-risk names before you attempt a port:

$ rg -n --glob '*.pl' --glob '*.pm' \
  '\b(chown|chroot|umask|dbm(open|close)|getsockopt|setsockopt|recvmsg|sendmsg)\b' \
  path/to/old-perl-tree
path/to/old-perl-tree/lib/Permissions.pm:42:umask 027;
path/to/old-perl-tree/lib/SocketCompat.pm:18:my $peer = getsockopt($socket, ...);

Matching lines are leads for inspection, not automatic failures. A function may sit in dead code, behind a platform check, or come from a compatibility layer. Preserve the original source while you investigate. If you have already edited a working copy, recover it with your version-control checkout or restore the untouched copy from backup.

Warning

Do not mass-replace these calls. Changing permissions or socket behaviour without understanding why the code was written that way can create a security defect.

5. Treat signals as a separate porting risk

Plan 9 Perl used POSIX signal emulation through Plan 9's ANSI POSIX Environment, and the manual says signal stacking was not supported. It lists signals such as SIGINT, SIGTERM, SIGCHLD and the job-control signals.

Search for handlers and for any assumption that more than one handler gets installed:

$ rg -n --glob '*.pl' --glob '*.pm' \
  "\$SIG\{|signal|SIG(INT|TERM|CHLD|ALRM)" \
  path/to/old-perl-tree

Test a port against a foreground process and a disposable input file first, never against a production service. A handler that exits differently, reaps children differently, or gets silently overwritten can leave a service running without its intended shutdown path. The safe recovery is to stop the test process, restore the previous handler code, and rerun the original test case.

6. Keep the historical build instructions in their lane

The manual describes a Plan 9 build under /sys/src/cmd/perl, using plan9/setup.rc, mk install, optionally mk installall, and later mk man. These commands belong on a prepared Plan 9 source tree. They are not Linux commands.

Warning

Do not run setup.rc, mk install or mk installall from an extracted archive on this Linux host. The documented process writes source and installed software into system locations and may need privileges, and there is no useful undo command in the manual. If you genuinely need a Plan 9 build, use a disposable Plan 9 environment, snapshot it first, and keep the source tree separate from the host's Linux Perl installation. Only an environment snapshot or a documented package removal gives you a reliable recovery path.

For reference only, the sequence the manual describes is:

; plan9/setup.rc
; cd /sys/src/cmd/perl/5.00301
; mk install
; mk man

The semicolon prompt marks Plan 9 context. Do not paste this block into a Linux shell. On Linux, use man perl or perldoc perl for the installed interpreter instead.

Done means

  • Manual identified: perl-doc, perlplan9 and the local Perl version are recorded.
  • Risk areas found: the old shebang, .PL files, module assumptions and unsupported calls have been identified.
  • Signals flagged separately: signal handlers are listed as their own test concern.
  • Timeline respected: the 1996 Plan 9 instructions were not treated as Linux installation commands.
  • Reversible edits: any porting changes sit in a reversible working copy with a clear recovery path.