6.1810
Labs
References
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
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);
}
2.1 Using gdb