MIT6.S081 Lab1:Unix utilities

sleep

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){
        fprintf(2, "Usage: sleep seconds\n");
        exit(1);
    }
    int num = atoi(argv[1]);
    sleep(num);
    exit(0);
}

pingpong

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 “: received ping”, where 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 “: 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]; // pipe parent write and child read
    int p2[2]; // pipe parent read and child writes
    char buf[1];
    pipe(p1);
    pipe(p2);

    if(fork()==0){  //child process
        if(read(p1[0],buf,1))
            fprintf(1,"%d: received ping\n",getpid());
        write(p2[1],"B",1);
        close(p2[1]);
    }else{  // parent process
        write(p1[1],"A",1);
        if(read(p2[0],buf,1))
            fprintf(1,"%d: received pong\n",getpid());
        close(p1[1]);
    }
    exit(0);
}

primes

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.
link

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

int main(int argc,char* argv[]){
    int fd[2];
    int prime[36];
    int index = 0;
    for(int i=2;i<=35;i++) prime[index++] = i;
    while(index>0){
        pipe(fd);
        if(fork()==0){  // child process
            close(fd[1]);
            int output = 0,temp=0;
            index = -1;
            while(read(fd[0],&temp,sizeof(temp))!=0){
                if(index<0) output = temp,index++;
                else{
                    if(temp%output!=0) prime[index++]=temp;
                }
            }
            printf("prime %d\n",output);
            close(fd[0]);
        }else{  //parent process
            close(fd[0]);
            for(int i=0;i<index;i++) write(fd[1],&prime[i],sizeof(prime[i]));
            close(fd[1]);
            wait((int *) 0);
            exit(0);
        }
    }
    exit(0);
}

find

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));
  buf[strlen(p)]=0;
  return buf;
}

void find(char *path,char *filename)
{
  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),filename)==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)
        continue;
      memmove(p, de.name, DIRSIZ);
      p[DIRSIZ] = 0;
      if(stat(buf, &st) < 0){
        printf("find: cannot stat %s\n", buf);
        continue;
      }
      if(!strcmp(de.name,".")||!strcmp(de.name,"..")) continue;
      find(buf,filename);
    }
    break;
  }
  close(fd);
}

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

xargs

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 **params = malloc(sizeof(char*)*(argc+2));
    memcpy(params,argv,sizeof(char*)*(argc+1));
    params[argc+1]=0;
    int flag = 1;
    while(flag){
        char buf[520],*p=buf;
        while((flag=read(0,p,1))&&*p!='\n') ++p;
        if(!flag) exit(0);
        *p=0;
        params[argc]=buf;
        if(fork()==0){
            exec(argv[1],params+1);
            exit(0);
        }
        wait(0);
    }
    exit(0);
}

Finish lab 1

MIT6.S081 Lab1:Unix utilities_第1张图片

你可能感兴趣的:(6.S081,unix)