a7 is updated with Phil's stdin reading patch. I've written a few more

utilities and modified the v1 man pages for them. Fixed a typo (missing
line) in src/cmd/as.s.
This commit is contained in:
Warren Toomey
2016-03-07 16:17:57 +10:00
parent 42636a83e3
commit cfafcad963
10 changed files with 427 additions and 18 deletions
+5 -2
View File
@@ -39,8 +39,11 @@ cmd: dirs
# $(AS) $(ASARGS) -o $(CMDDIR)/init src/cmd/init.s
others:
$(AS) $(ASARGS) -o $(CMDDIR)/ls src/other/wktls.s
$(AS) $(ASARGS) -o $(CMDDIR)/sh src/other/sh.s
$(AS) $(ASARGS) -o $(CMDDIR)/ls src/other/wktls.s
$(AS) $(ASARGS) -o $(CMDDIR)/sh src/other/sh.s
$(AS) $(ASARGS) -o $(CMDDIR)/stat src/other/wktstat.s
$(AS) $(ASARGS) -o $(CMDDIR)/mv src/other/wktmv.s
$(AS) $(ASARGS) -o $(CMDDIR)/ln src/other/wktln.s
clean:
rm -rf $(SYSDIR)/*
+19
View File
@@ -0,0 +1,19 @@
11/3/70 LN (I)
NAME ln -- link to a file
SYNOPSIS ln name1 name2
DESCRIPTION ln adds another filename to the first filename
FILES
SEE ALSO
DIAGNOSTICS "twofiles" - please provide two filenames
"? file" - unable to make the link
BUGS
OWNER wkt
+19
View File
@@ -0,0 +1,19 @@
11/3/70 MV (I)
NAME mv -- move or rename a file
SYNOPSIS mv name1 name2
DESCRIPTION mv changes the name of name with the rename system call.
FILES
SEE ALSO
DIAGNOSTICS "twofiles" - please provide two filenames
"? file" - either unable to remove or create a file
BUGS The second diagnostic is ambiguous.
OWNER wkt
+50
View File
@@ -0,0 +1,50 @@
11/3/70 STAT (I)
NAME stat - get file status
SYNOPSIS stat name
DESCRIPTION stat gives several kinds of information about one file:
files:
access mode
number of links
owner
size in words
name
All information is self-explanatory except the mode. The
mode is a five-character string whose characters mean the
following:
1 s: file is small (smaller than 4096 words)
l: file is large
d: file is a directory
2 r: owner can read
-: owner cannot read
3 w: owner can write
-: owner cannot write
4 r: non-owner can read
-: non-owner cannot read
5 w: non-owner can write
-: non-owner cannot write
All numeric values are printed in octal
if he cannot be found in "/etc/uids" a number is given.
FILES
SEE ALSO ls with the -l option gives the same information as stat,
except that it also shows the i-node number for each file.
DIAGNOSTICS "name ?" for any error. "nofiles" if no file name is given.
BUGS none
OWNER wkt
+1
View File
@@ -148,6 +148,7 @@ init: 0 " common init for both passes
dac fname " point to first file name
-1
dac eofflg
jms nextfil
jms ioinit
dzm savchr " clear saved char
dzm comflg " clear line comment flag
+11
View File
@@ -0,0 +1,11 @@
lac d10
cll " clear link
mul " mutiply by radix
num2: 10
lacq
cll
idiv; 10
nop
hlt
d10: 10
+41
View File
@@ -0,0 +1,41 @@
" Warren's version of mv. mv file1 file2
main:
lac 017777 i " Load the pointer pointer in 017777
sad d8 " to see if we have two
jmp nofiles " No arguments, stop now
lac 017777 " Move five words past the argument word count
tad d5 " so that AC points at the first argument
dac name1 " and save it
tad d4 " Then do the same for the second name
dac name2
sys link; name1:0; name2:0 " Link the file
spa
jmp badfile " Print out an error on failure
sys exit
nofiles:
lac d8
sys write; 1f; 5 " Write "No files\n" to stderr
sys exit " and exit
1: <tw>; <o 040; <fi>;<le>;<s 012
badfile:
lac name1 " Get the pointer to the filename
dac 1f " Store it in 1f below
lac d8 " Load fd 8 which is stderr
sys write; 1:0; 4 " Write the four words of the filename
lac d8
sys write; 1f; 2 " and then write " ?\n"
sys exit
1: 040;077012 " String literal: " ?\n"
d1: 1
d4: 4
d5: 5
d8: 8
+41
View File
@@ -0,0 +1,41 @@
" Warren's version of mv. mv file1 file2
main:
lac 017777 i " Load the pointer pointer in 017777
sad d8 " to see if we have two
jmp nofiles " No arguments, stop now
lac 017777 " Move five words past the argument word count
tad d5 " so that AC points at the first argument
dac name1 " and save it
tad d4 " Then do the same for the second name
dac name2
sys rename; name1:0; name2:0 " Rename the file
spa
jmp badfile " Print out an error on failure
sys exit
nofiles:
lac d8
sys write; 1f; 5 " Write "No files\n" to stderr
sys exit " and exit
1: <tw>; <o 040; <fi>;<le>;<s 012
badfile:
lac name1 " Get the pointer to the filename
dac 1f " Store it in 1f below
lac d8 " Load fd 8 which is stderr
sys write; 1:0; 4 " Write the four words of the filename
lac d8
sys write; 1f; 2 " and then write " ?\n"
sys exit
1: 040;077012 " String literal: " ?\n"
d1: 1
d4: 4
d5: 5
d8: 8
+179
View File
@@ -0,0 +1,179 @@
" Warren's version of stat. stat file
" Like ls -l, except that we don't print out the i-node
main:
lac 017777 i " Load the pointer pointer in 017777
sad d4 " to see if we have any arguments
jmp nofiles " No arguments, stop now
lac 017777 " Move five words past the argument word count
tad d5 " so that AC points at the first argument
dac statfile " and save in statfile and name
dac name
lac statbufptr " Get the file's details into the statbuf
sys status; statfile:0; 0
spa
jmp badfile
" Ugly code. Improvements welcome!
lac s.perm " See if this is a directory
and isdirmask
sna
jmp 1f
lac fd1
sys write; d; 1 " Yes, print a d
jmp 2f
1: lac s.perm " Not a dir, see if its a large file
and largemask
sna
jmp 1f
lac fd1
sys write; l; 1 " Yes, print an l
jmp 2f
1: lac fd1
sys write; minus; 1 " Not a dir, not large, print an s
2: lac s.perm " Readable by owner?
and ureadmask
sna
jmp 1f
lac fd1
1: sys write; r; 1 " Yes, print an r
jmp 2f
sys write; minus; 1 " No, print a - sign
2: lac s.perm " Writable by owner?
and uwritemask
sna
jmp 1f
lac fd1
sys write; w; 1 " Yes, print a w
jmp 2f
1: lac fd1
sys write; minus; 1 " No, print a - sign
2: lac s.perm " Readable by other?
and oreadmask
sna
jmp 1f
lac fd1
sys write; r; 1 " Yes, print an r
jmp 2f
1: lac fd1
sys write; minus; 1 " No, print a - sign
2: lac s.perm " Writable by other?
and owritemask
sna
jmp 1f
lac fd1
sys write; w; 1 " Yes, print a w
jmp 2f
1: lac fd1
sys write; minus; 1 " No, print a - sign
2: lac fd1
sys write; space; 1 " Print a space
lac s.nlinks " Print the number of links out
jms octal; -2
lac s.uid " Print the user-id out
jms octal; -3
lac s.size " Print the size out
jms octal; -5
printname:
lac fd1
sys write; name:0; 4 " Write the filename out to stdout
lac fd1
sys write; newline; 1 " followed by a newline
sys exit
nofiles:
lac d8
sys write; 1f; 5 " Write "No files\n" to stderr
sys exit " and exit
1: <no>; 040; <fi>;<le>;<s 012
badfile:
lac name " Get the pointer to the filename
dac 1f " Store it in 1f below
lac d8 " Load fd 8 which is stderr
sys write; 1:0; 4 " Write the four words of the filename
lac d8
sys write; 1f; 2 " and then write " ?\n"
sys exit
1: 040;077012 " String literal: " ?\n"
" Octal print code: This code borrowed from ds.s
octal: 0
lmq " Move the negative argument into the MQ
" as we will use shifting to deal with the
" number by shifting groups of 3 digits.
lac d5 " By adding 5 to the negative count and
tad octal i " complementing it, we set the actual
cma " loop count up to 6 - count. So, if we
dac c " want to print 2 digits, we lose 6 - 2 = 4 digits
1:
llss 3 " Lose top 3 bits of the MQ
isz c " Do we have any more to lose?
jmp 1b " Yes, keep looping
lac octal i " Save the actual number of print digits into c
dac c " as a negative number.
1:
cla
llss 3 " Shift 3 more bits into AC
tad o60 " Add AC to ASCII '0'
dac cbuf " and print out the digit
lac fd1
sys write; cbuf; 1
isz c " Any more characters to print out?
jmp 1b " Yes, loop back
lac fd1 " Print out a space
sys write; space; 1
isz octal " Move return address 1 past the argument
jmp octal i " and return from subroutine
longopt: 0 " User set the -l option when this is 1
fd1: 1 " File descriptor 1, stdout
d4: 4
d5: 5
d8: 8
o60: 060
count: 0 " Count of # of directory words read in
cbuf: 0 " Used to print out in the octal routing
c: .=.+1 " Loop counter for printing octal digits
statbufptr: statbuf " Pointer to the statbuf
statbuf: " Status buffer fields below
s.perm: 0
s.blk1: 0
s.blk2: 0
s.blk3: 0
s.blk4: 0
s.blk5: 0
s.blk6: 0
s.blk7: 0
s.uid: 0
s.nlinks: 0
s.size: 0
s.uniq: 0
largemask: 200000 " large file, bigger than 4096 words
isdirmask: 000020 " is a directory
ureadmask: 000010 " user read
uwritemask: 000004 " user write
oreadmask: 000002 " other read
owritemask: 000001 " other write
d: 0144 " ASCII characters: d, l, s, r, w, -, space, \n
l: 0154
s: 0163
r: 0162
w: 0167
minus: 055
space: 040
newline: 012
+61 -16
View File
@@ -7,7 +7,7 @@
use strict;
use warnings;
use Fcntl qw(:seek);
use DateTime;
#use DateTime;
use Data::Dumper;
### Global variables ###
@@ -606,10 +606,10 @@ sub cal {
7 => \&sys_seek,
# 8 tell
9 => \&sys_close,
# 10 link
10 => \&sys_link,
11 => \&sys_unlink,
12 => \&sys_setuid,
# 13 rename
13 => \&sys_rename,
14 => \&sys_exit,
15 => \&sys_time,
16 => \&sys_intrp,
@@ -647,6 +647,8 @@ sub sys_exit {
# Getuid system call
sub sys_getuid {
$AC = $< & MAXINT;
# On PDP-7 Unix, the root user is user-id -1
$AC= MAXINT if ($AC==0);
dprintf( "getuid system call, uid %06o\n", $AC );
$PC += 1;
return;
@@ -656,7 +658,7 @@ sub sys_getuid {
sub sys_setuid {
# For now, do nothing
dprint("setuid system call\n");
dprintf("setuid system call\n");
$PC += 1;
return;
}
@@ -665,7 +667,7 @@ sub sys_setuid {
sub sys_intrp {
# For now, do nothing
dprint("intrp system call\n");
dprintf("intrp system call\n");
$PC += 1;
return;
}
@@ -891,7 +893,7 @@ sub sys_read {
# That filehandle is not open, set an error -1 in octal
if ( !defined( $FD[$fd] ) ) {
dprint("read: fd $fd is not open\n");
dprintf("read: fd $fd is not open\n");
$AC = MAXINT;
return;
}
@@ -899,26 +901,35 @@ sub sys_read {
# Read each word in
my $FH = $FD[$fd];
$count = 0;
my $tty = -t $FH;
foreach my $addr ( $start .. $end ) {
if ( $ISBINARY[$fd] ) {
# Convert three bytes into one 18-bit word
my $result = read( $FH, my $three, 3 );
last if ( $result != 3 ); # Not enough bytes read
my ( $b1, $b2, $b3 ) = unpack( "CCC", $three );
$Mem[$addr] = ( ( $b1 & 077 ) << 12 ) | ( $b2 << 6 ) | $b3;
$Mem[$addr] = ((($b1 & 077) << 12 ) |
(($b2 & 077) << 6 ) |
($b3 & 077));
$count++;
}
else {
# Convert two ASCII characters into one 18-bit word
my $c1 = getc($FH);
my $c2;
last if ( !defined($c1) ); # No character, leave the loop
my $c2 = getc($FH); # No character, make it a NUL
$c2 = "" if ( !defined($c2) );
$Mem[$addr] =
( ord($c1) << 9 ) | ord($c2); # Pack both into one word
}
$count++;
my $word = ord($c1) << 9;
if ( !$tty || $c1 ne "\n") {
$c2 = getc($FH);
if (defined($c2)) {
$word |= ord($c2);
}
}
$Mem[$addr] = $word;
$count++;
last if ($tty && ($c1 eq "\n") || ($c2 eq "\n"));
} # ascii
}
# No error
@@ -946,7 +957,7 @@ sub sys_write {
# That filehandle is not open, set an error -1 in octal
if ( !defined( $FD[$fd] ) ) {
dprint("write: fd $fd is not open\n");
dprintf("write: fd $fd is not open\n");
$AC = MAXINT;
return;
}
@@ -1109,6 +1120,7 @@ sub sys_status {
# 000004 owner write
# 000002 user write
# 000001 user write
# XXX: We don't seem to have the i-node number in this structure?!
# Get the start address of the string
# Convert this to a sensible ASCII filename
@@ -1149,7 +1161,7 @@ sub sys_status {
# Seek syscall
sub sys_seek {
# Seek takes three arguments: AC is the fd, PC+1 is a signed count
# and PC+1 is how to seek: 0=from start, 1=from curptr, 2=from end
# and PC+2 is how to seek: 0=from start, 1=from curptr, 2=from end
# of file. Return AC=0 if OK, -1 on error.
my $fd= $AC;
my $FH= $FD[$fd];
@@ -1167,6 +1179,39 @@ sub sys_seek {
return;
}
# Rename syscall
sub sys_rename {
# Rename takes two arguments: PC+1 is the current filename and
# PC+2 is the new filename. Returns AC=0 on success, AC=-1 on error.
#
my $oldname = mem2arg($Mem[$PC+1]);
my $newname = mem2arg($Mem[$PC+2]);
dprintf( "rename file %s to %s\n", $oldname, $newname );
my $result= rename($oldname, $newname);
# Set the AC result
$AC= ($result)? 0: MAXINT;
$PC += 3;
return;
}
# Link syscall
sub sys_link {
# Link takes two arguments: PC+1 is the current filename and
# PC+2 is the new filename. Returns AC=0 on success, AC=-1 on error.
# Yes, this is not strictly what PDP-7 Unix would have done.
#
my $oldname = mem2arg($Mem[$PC+1]);
my $newname = mem2arg($Mem[$PC+2]);
dprintf( "link file %s to %s\n", $oldname, $newname );
my $result= link($oldname, $newname);
# Set the AC result
$AC= ($result)? 0: MAXINT;
$PC += 3;
return;
}
# Convert an 18-bit word into a scalar which has three sixbit
# values in three bytes. Set the msb in the first byte
sub word2three {