Use perlplan9(1) to Audit Old Plan 9 Perl Code Safely
You will finish with a short compatibility audit for old Plan 9 Perl code: the local manual will be identified, its historical assumptions will be separated from ordinary Linux Perl behaviour, and you will have a safe next step for a port. This is an audit guide, not a recipe for installing Plan 9 software on Linux.
The route
Jump straight to the step you need, or tick off Done means at the end.
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 the 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 historical rather than 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 do not run any 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 documentation paths are useful for different jobs. man -w tells you which compressed manual the pager will use. perldoc -l locates the POD source used by Perl's 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.
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 that 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. They are not instructions to rename /usr/bin/perl, create a new interpreter path, or assume that Linux's shell can use /bin/perl.
For a port, 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
The file names and matches above are examples. Your output is the evidence. Do not edit a shebang until you know which interpreter and module set the script actually requires.
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 statements as constraints on the old target, not as a reason to remove modern Linux modules from a working project.
Now compare the interpreter you will use for the port:
$ perl -V:osname -V:osvers -V:archname
osname='linux';
osvers='6.1.0';
archname='x86_64-linux-gnu-thread-multi';
The output proves that this is a Linux, threaded, 64-bit Perl build. It does not prove that a Plan 9 program will run unchanged. Make a small table in your notes with the 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 that were absent from Plan 9 Perl, including chown, chroot, umask, several DBM functions, and several network database and socket functions. It also warns that the list is not complete and that other functions may have undefined behaviour.
Search the project for the high-risk names before attempting 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, ...);
The matching lines are leads for inspection, not automatic failures. A function may be inside dead code, behind a platform check, or supplied by a compatibility layer. Preserve the original source while investigating. If you have already edited a working copy, recover with your version-control checkout or restore the untouched copy from your backup. Do not mass-replace these calls: changing permissions or socket behaviour 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 job-control signals.
Search for handlers and for assumptions about more than one handler being installed:
$ rg -n --glob '*.pl' --glob '*.pm' \
"\$SIG\{|signal|SIG(INT|TERM|CHLD|ALRM)" \
path/to/old-perl-tree
Test a port with a foreground process and a disposable input file first. Do not test signal changes against a production service. A handler that exits differently, reaps children differently, or gets 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 require privileges. 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 documentation only, the sequence described by the manual 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
perl-doc,perlplan9and the local Perl version are recorded.- The old shebang,
.PLfiles, module assumptions and unsupported calls have been identified. - Signal handlers are listed as a separate test concern.
- You have not treated the 1996 Plan 9 instructions as Linux installation commands.
- Any porting edits are kept in a reversible working copy with a clear recovery path.