0
点赞
收藏
分享

微信扫一扫

Lab1 Xv6 and Unix utilities

小a草 2022-02-03 阅读 104

Lab1 Xv6 and Unix utilities

sleep

user/sleep.c

在这里插入图片描述

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
	if(argc == 2){
		sleep(atoi((const char*) argv[1])); // convert ascii to integer and use system call sleep
		exit(0);
	}
	else{
		fprintf(2, "Usage:sleep number...\n");  // put the error masssage to the file descriptor 2
		exit(1); 	// terminate the process, 
				    //status = 1: indicates failure, and reported to wait() 
	}
}

pingpong

user/pingpong.c

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
	int p1[2]; // parent -> child
	int p2[2]; // child -> parent
    char buffer[] = {'x'};
    int length = sizeof(buffer);
	if(argc != 1){
		fprintf(2, "Usage: pingpong\n");
		exit(1);
	}
	pipe(p1);
	pipe(p2);
	if(fork() == 0){ // child
		close(p1[1]);
		close(p2[0]);
		if(read(p1[0], buffer, length) == 1){  // child receives the byte
			printf("%d: received ping\n", getpid());
			write(p2[1], buffer, length);     // child sends the byte to child
			close(p2[1]);
			exit(0);
		}
		close(p2[1]);
		exit(1);			
	}else{  // parent
		close(p1[0]);
		close(p2[1]);
		write(p1[1], buffer,  length); // parent sends a byte to the child
		close(p1[1]);
		wait((int *)0);
		if(read(p2[0], buffer, length) == 1){  // parent receives the byte
			printf("%d: received pong\n", getpid());
		}
		exit(0);
	}
}

primes

user/primes.c

在这里插入图片描述

#include "kernel/types.h"
#include "user/user.h"

void
close_pipe(int *p) {
  close(p[0]);
  close(p[1]);
}

void
primes() {
  int n, p, len;
  int fd[2];

  // read the frist number from previous prime 
  if ((len = read(0, &n, sizeof(int))) <= 0 || n <= 0) {
    close(1);
    exit(0);
  }
  
  // print first number to console
  printf("prime %d\n", n);
  
  pipe(fd);
  if (fork() == 0) { // child process
    close(0);
    dup(fd[0]);  // link the std i/o 0 to fd[0] 
    close_pipe(fd);
    primes();
  } else {      // parent process
    close(1);
    dup(fd[1]); // link the std i/o 1 to fd[1]
    close_pipe(fd); 
    while ((len = read(0, &p, sizeof(int))) > 0 && p > 0) {  // read the number from the prime
      if (p % n != 0) {
        write(1, &p, sizeof(int));  // filter the number
      }
    }
    close(1);
    wait((int *)0);   
  } 
  exit(0);
}

int
main(void) {
  int i;
  int fd[2];
  
  pipe(fd);
  if (fork() == 0) {  // child process
    close(0);
    dup(fd[0]);  // link the std i/o 0 to the fd[0]
    close_pipe(fd);
    primes();
  } else {
    close(1);
    dup(fd[1]);  // link the std i/o 1 to the fd[1]
    close_pipe(fd);
    for (i = 2; i <= 35; i++) {
      write(1, &i, sizeof(int));
    }
    close(1);
    wait((int *)0);
  }
  exit(0);
}

find

user/find.c

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

char*
fmtname(char *path)  // 将路径格式化为文件名
{
  static char buf[DIRSIZ+1];
  char *p;

  // Find first character after last slash. 从字符串末尾开始遍历,直到遇到'/'或者到字符串的头部为止
  for(p=path+strlen(path); p >= path && *p != '/'; p--) ;
  p++;

  // Return blank-padded name.
  if(strlen(p) >= DIRSIZ)  // 字符串太长了
    return p;
  memmove(buf, p, strlen(p)+1);
  return buf;
}

void
find(char *path, char *file)
{
  char buf[512], *p;
  int fd;
  struct dirent de;
  struct stat st;

  if((fd = open(path, 0)) < 0){  // 路径不存在
    fprintf(2, "find: cannot open %s\n", path);
    return;
  }

  if(fstat(fd, &st) < 0){   // 获取不了该路径的状态
    fprintf(2, "find: cannot stat %s\n", path);
    close(fd);
    return;
  }

  switch(st.type){
  case T_FILE:  // 如果这是一个文件
    	if(strcmp(fmtname(path), file) == 0){
			printf("%s\n", path);
	}
    break;

  case T_DIR: // 如果这是一个目录
    if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){  // 路径太长,缓冲区装不下
      printf("find: path too long\n");
      break;
    }
    strcpy(buf, path); 
    p = buf+strlen(buf);
    *p++ = '/';  // 在路径末尾添加'/'
    while(read(fd, &de, sizeof(de)) == sizeof(de)){  // 从该路径读取出文件名或者目录名
      if(de.inum == 0 || de.inum == 1)
        continue;
      if (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
        continue;
      memmove(p, de.name, DIRSIZ);  // 在路径后面添加文件名or目录
      p[DIRSIZ] = 0;      // the end of string is '\0'
      find(buf, file);
    }
    break;

  default:
    break;
  }
  close(fd);
}


int
main(int argc, char *argv[])
{
	if(argc != 3){
		fprintf(2, "Usage: find <path> <file>\n");
		exit(1);
	}
	find(argv[1], argv[2]);
	exit(0);
}

xargs

user/xargs.c

#include "kernel/types.h"
#include "user/user.h"
#include "kernel/param.h"

int
main(int argc, char *argv[])
{
	char *arguments[MAXARG];
	char buff[255];
	char *p = buff, *q = buff;
	int i, offset;
	if(argc <= 1){
		fprintf(2, "Usage: xargc <command>...\n");
		exit(1);
	}
	
	for(i = 1; i < argc; i++){  // get the command which is behind the "xargs"
        arguments[i-1] = argv[i];
    }
    i = i - 1;
    offset = i;  // backup
    
    while(read(0, p, 1)){
    	if(*p == '\n'){  // meet the '\n' and execute it with arguments
    		*p = '\0';
    		arguments[i] = q;
    		if(fork() == 0){
    			exec(arguments[0], arguments);
    			exit(0);
    		}else{
    			wait((int*)0);
    			p = buff;
    			q = p;
    			i = offset;
    		}
    	}else if(*p == ' ' || *p == '\t'){  // meet the ' ' or '\t', find an argument
    		*p = '\0';
    		arguments[i] = q;
    		i = i + 1;
    		p = p + 1;
    		q = p; 
    	}else{
    		p = p + 1;
    	}
    }
	exit(0);
}

other

源代码:https://gitee.com/kiloGrand/xv6-lab/tree/util/user

举报

相关推荐

0 条评论