> ## Content Index
> Fetch the complete content index at: https://blog.hacking.pub/llms.txt
> Use this file to discover other available public pages before exploring further.

# xv6系列 util实验
- URL: https://blog.hacking.pub/2022/02/09/untitled-8/
- Published: 2022-02-09T14:37:26.000Z
- Updated: 2022-02-09T14:37:26.000Z
- Author: chainhelen

#### Sleep

没啥难度，主要调用系统调用 sleep

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

int
main(int argc, char *argv[])
{
    char *err1 = "not right\0";
    char *err2 = "sleep wrong\0";

    if (argc != 2) {
        write(2, err1, strlen(err1));
    }
    int n = atoi(argv[1]);
    int ret = sleep(n);
    if (ret < 0) {
        write(2, err2, strlen(err2));
    }
    exit(0);
}

```

#### pingpong

熟悉一下fork以及pipe的用法，xv6 book介绍比较详细

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

int
main(int argc, char *argv[])
{
	char *err1 = "len(argc) not right\n0";
//	char *err2 = "pipe faile\0";
	char *err3 = "fork faile\0";

	char buf[8];

	if (argc != 1) {
		write(2, err1, strlen(err1));
		exit(1);
	}
	int p[2];
	pipe(p);

	int pid = fork();
	if (pid < 0) {
		write(2, err3, strlen(err3));
		exit(1);
	}
	if (pid == 0) {
		// child receive one byte
		if (read(p[0], buf, 1) == 1) {
			printf("%d: received pong\n", getpid());
		}
		// child send one byte
		write(p[1], "c", 1);
		exit(0);
	}

	// parent send one byte
	write(p[1], "p", 1);
	// parent receive one byte
	if (read(p[0], buf, 1) == 1) {
		printf("%d: received ping\n", getpid());
	}

	exit(0);
}

```

#### primes

看网上到处都是递归版本，实际只要找到循环节是啥即可

有两个注意的细节点

1. close要放在前面，只读不写的需要先把写close了，否则另一个子进程可能会卡死
2. wait需要加一下，否则输出容易串场

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

int
main(int argc, char *argv[])
{
	char *err1 = "fork failed\0";

	int prev[2];
	pipe(prev);

	int pid = fork();

	if (pid < 0) {
		write(2, err1,  strlen(err1));
		exit(1);
	}

	if (pid == 0) {
		while(1) {
			int base = 0;
			close(prev[1]);  // 有两个点需要注意，这个close要放在前面，只读不写的需要先把写close了;wait需要加一下，否则容易串场
			if(0 == read(prev[0], &base, sizeof(base))) {
				// printf("read == 0\n");
				close(prev[0]);
				exit(0);
			}
			// printf("read <- %d\n", base);
			printf("prime %d\n", base);

			int next[2];
			pipe(next);
			int pid = fork();
			if (pid < 0) {
				write(2, err1, strlen(err1));
				exit(1);
			}

			// parent
			if (pid > 0) {
				int cur = 0;
				for(;0 != read(prev[0], &cur, sizeof(cur));) {
					if (0 != cur % base) {
						write(next[1], &cur, sizeof(cur));
					}
				}
				close(prev[0]);
				close(next[0]);
				close(next[1]);
				wait(0);
				exit(0);
			}

			// child
			close(prev[0]);
			prev[0] = next[0];
			prev[1] = next[1];
		}
		exit(0);
	}

	// parent
	close(prev[0]);
	for (int i = 2;i <= 32;i++) {
		// printf("write -> %d\n", i);
		write(prev[1], &i, sizeof(i));
	}
	close(prev[1]);
	wait(0);

	exit(0);
}

```

#### find

1. pfilename是稍微改了ls.c的fmtfilename
2. c语言中的字符串最后末尾不上 0

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

char*
pfilename(char *path)
{
  char *p;

  // Find first character after last slash.
  for(p=path+strlen(path); p >= path && *p != '/'; p--)
    ;
  p++;

  return p;
}

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

	if ((fd = open(path, 0)) < 0) {
		fprintf(2, "find: cannot open %s\n", path);
		return -1;
	}
	if(fstat(fd, &st) < 0) {
		fprintf(2, "find: cannot stat %s\n", path);
		close(fd);
		return -1;
	}

	switch(st.type) {
		case T_FILE:
			if(0 == strcmp(pfilename(path), filename)) {
				fprintf(1, "%s\n", path);
			}
			break;
		case T_DIR:
			strcpy(buf, path);
			p = buf + strlen(buf);
			*p++='/';
			while(read(fd, &de, sizeof(de)) == sizeof(de)) {
				if(de.inum == 0) {
					continue;
				}
				if(0 == strcmp(".", de.name) || 0 == strcmp("..", de.name)) {
					continue;
				}
				memmove(p, de.name, DIRSIZ);
				p[DIRSIZ] = 0;
				if(stat(buf, &st) < 0) {
					printf("find: cannot stat %s\n", buf);
					continue;
				}

				find(buf, filename);
			}
			break;
	}
	close(fd);
	return 0;
}

int
main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(2, "not enough arguments\n");
		exit(1);
	}
	find(argv[1], argv[2]);
	exit(0);
}

```