ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Lab1 Xv6 and Unix utilities

2022-02-03 15:58:00  阅读:267  来源: 互联网

标签:int Lab1 utilities char Unix exit fd user close


Lab1 Xv6 and Unix utilities

sleep

user/sleep.c

implement the UNIX program sleep for xv6; your sleep should pause for a user-specified number of ticks. A tick is a notion of time defined by the xv6 kernel, namely the time between two interrupts from the timer chip. Your solution should be in the file 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

  • Write a program that uses UNIX system calls to ‘‘ping-pong’’ a byte between two processes over a pair of pipes, one for each direction.
  • The parent should send a byte to the child; the child should print “< pid >: received ping”, where < pid > is its process ID, write the byte on the pipe to the parent, and exit;
    the parent should read the byte from the child, print “< pid >: received pong”, and exit.
  • Your solution should be in the file 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

Write a concurrent version of prime sieve using pipes. This idea is due to Doug McIlroy, inventor of Unix pipes.
The picture halfway down this page and the surrounding text explain how to do it. Your solution should be in the file 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

Write a simple version of the UNIX find program: find all the files in a directory tree with a specific name. Your
solution should be in the file 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

Write a simple version of the UNIX xargs program: read lines from the standard input and run a command for each line, supplying the line as arguments to the command.
Your solution should be in the file 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

标签:int,Lab1,utilities,char,Unix,exit,fd,user,close
来源: https://blog.csdn.net/qq_50258800/article/details/122776247

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有