file descriptors
pipes
This commit is contained in:
		
							parent
							
								
									b61c2547b8
								
							
						
					
					
						commit
						c41f1de5d4
					
				
					 16 changed files with 424 additions and 39 deletions
				
			
		
							
								
								
									
										18
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
 | 
			
		||||
       syscall.o ide.o picirq.o mp.o spinlock.o
 | 
			
		||||
       syscall.o ide.o picirq.o mp.o spinlock.o fd.o pipe.o
 | 
			
		||||
 | 
			
		||||
CC = i386-jos-elf-gcc
 | 
			
		||||
LD = i386-jos-elf-ld
 | 
			
		||||
| 
						 | 
				
			
			@ -20,22 +20,30 @@ bootblock : bootasm.S bootmain.c
 | 
			
		|||
	$(OBJCOPY) -S -O binary bootblock.o bootblock
 | 
			
		||||
	./sign.pl bootblock
 | 
			
		||||
 | 
			
		||||
kernel : $(OBJS) bootother.S user1
 | 
			
		||||
kernel : $(OBJS) bootother.S user1 usertests
 | 
			
		||||
	$(CC) -nostdinc -I. -c bootother.S
 | 
			
		||||
	$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
 | 
			
		||||
	$(OBJCOPY) -S -O binary bootother.out bootother
 | 
			
		||||
	$(OBJDUMP) -S bootother.o > bootother.asm
 | 
			
		||||
	$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1
 | 
			
		||||
	$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1 usertests
 | 
			
		||||
	$(OBJDUMP) -S kernel > kernel.asm
 | 
			
		||||
 | 
			
		||||
vectors.S : vectors.pl
 | 
			
		||||
	perl vectors.pl > vectors.S
 | 
			
		||||
 | 
			
		||||
user1 : user1.c
 | 
			
		||||
user1 : user1.c ulib.o
 | 
			
		||||
	$(CC) -nostdinc -I. -c user1.c
 | 
			
		||||
	$(LD) -N -e main -Ttext 0 -o user1 user1.o
 | 
			
		||||
	$(LD) -N -e main -Ttext 0 -o user1 user1.o ulib.o
 | 
			
		||||
	$(OBJDUMP) -S user1 > user1.asm
 | 
			
		||||
 | 
			
		||||
usertests : usertests.c ulib.o
 | 
			
		||||
	$(CC) -nostdinc -I. -c usertests.c
 | 
			
		||||
	$(LD) -N -e main -Ttext 0 -o usertests usertests.o ulib.o
 | 
			
		||||
	$(OBJDUMP) -S usertests > usertests.asm
 | 
			
		||||
 | 
			
		||||
ulib.o : ulib.c
 | 
			
		||||
	$(CC) -nostdinc -I. -c ulib.c
 | 
			
		||||
 | 
			
		||||
-include *.d
 | 
			
		||||
 | 
			
		||||
clean : 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								Notes
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								Notes
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -83,3 +83,11 @@ it's IRQ 0, but it comes at a weird and changing vector (e.g. 119) if
 | 
			
		|||
you don't initialize the PIC. why doesn't jos see this? if i
 | 
			
		||||
initialize the PIC with IRQ_OFFSET 32, the interrupt arrives at vector
 | 
			
		||||
32.
 | 
			
		||||
 | 
			
		||||
test out-of-fd cases for creating pipe.
 | 
			
		||||
test pipe circular buffer
 | 
			
		||||
test pipe writer or reader closes while other active or waiting
 | 
			
		||||
test exit vs fd reference counts
 | 
			
		||||
test write of more than PIPESIZE
 | 
			
		||||
test reader goes first vs writer goes first
 | 
			
		||||
test streaming of a lot of data
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								defs.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -37,6 +37,7 @@ void pic_init(void);
 | 
			
		|||
void mp_init(void);
 | 
			
		||||
int cpu(void);
 | 
			
		||||
int mp_isbcpu(void);
 | 
			
		||||
void lapic_init(int c);
 | 
			
		||||
 | 
			
		||||
// spinlock.c
 | 
			
		||||
extern uint32_t kernel_lock;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,3 +47,18 @@ void release_grant_spinlock(uint32_t* lock, int cpu);
 | 
			
		|||
 | 
			
		||||
// main.c
 | 
			
		||||
void load_icode(struct proc *p, uint8_t *binary, unsigned size);
 | 
			
		||||
 | 
			
		||||
// pipe.c
 | 
			
		||||
struct pipe;
 | 
			
		||||
struct fd;
 | 
			
		||||
int pipe_alloc(struct fd **fd1, struct fd **fd2);
 | 
			
		||||
void pipe_close(struct pipe *p, int writeable);
 | 
			
		||||
int pipe_write(struct pipe *p, char *addr, int n);
 | 
			
		||||
int pipe_read(struct pipe *p, char *addr, int n);
 | 
			
		||||
 | 
			
		||||
// fd.c
 | 
			
		||||
int fd_ualloc();
 | 
			
		||||
struct fd * fd_alloc();
 | 
			
		||||
void fd_close(struct fd *);
 | 
			
		||||
int fd_read(struct fd *fd, char *addr, int n);
 | 
			
		||||
int fd_write(struct fd *fd, char *addr, int n);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										80
									
								
								fd.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								fd.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
#include "types.h"
 | 
			
		||||
#include "param.h"
 | 
			
		||||
#include "x86.h"
 | 
			
		||||
#include "mmu.h"
 | 
			
		||||
#include "proc.h"
 | 
			
		||||
#include "defs.h"
 | 
			
		||||
#include "fd.h"
 | 
			
		||||
 | 
			
		||||
struct fd fds[NFD];
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * allocate a file descriptor number for curproc.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
fd_ualloc()
 | 
			
		||||
{
 | 
			
		||||
  int fd;
 | 
			
		||||
  struct proc *p = curproc[cpu()];
 | 
			
		||||
  for(fd = 0; fd < NOFILE; fd++)
 | 
			
		||||
    if(p->fds[fd] == 0)
 | 
			
		||||
      return fd;
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct fd *
 | 
			
		||||
fd_alloc()
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < NFD; i++){
 | 
			
		||||
    if(fds[i].type == FD_CLOSED){
 | 
			
		||||
      fds[i].type = FD_NONE;
 | 
			
		||||
      fds[i].count = 1;
 | 
			
		||||
      return fds + i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
fd_close(struct fd *fd)
 | 
			
		||||
{
 | 
			
		||||
  if(fd->type == FD_CLOSED || fd->count <= 0)
 | 
			
		||||
    panic("fd_close");
 | 
			
		||||
  fd->count -= 1;
 | 
			
		||||
  if(fd->count == 0){
 | 
			
		||||
    if(fd->type == FD_PIPE)
 | 
			
		||||
      pipe_close(fd->pipe, fd->writeable);
 | 
			
		||||
    fd->type = FD_CLOSED;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * addr is a kernel address, pointing into some process's p->mem.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
fd_write(struct fd *fd, char *addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  if(fd->writeable == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(fd->type == FD_PIPE){
 | 
			
		||||
    return pipe_write(fd->pipe, addr, n);
 | 
			
		||||
  } else {
 | 
			
		||||
    panic("fd_write");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fd_read(struct fd *fd, char *addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  if(fd->readable == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(fd->type == FD_PIPE){
 | 
			
		||||
    return pipe_read(fd->pipe, addr, n);
 | 
			
		||||
  } else {
 | 
			
		||||
    panic("fd_read");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								fd.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								fd.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
struct fd {
 | 
			
		||||
  enum { FD_CLOSED, FD_NONE, FD_PIPE } type;
 | 
			
		||||
  int count; // reference count
 | 
			
		||||
  char readable;
 | 
			
		||||
  char writeable;
 | 
			
		||||
  struct pipe *pipe;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct fd fds[NFD];
 | 
			
		||||
							
								
								
									
										8
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								main.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,8 +11,8 @@
 | 
			
		|||
 | 
			
		||||
extern char edata[], end[];
 | 
			
		||||
extern int acpu;
 | 
			
		||||
extern char _binary_user1_start[];
 | 
			
		||||
extern char _binary_user1_size[];
 | 
			
		||||
extern char _binary_user1_start[], _binary_user1_size[];
 | 
			
		||||
extern char _binary_usertests_start[], _binary_usertests_size[];
 | 
			
		||||
 | 
			
		||||
char buf[512];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ main()
 | 
			
		|||
    cprintf("an application processor\n");
 | 
			
		||||
    release_spinlock(&kernel_lock);
 | 
			
		||||
    acquire_spinlock(&kernel_lock);
 | 
			
		||||
    idtinit();
 | 
			
		||||
    idtinit(); // CPU's idt
 | 
			
		||||
    lapic_init(cpu());
 | 
			
		||||
    curproc[cpu()] = &proc[0]; // XXX
 | 
			
		||||
    swtch();
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ main()
 | 
			
		|||
 | 
			
		||||
#if 1
 | 
			
		||||
  p = newproc();
 | 
			
		||||
  load_icode(p, _binary_user1_start, (unsigned) _binary_user1_size);
 | 
			
		||||
  load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								param.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								param.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2,3 +2,5 @@
 | 
			
		|||
#define PAGE 4096
 | 
			
		||||
#define KSTACKSIZE PAGE
 | 
			
		||||
#define NCPU 8
 | 
			
		||||
#define NOFILE 16 // file descriptors per process
 | 
			
		||||
#define NFD 100 // file descriptors per system
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										100
									
								
								pipe.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								pipe.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
#include "types.h"
 | 
			
		||||
#include "param.h"
 | 
			
		||||
#include "x86.h"
 | 
			
		||||
#include "mmu.h"
 | 
			
		||||
#include "proc.h"
 | 
			
		||||
#include "defs.h"
 | 
			
		||||
#include "fd.h"
 | 
			
		||||
 | 
			
		||||
#define PIPESIZE 512
 | 
			
		||||
 | 
			
		||||
struct pipe {
 | 
			
		||||
  int readopen; // read fd is still open
 | 
			
		||||
  int writeopen; // write fd is still open
 | 
			
		||||
  int writep; // next index to write
 | 
			
		||||
  int readp;  // next index to read
 | 
			
		||||
  char data[PIPESIZE];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pipe_alloc(struct fd **fd1, struct fd **fd2)
 | 
			
		||||
{
 | 
			
		||||
  *fd1 = *fd2 = 0;
 | 
			
		||||
  struct pipe *p = 0;
 | 
			
		||||
 | 
			
		||||
  if((*fd1 = fd_alloc()) == 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  if((*fd2 = fd_alloc()) == 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  if((p = (struct pipe *) kalloc(PAGE)) == 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  (*fd1)->type = FD_PIPE;
 | 
			
		||||
  (*fd1)->readable = 1;
 | 
			
		||||
  (*fd1)->writeable = 0;
 | 
			
		||||
  (*fd1)->pipe = p;
 | 
			
		||||
  (*fd2)->type = FD_PIPE;
 | 
			
		||||
  (*fd2)->readable = 0;
 | 
			
		||||
  (*fd2)->writeable = 1;
 | 
			
		||||
  (*fd2)->pipe = p;
 | 
			
		||||
  return 0;
 | 
			
		||||
 oops:
 | 
			
		||||
  if(p)
 | 
			
		||||
    kfree((char *) p, PAGE);
 | 
			
		||||
  if(*fd1){
 | 
			
		||||
    (*fd1)->type = FD_NONE;
 | 
			
		||||
    fd_close(*fd1);
 | 
			
		||||
  }
 | 
			
		||||
  if(*fd2){
 | 
			
		||||
    (*fd2)->type = FD_NONE;
 | 
			
		||||
    fd_close(*fd2);
 | 
			
		||||
  }
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pipe_close(struct pipe *p, int writeable)
 | 
			
		||||
{
 | 
			
		||||
  if(writeable)
 | 
			
		||||
    p->writeopen = 0;
 | 
			
		||||
  else
 | 
			
		||||
    p->readopen = 0;
 | 
			
		||||
  if(p->readopen == 0 && p->writeopen == 0)
 | 
			
		||||
    kfree((char *) p, PAGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pipe_write(struct pipe *p, char *addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < n; i++){
 | 
			
		||||
    while(((p->writep + 1) % PIPESIZE) == p->readp){
 | 
			
		||||
      if(p->readopen == 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
      sleep(&p->writep);
 | 
			
		||||
    }
 | 
			
		||||
    p->data[p->writep] = addr[i];
 | 
			
		||||
    p->writep = (p->writep + 1) % PIPESIZE;
 | 
			
		||||
  }
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pipe_read(struct pipe *p, char *addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  while(p->readp == p->writep){
 | 
			
		||||
    if(p->writeopen == 0)
 | 
			
		||||
      return 0;
 | 
			
		||||
    sleep(&p->readp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < n; i++){
 | 
			
		||||
    if(p->readp == p->writep)
 | 
			
		||||
      break;
 | 
			
		||||
    addr[i] = p->data[p->readp];
 | 
			
		||||
    p->readp = (p->readp + 1) % PIPESIZE;
 | 
			
		||||
  }
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#include "mmu.h"
 | 
			
		||||
#include "x86.h"
 | 
			
		||||
#include "param.h"
 | 
			
		||||
#include "fd.h"
 | 
			
		||||
#include "proc.h"
 | 
			
		||||
#include "defs.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +50,7 @@ newproc()
 | 
			
		|||
  struct proc *np;
 | 
			
		||||
  struct proc *op = curproc[cpu()];
 | 
			
		||||
  unsigned *sp;
 | 
			
		||||
  int fd;
 | 
			
		||||
 | 
			
		||||
  for(np = &proc[1]; np < &proc[NPROC]; np++)
 | 
			
		||||
    if(np->state == UNUSED)
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +82,13 @@ newproc()
 | 
			
		|||
  np->esp = (unsigned) sp;
 | 
			
		||||
  np->ebp = (unsigned) sp;
 | 
			
		||||
 | 
			
		||||
  // copy file descriptors
 | 
			
		||||
  for(fd = 0; fd < NOFILE; fd++){
 | 
			
		||||
    np->fds[fd] = op->fds[fd];
 | 
			
		||||
    if(np->fds[fd])
 | 
			
		||||
      np->fds[fd]->count += 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  np->state = RUNNABLE;
 | 
			
		||||
 | 
			
		||||
  cprintf("newproc %x\n", np);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								proc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -24,6 +24,7 @@ struct proc{
 | 
			
		|||
  int pid;
 | 
			
		||||
  int ppid;
 | 
			
		||||
  void *chan; // sleep
 | 
			
		||||
  struct fd *fds[NOFILE];
 | 
			
		||||
 | 
			
		||||
  struct Taskstate ts;  // only to give cpu address of kernel stack
 | 
			
		||||
  struct Segdesc gdt[NSEGS];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										93
									
								
								syscall.c
									
										
									
									
									
								
							
							
						
						
									
										93
									
								
								syscall.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -42,6 +42,88 @@ fetcharg(int argno, int *ip)
 | 
			
		|||
  return fetchint(curproc[cpu()], esp + 8 + 4*argno, ip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
putint(struct proc *p, unsigned addr, int ip)
 | 
			
		||||
{
 | 
			
		||||
  if(addr > p->sz - 4)
 | 
			
		||||
    return 0;
 | 
			
		||||
  memcpy(p->mem + addr, &ip, 4);
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
sys_pipe()
 | 
			
		||||
{
 | 
			
		||||
  struct fd *rfd = 0, *wfd = 0;
 | 
			
		||||
  int f1 = -1, f2 = -1;
 | 
			
		||||
  struct proc *p = curproc[cpu()];
 | 
			
		||||
  unsigned fdp;
 | 
			
		||||
 | 
			
		||||
  if(pipe_alloc(&rfd, &wfd) < 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  if((f1 = fd_ualloc()) < 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  p->fds[f1] = rfd;
 | 
			
		||||
  if((f2 = fd_ualloc()) < 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  p->fds[f2] = wfd;
 | 
			
		||||
  if(fetcharg(0, &fdp) < 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  if(putint(p, fdp, f1) < 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  if(putint(p, fdp+4, f2) < 0)
 | 
			
		||||
    goto oops;
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
 oops:
 | 
			
		||||
  cprintf("sys_pipe failed\n");
 | 
			
		||||
  if(rfd)
 | 
			
		||||
    fd_close(rfd);
 | 
			
		||||
  if(wfd)
 | 
			
		||||
    fd_close(wfd);
 | 
			
		||||
  if(f1 >= 0)
 | 
			
		||||
    p->fds[f1] = 0;
 | 
			
		||||
  if(f2 >= 0)
 | 
			
		||||
    p->fds[f2] = 0;
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
sys_write()
 | 
			
		||||
{
 | 
			
		||||
  int fd, n;
 | 
			
		||||
  unsigned addr;
 | 
			
		||||
  struct proc *p = curproc[cpu()];
 | 
			
		||||
 | 
			
		||||
  if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(fd < 0 || fd >= NOFILE)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(p->fds[fd] == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(addr + n > p->sz)
 | 
			
		||||
    return -1;
 | 
			
		||||
  return fd_write(p->fds[fd], p->mem + addr, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
sys_read()
 | 
			
		||||
{
 | 
			
		||||
  int fd, n;
 | 
			
		||||
  unsigned addr;
 | 
			
		||||
  struct proc *p = curproc[cpu()];
 | 
			
		||||
 | 
			
		||||
  if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(fd < 0 || fd >= NOFILE)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(p->fds[fd] == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(addr + n > p->sz)
 | 
			
		||||
    return -1;
 | 
			
		||||
  return fd_read(p->fds[fd], p->mem + addr, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
sys_fork()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +204,7 @@ syscall()
 | 
			
		|||
  int num = cp->tf->tf_regs.reg_eax;
 | 
			
		||||
  int ret = -1;
 | 
			
		||||
 | 
			
		||||
  cprintf("%x sys %d\n", cp, num);
 | 
			
		||||
  //cprintf("%x sys %d\n", cp, num);
 | 
			
		||||
  switch(num){
 | 
			
		||||
  case SYS_fork:
 | 
			
		||||
    ret = sys_fork();
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +218,15 @@ syscall()
 | 
			
		|||
  case SYS_cons_putc:
 | 
			
		||||
    ret = sys_cons_putc();
 | 
			
		||||
    break;
 | 
			
		||||
  case SYS_pipe:
 | 
			
		||||
    ret = sys_pipe();
 | 
			
		||||
    break;
 | 
			
		||||
  case SYS_write:
 | 
			
		||||
    ret = sys_write();
 | 
			
		||||
    break;
 | 
			
		||||
  case SYS_read:
 | 
			
		||||
    ret = sys_read();
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    cprintf("unknown sys call %d\n", num);
 | 
			
		||||
    // XXX fault
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,3 +2,6 @@
 | 
			
		|||
#define SYS_exit 2
 | 
			
		||||
#define SYS_wait 3
 | 
			
		||||
#define SYS_cons_putc 4
 | 
			
		||||
#define SYS_pipe 5
 | 
			
		||||
#define SYS_write 6
 | 
			
		||||
#define SYS_read 7
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								trap.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								trap.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -37,14 +37,14 @@ trap(struct Trapframe *tf)
 | 
			
		|||
 | 
			
		||||
  acquire_spinlock(&kernel_lock); // released in trapret in trapasm.S
 | 
			
		||||
 | 
			
		||||
  cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
 | 
			
		||||
 | 
			
		||||
  if(v == T_SYSCALL){
 | 
			
		||||
    curproc[cpu()]->tf = tf;
 | 
			
		||||
    syscall();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
 | 
			
		||||
 | 
			
		||||
  if(v == 32){
 | 
			
		||||
    // probably clock
 | 
			
		||||
    return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										44
									
								
								ulib.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ulib.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
int
 | 
			
		||||
fork()
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $1, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cons_putc(int c)
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $4, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
puts(char *s)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; s[i]; i++)
 | 
			
		||||
    cons_putc(s[i]);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pipe(int fds[])
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $5, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
read(int fd, char *buf, int n)
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $7, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
write(int fd, char *buf, int n)
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $6, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								user1.c
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								user1.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,35 +1,19 @@
 | 
			
		|||
int
 | 
			
		||||
fork()
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $1, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cons_putc(int c)
 | 
			
		||||
{
 | 
			
		||||
  asm("mov $4, %eax");
 | 
			
		||||
  asm("int $48");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
puts(char *s)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; s[i]; i++)
 | 
			
		||||
    cons_putc(s[i]);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
char buf[32];
 | 
			
		||||
 | 
			
		||||
main()
 | 
			
		||||
{
 | 
			
		||||
  int pid;
 | 
			
		||||
  int pid, fds[2], n;
 | 
			
		||||
 | 
			
		||||
  pipe(fds);
 | 
			
		||||
  pid = fork();
 | 
			
		||||
  if(pid == 0){
 | 
			
		||||
    cons_putc('C');
 | 
			
		||||
  if(pid > 0){
 | 
			
		||||
    write(fds[1], "xyz", 4);
 | 
			
		||||
    puts("w");
 | 
			
		||||
  } else {
 | 
			
		||||
    cons_putc('P');
 | 
			
		||||
    n = read(fds[0], buf, sizeof(buf));
 | 
			
		||||
    puts("r: ");
 | 
			
		||||
    puts(buf);
 | 
			
		||||
    puts("\n");
 | 
			
		||||
  }
 | 
			
		||||
  while(1)
 | 
			
		||||
    ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								usertests.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								usertests.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
// simple fork and pipe read/write
 | 
			
		||||
 | 
			
		||||
char buf[32];
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pipe1()
 | 
			
		||||
{
 | 
			
		||||
  int fds[2], pid;
 | 
			
		||||
 | 
			
		||||
  pipe(fds);
 | 
			
		||||
  pid = pipe();
 | 
			
		||||
  if(pid == 0){
 | 
			
		||||
    write(fds[1], "xyz", 4);
 | 
			
		||||
  } else {
 | 
			
		||||
    read(fds[0], buf, sizeof(buf));
 | 
			
		||||
    if(buf[0] != 'x' || buf[1] != 'y'){
 | 
			
		||||
      puts("pipe1 oops\n");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  puts("pipe1 ok\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main()
 | 
			
		||||
{
 | 
			
		||||
  pipe1();
 | 
			
		||||
 | 
			
		||||
  while(1)
 | 
			
		||||
    ;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue