exec arguments
This commit is contained in:
parent
c59361f143
commit
8455980b27
7 changed files with 89 additions and 17 deletions
10
Makefile
10
Makefile
|
@ -66,6 +66,10 @@ usertests : usertests.o $(ULIB)
|
||||||
$(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB)
|
$(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB)
|
||||||
$(OBJDUMP) -S usertests > usertests.asm
|
$(OBJDUMP) -S usertests > usertests.asm
|
||||||
|
|
||||||
|
echo : echo.o $(ULIB)
|
||||||
|
$(LD) -N -e main -Ttext 0 -o echo echo.o $(ULIB)
|
||||||
|
$(OBJDUMP) -S echo > echo.asm
|
||||||
|
|
||||||
userfs : userfs.o $(ULIB)
|
userfs : userfs.o $(ULIB)
|
||||||
$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)
|
$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)
|
||||||
$(OBJDUMP) -S userfs > userfs.asm
|
$(OBJDUMP) -S userfs > userfs.asm
|
||||||
|
@ -73,12 +77,12 @@ userfs : userfs.o $(ULIB)
|
||||||
mkfs : mkfs.c fs.h
|
mkfs : mkfs.c fs.h
|
||||||
cc -o mkfs mkfs.c
|
cc -o mkfs mkfs.c
|
||||||
|
|
||||||
fs.img : mkfs usertests
|
fs.img : mkfs usertests echo
|
||||||
./mkfs fs.img usertests
|
./mkfs fs.img usertests echo
|
||||||
|
|
||||||
-include *.d
|
-include *.d
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f *.o *.d *.asm vectors.S parport.out \
|
rm -f *.o *.d *.asm vectors.S parport.out \
|
||||||
bootblock kernel xv6.img user1 userfs usertests \
|
bootblock kernel xv6.img user1 userfs usertests \
|
||||||
fs.img mkfs
|
fs.img mkfs echo
|
||||||
|
|
2
Notes
2
Notes
|
@ -161,3 +161,5 @@ need to lock bufs in bio between bread and brelse
|
||||||
test 14-character file names
|
test 14-character file names
|
||||||
and file arguments longer than 14
|
and file arguments longer than 14
|
||||||
and directories longer than one sector
|
and directories longer than one sector
|
||||||
|
|
||||||
|
kalloc() can return 0; do callers handle this right?
|
||||||
|
|
14
echo.c
Normal file
14
echo.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < argc; i++){
|
||||||
|
puts(argv[i]);
|
||||||
|
puts(" ");
|
||||||
|
}
|
||||||
|
puts("\n");
|
||||||
|
exit();
|
||||||
|
}
|
5
mkfs.c
5
mkfs.c
|
@ -144,11 +144,6 @@ winode(uint inum, struct dinode *ip)
|
||||||
dip = ((struct dinode *) buf) + (inum % IPB);
|
dip = ((struct dinode *) buf) + (inum % IPB);
|
||||||
*dip = *ip;
|
*dip = *ip;
|
||||||
wsect(bn, buf);
|
wsect(bn, buf);
|
||||||
printf("wi %d size %d addrs %d %d...\n",
|
|
||||||
inum,
|
|
||||||
xint(dip->size),
|
|
||||||
xint(dip->addrs[0]),
|
|
||||||
xint(dip->addrs[1]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
70
syscall.c
70
syscall.c
|
@ -58,17 +58,20 @@ fetcharg(int argno, void *ip)
|
||||||
return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
|
return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that an entire string is valid in user space
|
// check that an entire string is valid in user space.
|
||||||
|
// returns the length, not including null, or -1.
|
||||||
int
|
int
|
||||||
checkstring(uint s)
|
checkstring(uint s)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
if(fetchbyte(curproc[cpu()], s, &c) < 0)
|
if(fetchbyte(curproc[cpu()], s, &c) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(c == '\0')
|
if(c == '\0')
|
||||||
return 0;
|
return len;
|
||||||
|
len++;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,14 +247,17 @@ int
|
||||||
sys_exec(void)
|
sys_exec(void)
|
||||||
{
|
{
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
uint arg0, sz;
|
uint arg0, arg1, sz=0, ap, sp, p1, p2;
|
||||||
int i;
|
int i, nargs, argbytes, len;
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
struct elfhdr elf;
|
struct elfhdr elf;
|
||||||
struct proghdr ph;
|
struct proghdr ph;
|
||||||
|
char *mem = 0;
|
||||||
|
|
||||||
if(fetcharg(0, &arg0) < 0)
|
if(fetcharg(0, &arg0) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
if(fetcharg(1, &arg1) < 0)
|
||||||
|
return -1;
|
||||||
if(checkstring(arg0) < 0)
|
if(checkstring(arg0) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
ip = namei(cp->mem + arg0);
|
ip = namei(cp->mem + arg0);
|
||||||
|
@ -278,14 +284,62 @@ sys_exec(void)
|
||||||
sz += 4096 - (sz % 4096);
|
sz += 4096 - (sz % 4096);
|
||||||
sz += 4096;
|
sz += 4096;
|
||||||
|
|
||||||
|
mem = kalloc(sz);
|
||||||
|
if(mem == 0)
|
||||||
|
goto bad;
|
||||||
|
memset(mem, 0, sz);
|
||||||
|
|
||||||
|
// arg1 is a pointer to an array of pointers to string.
|
||||||
|
nargs = 0;
|
||||||
|
argbytes = 0;
|
||||||
|
for(i = 0; ; i++){
|
||||||
|
if(fetchint(cp, arg1 + 4*i, &ap) < 0)
|
||||||
|
goto bad;
|
||||||
|
if(ap == 0)
|
||||||
|
break;
|
||||||
|
len = checkstring(ap);
|
||||||
|
if(len < 0)
|
||||||
|
goto bad;
|
||||||
|
nargs++;
|
||||||
|
argbytes += len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// argn\0
|
||||||
|
// ...
|
||||||
|
// arg0\0
|
||||||
|
// 0
|
||||||
|
// ptr to argn
|
||||||
|
// ...
|
||||||
|
// 12: ptr to arg0
|
||||||
|
// 8: argv (points to ptr to arg0)
|
||||||
|
// 4: argc
|
||||||
|
// 0: fake return pc
|
||||||
|
sp = sz - argbytes - (nargs+1)*4 - 4 - 4 - 4;
|
||||||
|
*(uint*)(mem + sp) = 0xffffffff;
|
||||||
|
*(uint*)(mem + sp + 4) = nargs;
|
||||||
|
*(uint*)(mem + sp + 8) = (uint)(sp + 12);
|
||||||
|
|
||||||
|
p1 = sp + 12;
|
||||||
|
p2 = sp + 12 + (nargs + 1) * 4;
|
||||||
|
for(i = 0; i < nargs; i++){
|
||||||
|
fetchint(cp, arg1 + 4*i, &ap);
|
||||||
|
len = checkstring(ap);
|
||||||
|
memmove(mem + p2, cp->mem + ap, len + 1);
|
||||||
|
*(uint*)(mem + p1) = p2;
|
||||||
|
p1 += 4;
|
||||||
|
p2 += len + 1;
|
||||||
|
}
|
||||||
|
*(uint*)(mem + p1) = 0;
|
||||||
|
|
||||||
// commit to the new image.
|
// commit to the new image.
|
||||||
kfree(cp->mem, cp->sz);
|
kfree(cp->mem, cp->sz);
|
||||||
cp->sz = sz;
|
cp->sz = sz;
|
||||||
cp->mem = kalloc(cp->sz);
|
cp->mem = mem;
|
||||||
|
mem = 0;
|
||||||
|
|
||||||
for(i = 0; i < elf.phnum; i++){
|
for(i = 0; i < elf.phnum; i++){
|
||||||
if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph))
|
if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph))
|
||||||
goto bad;
|
goto bad2;
|
||||||
if(ph.type != ELF_PROG_LOAD)
|
if(ph.type != ELF_PROG_LOAD)
|
||||||
continue;
|
continue;
|
||||||
if(ph.va + ph.memsz > sz)
|
if(ph.va + ph.memsz > sz)
|
||||||
|
@ -298,13 +352,15 @@ sys_exec(void)
|
||||||
iput(ip);
|
iput(ip);
|
||||||
|
|
||||||
cp->tf->eip = elf.entry;
|
cp->tf->eip = elf.entry;
|
||||||
cp->tf->esp = cp->sz;
|
cp->tf->esp = sp;
|
||||||
setupsegs(cp);
|
setupsegs(cp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
cprintf("exec failed early\n");
|
cprintf("exec failed early\n");
|
||||||
|
if(mem)
|
||||||
|
kfree(mem, sz);
|
||||||
iput(ip);
|
iput(ip);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
3
userfs.c
3
userfs.c
|
@ -3,12 +3,13 @@
|
||||||
// file system tests
|
// file system tests
|
||||||
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
char *args[] = { "echo", "hello", "goodbye", 0 };
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
puts("userfs running\n");
|
puts("userfs running\n");
|
||||||
block();
|
block();
|
||||||
exec("usertests");
|
exec("echo", args);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ exitwait(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
puts("usertests starting\n");
|
puts("usertests starting\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue