Support exit status for exit/wait
One test case for returning a exit status Passes usertests, but haven't used it to simplify tests
This commit is contained in:
		
							parent
							
								
									035cca95fe
								
							
						
					
					
						commit
						7e6c37e67e
					
				
					 22 changed files with 319 additions and 297 deletions
				
			
		| 
						 | 
					@ -82,7 +82,7 @@ void            printfinit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// proc.c
 | 
					// proc.c
 | 
				
			||||||
int             cpuid(void);
 | 
					int             cpuid(void);
 | 
				
			||||||
void            exit(void);
 | 
					void            exit(int);
 | 
				
			||||||
int             fork(void);
 | 
					int             fork(void);
 | 
				
			||||||
int             growproc(int);
 | 
					int             growproc(int);
 | 
				
			||||||
pagetable_t     proc_pagetable(struct proc *);
 | 
					pagetable_t     proc_pagetable(struct proc *);
 | 
				
			||||||
| 
						 | 
					@ -97,7 +97,7 @@ void            sched(void);
 | 
				
			||||||
void            setproc(struct proc*);
 | 
					void            setproc(struct proc*);
 | 
				
			||||||
void            sleep(void*, struct spinlock*);
 | 
					void            sleep(void*, struct spinlock*);
 | 
				
			||||||
void            userinit(void);
 | 
					void            userinit(void);
 | 
				
			||||||
int             wait(void);
 | 
					int             wait(uint64);
 | 
				
			||||||
void            wakeup(void*);
 | 
					void            wakeup(void*);
 | 
				
			||||||
void            yield(void);
 | 
					void            yield(void);
 | 
				
			||||||
int             either_copyout(int user_dst, uint64 dst, void *src, uint64 len);
 | 
					int             either_copyout(int user_dst, uint64 dst, void *src, uint64 len);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,6 +141,7 @@ freeproc(struct proc *p)
 | 
				
			||||||
  p->name[0] = 0;
 | 
					  p->name[0] = 0;
 | 
				
			||||||
  p->chan = 0;
 | 
					  p->chan = 0;
 | 
				
			||||||
  p->killed = 0;
 | 
					  p->killed = 0;
 | 
				
			||||||
 | 
					  p->xstate = 0;
 | 
				
			||||||
  p->state = UNUSED;
 | 
					  p->state = UNUSED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -319,7 +320,7 @@ reparent(struct proc *p, struct proc *parent) {
 | 
				
			||||||
// An exited process remains in the zombie state
 | 
					// An exited process remains in the zombie state
 | 
				
			||||||
// until its parent calls wait().
 | 
					// until its parent calls wait().
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
exit(void)
 | 
					exit(int status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  struct proc *p = myproc();
 | 
					  struct proc *p = myproc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -350,6 +351,7 @@ exit(void)
 | 
				
			||||||
  // Parent might be sleeping in wait().
 | 
					  // Parent might be sleeping in wait().
 | 
				
			||||||
  wakeup1(p->parent);
 | 
					  wakeup1(p->parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  p->xstate = status;
 | 
				
			||||||
  p->state = ZOMBIE;
 | 
					  p->state = ZOMBIE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  release(&p->parent->lock);
 | 
					  release(&p->parent->lock);
 | 
				
			||||||
| 
						 | 
					@ -362,7 +364,7 @@ exit(void)
 | 
				
			||||||
// Wait for a child process to exit and return its pid.
 | 
					// Wait for a child process to exit and return its pid.
 | 
				
			||||||
// Return -1 if this process has no children.
 | 
					// Return -1 if this process has no children.
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
wait(void)
 | 
					wait(uint64 addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  struct proc *np;
 | 
					  struct proc *np;
 | 
				
			||||||
  int havekids, pid;
 | 
					  int havekids, pid;
 | 
				
			||||||
| 
						 | 
					@ -387,6 +389,12 @@ wait(void)
 | 
				
			||||||
        if(np->state == ZOMBIE){
 | 
					        if(np->state == ZOMBIE){
 | 
				
			||||||
          // Found one.
 | 
					          // Found one.
 | 
				
			||||||
          pid = np->pid;
 | 
					          pid = np->pid;
 | 
				
			||||||
 | 
					          if(addr != 0 && copyout(p->pagetable, addr, (char *)&np->xstate,
 | 
				
			||||||
 | 
					                                  sizeof(np->xstate)) < 0) {
 | 
				
			||||||
 | 
					            release(&np->lock);
 | 
				
			||||||
 | 
					            release(&p->lock);
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          freeproc(np);
 | 
					          freeproc(np);
 | 
				
			||||||
          release(&np->lock);
 | 
					          release(&np->lock);
 | 
				
			||||||
          release(&p->lock);
 | 
					          release(&p->lock);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,7 @@ struct proc {
 | 
				
			||||||
  struct proc *parent;         // Parent process
 | 
					  struct proc *parent;         // Parent process
 | 
				
			||||||
  void *chan;                  // If non-zero, sleeping on chan
 | 
					  void *chan;                  // If non-zero, sleeping on chan
 | 
				
			||||||
  int killed;                  // If non-zero, have been killed
 | 
					  int killed;                  // If non-zero, have been killed
 | 
				
			||||||
 | 
					  int xstate;                  // Exit status to be returned to parent's wait
 | 
				
			||||||
  int pid;                     // Process ID
 | 
					  int pid;                     // Process ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // these are private to the process, so p->lock need not be held.
 | 
					  // these are private to the process, so p->lock need not be held.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,6 +246,7 @@ create(char *path, short type, short major, short minor)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if((dp = nameiparent(path, name)) == 0)
 | 
					  if((dp = nameiparent(path, name)) == 0)
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ilock(dp);
 | 
					  ilock(dp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if((ip = dirlookup(dp, name, 0)) != 0){
 | 
					  if((ip = dirlookup(dp, name, 0)) != 0){
 | 
				
			||||||
| 
						 | 
					@ -289,8 +290,9 @@ sys_open(void)
 | 
				
			||||||
  int fd, omode;
 | 
					  int fd, omode;
 | 
				
			||||||
  struct file *f;
 | 
					  struct file *f;
 | 
				
			||||||
  struct inode *ip;
 | 
					  struct inode *ip;
 | 
				
			||||||
 | 
					  int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argstr(0, path, MAXPATH) < 0 || argint(1, &omode) < 0)
 | 
					  if((n = argstr(0, path, MAXPATH)) < 0 || argint(1, &omode) < 0)
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  begin_op();
 | 
					  begin_op();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,10 @@
 | 
				
			||||||
uint64
 | 
					uint64
 | 
				
			||||||
sys_exit(void)
 | 
					sys_exit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  exit();
 | 
					  int n;
 | 
				
			||||||
 | 
					  if(argint(0, &n) < 0)
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					  exit(n);
 | 
				
			||||||
  return 0;  // not reached
 | 
					  return 0;  // not reached
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +32,10 @@ sys_fork(void)
 | 
				
			||||||
uint64
 | 
					uint64
 | 
				
			||||||
sys_wait(void)
 | 
					sys_wait(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return wait();
 | 
					  uint64 p;
 | 
				
			||||||
 | 
					  if(argaddr(0, &p) < 0)
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					  return wait(p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint64
 | 
					uint64
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ usertrap(void)
 | 
				
			||||||
    // system call
 | 
					    // system call
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(p->killed)
 | 
					    if(p->killed)
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // sepc points to the ecall instruction,
 | 
					    // sepc points to the ecall instruction,
 | 
				
			||||||
    // but we want to return to the next instruction.
 | 
					    // but we want to return to the next instruction.
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ usertrap(void)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(p->killed)
 | 
					  if(p->killed)
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // give up the CPU if this is a timer interrupt.
 | 
					  // give up the CPU if this is a timer interrupt.
 | 
				
			||||||
  if(which_dev == 2)
 | 
					  if(which_dev == 2)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								user/cat.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								user/cat.c
									
										
									
									
									
								
							| 
						 | 
					@ -12,12 +12,12 @@ cat(int fd)
 | 
				
			||||||
  while((n = read(fd, buf, sizeof(buf))) > 0) {
 | 
					  while((n = read(fd, buf, sizeof(buf))) > 0) {
 | 
				
			||||||
    if (write(1, buf, n) != n) {
 | 
					    if (write(1, buf, n) != n) {
 | 
				
			||||||
      printf("cat: write error\n");
 | 
					      printf("cat: write error\n");
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if(n < 0){
 | 
					  if(n < 0){
 | 
				
			||||||
    printf("cat: read error\n");
 | 
					    printf("cat: read error\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,16 +28,16 @@ main(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc <= 1){
 | 
					  if(argc <= 1){
 | 
				
			||||||
    cat(0);
 | 
					    cat(0);
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(i = 1; i < argc; i++){
 | 
					  for(i = 1; i < argc; i++){
 | 
				
			||||||
    if((fd = open(argv[i], 0)) < 0){
 | 
					    if((fd = open(argv[i], 0)) < 0){
 | 
				
			||||||
      printf("cat: cannot open %s\n", argv[i]);
 | 
					      printf("cat: cannot open %s\n", argv[i]);
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    cat(fd);
 | 
					    cat(fd);
 | 
				
			||||||
    close(fd);
 | 
					    close(fd);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,5 +15,5 @@ main(int argc, char *argv[])
 | 
				
			||||||
      write(1, "\n", 1);
 | 
					      write(1, "\n", 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,24 +25,24 @@ forktest(void)
 | 
				
			||||||
    if(pid < 0)
 | 
					    if(pid < 0)
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    if(pid == 0)
 | 
					    if(pid == 0)
 | 
				
			||||||
      exit();
 | 
					      exit(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(n == N){
 | 
					  if(n == N){
 | 
				
			||||||
    print("fork claimed to work N times!\n");
 | 
					    print("fork claimed to work N times!\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(; n > 0; n--){
 | 
					  for(; n > 0; n--){
 | 
				
			||||||
    if(wait() < 0){
 | 
					    if(wait(0) < 0){
 | 
				
			||||||
      print("wait stopped early\n");
 | 
					      print("wait stopped early\n");
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(wait() != -1){
 | 
					  if(wait(0) != -1){
 | 
				
			||||||
    print("wait got too many\n");
 | 
					    print("wait got too many\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  print("fork test OK\n");
 | 
					  print("fork test OK\n");
 | 
				
			||||||
| 
						 | 
					@ -52,5 +52,5 @@ int
 | 
				
			||||||
main(void)
 | 
					main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  forktest();
 | 
					  forktest();
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,24 +41,24 @@ main(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc <= 1){
 | 
					  if(argc <= 1){
 | 
				
			||||||
    fprintf(2, "usage: grep pattern [file ...]\n");
 | 
					    fprintf(2, "usage: grep pattern [file ...]\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  pattern = argv[1];
 | 
					  pattern = argv[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc <= 2){
 | 
					  if(argc <= 2){
 | 
				
			||||||
    grep(pattern, 0);
 | 
					    grep(pattern, 0);
 | 
				
			||||||
    exit();
 | 
					    exit(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(i = 2; i < argc; i++){
 | 
					  for(i = 2; i < argc; i++){
 | 
				
			||||||
    if((fd = open(argv[i], 0)) < 0){
 | 
					    if((fd = open(argv[i], 0)) < 0){
 | 
				
			||||||
      printf("grep: cannot open %s\n", argv[i]);
 | 
					      printf("grep: cannot open %s\n", argv[i]);
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    grep(pattern, fd);
 | 
					    grep(pattern, fd);
 | 
				
			||||||
    close(fd);
 | 
					    close(fd);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Regexp matcher from Kernighan & Pike,
 | 
					// Regexp matcher from Kernighan & Pike,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,14 +24,14 @@ main(void)
 | 
				
			||||||
    pid = fork();
 | 
					    pid = fork();
 | 
				
			||||||
    if(pid < 0){
 | 
					    if(pid < 0){
 | 
				
			||||||
      printf("init: fork failed\n");
 | 
					      printf("init: fork failed\n");
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(pid == 0){
 | 
					    if(pid == 0){
 | 
				
			||||||
      exec("sh", argv);
 | 
					      exec("sh", argv);
 | 
				
			||||||
      printf("init: exec sh failed\n");
 | 
					      printf("init: exec sh failed\n");
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    while((wpid=wait()) >= 0 && wpid != pid){
 | 
					    while((wpid=wait(0)) >= 0 && wpid != pid){
 | 
				
			||||||
      //printf("zombie!\n");
 | 
					      //printf("zombie!\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,9 +9,9 @@ main(int argc, char **argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc < 2){
 | 
					  if(argc < 2){
 | 
				
			||||||
    fprintf(2, "usage: kill pid...\n");
 | 
					    fprintf(2, "usage: kill pid...\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  for(i=1; i<argc; i++)
 | 
					  for(i=1; i<argc; i++)
 | 
				
			||||||
    kill(atoi(argv[i]));
 | 
					    kill(atoi(argv[i]));
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,9 +7,9 @@ main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if(argc != 3){
 | 
					  if(argc != 3){
 | 
				
			||||||
    fprintf(2, "Usage: ln old new\n");
 | 
					    fprintf(2, "Usage: ln old new\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if(link(argv[1], argv[2]) < 0)
 | 
					  if(link(argv[1], argv[2]) < 0)
 | 
				
			||||||
    fprintf(2, "link %s %s: failed\n", argv[1], argv[2]);
 | 
					    fprintf(2, "link %s %s: failed\n", argv[1], argv[2]);
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,9 +77,9 @@ main(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc < 2){
 | 
					  if(argc < 2){
 | 
				
			||||||
    ls(".");
 | 
					    ls(".");
 | 
				
			||||||
    exit();
 | 
					    exit(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  for(i=1; i<argc; i++)
 | 
					  for(i=1; i<argc; i++)
 | 
				
			||||||
    ls(argv[i]);
 | 
					    ls(argv[i]);
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ main(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc < 2){
 | 
					  if(argc < 2){
 | 
				
			||||||
    fprintf(2, "Usage: mkdir files...\n");
 | 
					    fprintf(2, "Usage: mkdir files...\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(i = 1; i < argc; i++){
 | 
					  for(i = 1; i < argc; i++){
 | 
				
			||||||
| 
						 | 
					@ -19,5 +19,5 @@ main(int argc, char *argv[])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ main(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc < 2){
 | 
					  if(argc < 2){
 | 
				
			||||||
    fprintf(2, "Usage: rm files...\n");
 | 
					    fprintf(2, "Usage: rm files...\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(i = 1; i < argc; i++){
 | 
					  for(i = 1; i < argc; i++){
 | 
				
			||||||
| 
						 | 
					@ -19,5 +19,5 @@ main(int argc, char *argv[])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										20
									
								
								user/sh.c
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								user/sh.c
									
										
									
									
									
								
							| 
						 | 
					@ -65,7 +65,7 @@ runcmd(struct cmd *cmd)
 | 
				
			||||||
  struct redircmd *rcmd;
 | 
					  struct redircmd *rcmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(cmd == 0)
 | 
					  if(cmd == 0)
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch(cmd->type){
 | 
					  switch(cmd->type){
 | 
				
			||||||
  default:
 | 
					  default:
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ runcmd(struct cmd *cmd)
 | 
				
			||||||
  case EXEC:
 | 
					  case EXEC:
 | 
				
			||||||
    ecmd = (struct execcmd*)cmd;
 | 
					    ecmd = (struct execcmd*)cmd;
 | 
				
			||||||
    if(ecmd->argv[0] == 0)
 | 
					    if(ecmd->argv[0] == 0)
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    exec(ecmd->argv[0], ecmd->argv);
 | 
					    exec(ecmd->argv[0], ecmd->argv);
 | 
				
			||||||
    fprintf(2, "exec %s failed\n", ecmd->argv[0]);
 | 
					    fprintf(2, "exec %s failed\n", ecmd->argv[0]);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,7 @@ runcmd(struct cmd *cmd)
 | 
				
			||||||
    close(rcmd->fd);
 | 
					    close(rcmd->fd);
 | 
				
			||||||
    if(open(rcmd->file, rcmd->mode) < 0){
 | 
					    if(open(rcmd->file, rcmd->mode) < 0){
 | 
				
			||||||
      fprintf(2, "open %s failed\n", rcmd->file);
 | 
					      fprintf(2, "open %s failed\n", rcmd->file);
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    runcmd(rcmd->cmd);
 | 
					    runcmd(rcmd->cmd);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
| 
						 | 
					@ -93,7 +93,7 @@ runcmd(struct cmd *cmd)
 | 
				
			||||||
    lcmd = (struct listcmd*)cmd;
 | 
					    lcmd = (struct listcmd*)cmd;
 | 
				
			||||||
    if(fork1() == 0)
 | 
					    if(fork1() == 0)
 | 
				
			||||||
      runcmd(lcmd->left);
 | 
					      runcmd(lcmd->left);
 | 
				
			||||||
    wait();
 | 
					    wait(0);
 | 
				
			||||||
    runcmd(lcmd->right);
 | 
					    runcmd(lcmd->right);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,8 +117,8 @@ runcmd(struct cmd *cmd)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    close(p[0]);
 | 
					    close(p[0]);
 | 
				
			||||||
    close(p[1]);
 | 
					    close(p[1]);
 | 
				
			||||||
    wait();
 | 
					    wait(0);
 | 
				
			||||||
    wait();
 | 
					    wait(0);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case BACK:
 | 
					  case BACK:
 | 
				
			||||||
| 
						 | 
					@ -127,7 +127,7 @@ runcmd(struct cmd *cmd)
 | 
				
			||||||
      runcmd(bcmd->cmd);
 | 
					      runcmd(bcmd->cmd);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					@ -166,16 +166,16 @@ main(void)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(fork1() == 0)
 | 
					    if(fork1() == 0)
 | 
				
			||||||
      runcmd(parsecmd(buf));
 | 
					      runcmd(parsecmd(buf));
 | 
				
			||||||
    wait();
 | 
					    wait(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
panic(char *s)
 | 
					panic(char *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  fprintf(2, "%s\n", s);
 | 
					  fprintf(2, "%s\n", s);
 | 
				
			||||||
  exit();
 | 
					  exit(-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ main(int argc, char *argv[])
 | 
				
			||||||
    read(fd, data, sizeof(data));
 | 
					    read(fd, data, sizeof(data));
 | 
				
			||||||
  close(fd);
 | 
					  close(fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  wait();
 | 
					  wait(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@ struct rtcdate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// system calls
 | 
					// system calls
 | 
				
			||||||
int fork(void);
 | 
					int fork(void);
 | 
				
			||||||
int exit(void) __attribute__((noreturn));
 | 
					int exit(int) __attribute__((noreturn));
 | 
				
			||||||
int wait(void);
 | 
					int wait(int*);
 | 
				
			||||||
int pipe(int*);
 | 
					int pipe(int*);
 | 
				
			||||||
int write(int, const void*, int);
 | 
					int write(int, const void*, int);
 | 
				
			||||||
int read(int, void*, int);
 | 
					int read(int, void*, int);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										483
									
								
								user/usertests.c
									
										
									
									
									
								
							
							
						
						
									
										483
									
								
								user/usertests.c
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -27,7 +27,7 @@ wc(int fd, char *name)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if(n < 0){
 | 
					  if(n < 0){
 | 
				
			||||||
    printf("wc: read error\n");
 | 
					    printf("wc: read error\n");
 | 
				
			||||||
    exit();
 | 
					    exit(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  printf("%d %d %d %s\n", l, w, c, name);
 | 
					  printf("%d %d %d %s\n", l, w, c, name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -39,16 +39,16 @@ main(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(argc <= 1){
 | 
					  if(argc <= 1){
 | 
				
			||||||
    wc(0, "");
 | 
					    wc(0, "");
 | 
				
			||||||
    exit();
 | 
					    exit(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(i = 1; i < argc; i++){
 | 
					  for(i = 1; i < argc; i++){
 | 
				
			||||||
    if((fd = open(argv[i], 0)) < 0){
 | 
					    if((fd = open(argv[i], 0)) < 0){
 | 
				
			||||||
      printf("wc: cannot open %s\n", argv[i]);
 | 
					      printf("wc: cannot open %s\n", argv[i]);
 | 
				
			||||||
      exit();
 | 
					      exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    wc(fd, argv[i]);
 | 
					    wc(fd, argv[i]);
 | 
				
			||||||
    close(fd);
 | 
					    close(fd);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,5 +10,5 @@ main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if(fork() > 0)
 | 
					  if(fork() > 0)
 | 
				
			||||||
    sleep(5);  // Let child exit before parent.
 | 
					    sleep(5);  // Let child exit before parent.
 | 
				
			||||||
  exit();
 | 
					  exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue