Zhaoyan LU
From Dusk Till Dawn

6.1810

6.1810

Labs

References

Lab 1 Lab: Xv6 and Unix utilities

1.1 Boot xv6

  • Install tools first.
  • Migrate all branches from the original git repo to my own Github repo.
$ git clone --mirror git://g.csail.mit.edu/xv6-labs-2023
$ cd xv6-labs-2023
$ git push --mirror git@github.com:LouisLU9911/xv6-labs-2023.git
  • make qemu
$ make qemu

1.2 sleep

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

int
main(int argc, char *argv[])
{
  if (argc <= 1) {
      char * errMsg = "Please input an integer.";
      write(2, errMsg, strlen(errMsg));
  }

  char * secStr = argv[1];
  int sec = atoi(secStr);
  sleep(sec);
  exit(0);
}

1.3 pingpong

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

int
main(int argc, char *argv[])
{
  int pP2C[2];
  int pC2P[2];
  pipe(pP2C);
  pipe(pC2P);

  if (fork() == 0) {
    char cBuf[1];
    close(pP2C[1]);
    read(pP2C[0], cBuf, 1);
    close(pP2C[0]);
    int cPid = getpid();
    fprintf(1, "%d: received ping\n", cPid);
    close(pC2P[0]);
    write(pC2P[1], cBuf, 1);
    close(pC2P[1]);
  } else {
    char pBuf[1];
    close(pP2C[0]);
    write(pP2C[1], "\n", 1);
    close(pP2C[1]);
    close(pC2P[1]);
    read(pC2P[0], pBuf, 1);
    close(pC2P[0]);
    int pPid = getpid();
    fprintf(1, "%d: received pong\n", pPid);
  }
  exit(0);
}

1.4 primes

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

void
primePipe(int leftFd) {
  int prime = 0;
  if (read(leftFd, &prime, sizeof(prime)) == 0) {
    close(leftFd);
    return;
  }
  fprintf(1, "prime %d\n", prime);

  int p[2];
  pipe(p);
  if (fork() == 0) {
    close(p[1]);
    primePipe(p[0]);
    exit(0);
  }
  close(p[0]);
  int n;
  while (read(leftFd, &n, sizeof(n)) != 0) {
    if (n % prime != 0) {
      write(p[1], &n, sizeof(n));
    }
  }
  close(leftFd);
  close(p[1]);
  wait(0);
}

int
main(int argc, char *argv[])
{
  int p[2];
  pipe(p);
  if (fork() == 0) {
    close(p[1]);
    primePipe(p[0]);
    exit(0);
  }
  close(p[0]);
  for (int i = 2; i <= 35; i++) {
      write(p[1], &i, sizeof(i));
  }
  close(p[1]);
  wait(0);
  exit(0);
}

1.5 find

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

void
checkName(char *path, char *name, char *buf)
{
  if(strcmp(path, name) == 0) {
    fprintf(1, "%s\n", buf);
  }
}

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

  if((fd = open(path, O_RDONLY)) < 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_DEVICE:
  case T_FILE:
    checkName(path, name, 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)
        continue;
      memmove(p, de.name, DIRSIZ);
      p[DIRSIZ] = 0;
      if(stat(buf, &st) < 0){
        printf("find: cannot stat %s\n", buf);
        continue;
      }
      if(st.type == T_DIR &&
         strcmp(de.name, ".") != 0 &&
         strcmp(de.name, "..") != 0){
        find(buf, name);
      } else {
        checkName(de.name, name, buf);
      }
    }
    break;
  }
  close(fd);
}

int
main(int argc, char *argv[])
{
  if(argc == 2){
    find(argv[1], "");
    exit(0);
  }
  if(argc == 3) {
    find(argv[1], argv[2]);
    exit(0);
  }
  fprintf(2, "Syntax error\n");
  exit(1);
}

1.6 xargs

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

int
readline(char *line, int max)
{
  // [0, max-2]
  int p = 0;
  char c;
  while (read(0, &c, 1) == 1) {
    if (p > max - 2) {
      fprintf(2, "grep: command too long\n");
      return -1;
    }
    if (c == '\n') break;
    line[p++] = c;
  }
  line[p] = '\0';
  // fprintf(1, "%s\n", line);
  return p;
}

int
main(int argc, char *argv[])
{
  int i;
  char *newArgv[MAXARG];
  for(i = 1; i < argc; i++){
    newArgv[i-1] = argv[i];
  }

  char line[512];
  while(readline(line, 512) > 0) {
    newArgv[argc-1] = line;
    newArgv[argc] = 0;
    // for(i=0; i<=argc; i++) fprintf(1, "newArgv[%d]: %s\n", i, newArgv[i]);
    if(fork() == 0){
      exec(newArgv[0], newArgv);
    }
    wait(0);
  }
  exit(0);
}

(Optional) 1.7 challenge exercises

Lab 2 Lab: system calls

2.1 Using gdb

Back to top