diff options
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | user/find.c | 84 | ||||
| -rw-r--r-- | user/pingpong.c | 44 | ||||
| -rw-r--r-- | user/primes.c | 74 | ||||
| -rw-r--r-- | user/sh.c | 3 | ||||
| -rw-r--r-- | user/sleep.c | 22 | ||||
| -rw-r--r-- | user/xargs.c | 60 | 
7 files changed, 292 insertions, 0 deletions
| @@ -188,6 +188,11 @@ UPROGS=\  	$U/_grind\  	$U/_wc\  	$U/_zombie\ +	$U/_sleep\ +	$U/_pingpong\ +	$U/_primes\ +	$U/_find\ +	$U/_xargs\ diff --git a/user/find.c b/user/find.c new file mode 100644 index 0000000..e185e9d --- /dev/null +++ b/user/find.c @@ -0,0 +1,84 @@ +#include "kernel/types.h" + +#include "kernel/fcntl.h" +#include "kernel/fs.h" +#include "kernel/stat.h" +#include "user/user.h" + +char* +fmtname(char* path) +{ +  char* p; + +  // Find first character after last slash. +  for (p = path + strlen(path); p >= path && *p != '/'; p--) +    ; +  p++; +  return p; +} + +void +find(char* root_path, char* filename) +{ +  static char buf[512]; +  char* p; +  int fd; +  struct dirent de; +  struct stat st; + +  if ((fd = open(root_path, O_RDONLY)) < 0) { +    fprintf(2, "find: cannot open %s\n", root_path); +    return; +  } +  if (fstat(fd, &st) < 0) { +    fprintf(2, "find: cannot stat %s\n", root_path); +    close(fd); +    return; +  } + +  switch (st.type) { +    case T_FILE: +      if (!strcmp(fmtname(root_path), filename)) { +        printf("%s\n", root_path); +      } +      break; +    case T_DIR: +      if (strlen(root_path) + 1 + DIRSIZ + 1 > sizeof(buf)) { +        printf("find: path too long\n"); +        break; +      } + +      strcpy(buf, root_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'; + +        // printf("i'm finding %s!\n", fmtname(buf)); + +        if (!strcmp(fmtname(buf), ".") || !strcmp(fmtname(buf), "..")) { +          continue; +        } + +        find(buf, filename); +      } +  } +  close(fd); +} + +int +main(int argc, char* argv[]) +{ +  if (argc < 3) { +    fprintf(2, "usage: find [root_path] filename...\n"); +    exit(1); +  } + +  for (int i = 2; i < argc; i++) { +    find(argv[1], argv[i]); +  } +} diff --git a/user/pingpong.c b/user/pingpong.c new file mode 100644 index 0000000..7b03a76 --- /dev/null +++ b/user/pingpong.c @@ -0,0 +1,44 @@ +#include "kernel/types.h" +#include "user/user.h" + +int +main(int argc, char* argv[]) +{ +  int p[2]; + +  if (argc > 1) { +    fprintf(2, "usage: pingpong\n"); +    exit(1); +  } + +  pipe(p); + +  int pid = fork(); + +  if (pid == 0) { +    short n; +    read(p[0], &n, sizeof(n)); +    if (n == 42) { +      fprintf(1, "%d: received ping\n", getpid()); +    } +    n++; +    write(p[1], &n, sizeof(n)); +    close(p[0]); +    close(p[1]); +    exit(0); +  } + +  short n = 42; + +  write(p[1], &n, sizeof(n)); +  read(p[0], &n, sizeof(n)); +  if (n == 43) { +    fprintf(1, "%d: received pong\n", getpid()); +  } +  close(p[0]); +  close(p[1]); + +  wait(0); + +  exit(0); +} diff --git a/user/primes.c b/user/primes.c new file mode 100644 index 0000000..b359524 --- /dev/null +++ b/user/primes.c @@ -0,0 +1,74 @@ +#include "kernel/types.h" +#include "user/user.h" + +#define MAX 36 +#define FIRST_PRIME 2 + +int +generate_natural(); // -> out_fd +int +prime_filter(int in_fd, int prime); // -> out_fd + +int +main(int argc, char* argv[]) +{ +  int prime; + +  int in = generate_natural(); +  while (read(in, &prime, sizeof(int))) { +    // printf("prime %d: in_fd: %d\n", prime, in);  // debug +    printf("prime %d\n", prime); +    in = prime_filter(in, prime); +  } + +  close(in); + +  exit(0); +} + +int +generate_natural() +{ +  int out_pipe[2]; + +  pipe(out_pipe); + +  if (!fork()) { +    for (int i = FIRST_PRIME; i < MAX; i++) { +      write(out_pipe[1], &i, sizeof(int)); +    } +    close(out_pipe[1]); + +    exit(0); +  } + +  close(out_pipe[1]); + +  return out_pipe[0]; +} + +int +prime_filter(int in_fd, int prime) +{ +  int num; +  int out_pipe[2]; + +  pipe(out_pipe); + +  if (!fork()) { +    while (read(in_fd, &num, sizeof(int))) { +      if (num % prime) { +        write(out_pipe[1], &num, sizeof(int)); +      } +    } +    close(in_fd); +    close(out_pipe[1]); + +    exit(0); +  } + +  close(in_fd); +  close(out_pipe[1]); + +  return out_pipe[0]; +} @@ -165,6 +165,9 @@ main(void)          fprintf(2, "cannot cd %s\n", buf+3);        continue;      } +    if(buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't'){ +      exit(0); +    }      if(fork1() == 0)        runcmd(parsecmd(buf));      wait(0); diff --git a/user/sleep.c b/user/sleep.c new file mode 100644 index 0000000..961f558 --- /dev/null +++ b/user/sleep.c @@ -0,0 +1,22 @@ +#include "kernel/types.h" +#include "user/user.h" + +int +main(int argc, char* argv[]) +{ +  uint sec = 0; + +  if (argc <= 1) { +    fprintf(2, "usage: sleep [time (ticks)]\n"); +    exit(1); +  } +  sec = atoi(argv[1]); + +  sleep(sec); + +  if (argc <= 2) { +    exit(0); +  } + +  exit(0); +} diff --git a/user/xargs.c b/user/xargs.c new file mode 100644 index 0000000..b5b9bee --- /dev/null +++ b/user/xargs.c @@ -0,0 +1,60 @@ +#include "kernel/types.h" + +#include "kernel/param.h" +#include "kernel/stat.h" +#include "user/user.h" + +#define is_blank(chr) (chr == ' ' || chr == '\t') + +int +main(int argc, char* argv[]) +{ +  char buf[2048], ch; +  char* p = buf; +  char* v[MAXARG]; +  int c; +  int blanks = 0; +  int offset = 0; + +  if (argc <= 1) { +    fprintf(2, "usage: xargs <command> [argv...]\n"); +    exit(1); +  } + +  for (c = 1; c < argc; c++) { +    v[c - 1] = argv[c]; +  } +  --c; + +  while (read(0, &ch, 1) > 0) { +    if (is_blank(ch)) { +      blanks++; +      continue; +    } + +    if (blanks) { +      buf[offset++] = 0; + +      v[c++] = p; +      p = buf + offset; + +      blanks = 0; +    } + +    if (ch != '\n') { +      buf[offset++] = ch; +    } else { +      v[c++] = p; +      p = buf + offset; + +      if (!fork()) { +        exit(exec(v[0], v)); +      } +      wait(0); + +      c = argc - 1; +    } +  } + +  exit(0); +} | 
