📂
build a OS
  • Learn OS with me
  • OS Interfaces
    • OS interfaces
    • I/O and File descriptors
    • Process and Memory
    • Pipes
    • File
  • OS Organization
    • OS Organization
    • Challenge yourself
  • Memory Management
    • XV6 Virtual Memory
    • Page Table
      • Part 1: How to translate address
      • Part 2: Create an Address Space
      • Part 3: How Page Table is used
      • Part 4: Page Fault and Swap
      • Part 5: How to operate on page tables
    • xv6 buddy allocator
      • How to display physical memory
    • Memory Management Walk Through
  • Traps and Interrupts
    • Trap Home Page
      • 系统调用的核心原理
    • What is trapframe
    • What is trampoline
    • Traps from kernel space
    • How fork() works
    • How system calls get into/out of the kernel
    • How exec() works
  • Scheduling
    • XV6 CPU Scheduling
    • How unix pipes work?
    • How does wait(), exit(), kill() work?
  • File System
    • Overview and Disk Layout
    • Buffer Cache
    • Design Inode Layer
    • Inode Content
    • Block Allocator
    • Design a log system for crash recovery
    • Directory Layer
    • Path names
    • File Descriptor Layer
    • FS System Calls
    • XV6 VS Real World
    • Make Xv6 File disk management system
    • Write FS simulator in python
    • How Redirect Shell command works
  • Concurrency
    • Spinlock
    • How linux select work
    • Hardware Support Locking
    • Exercise: Implement atomic counter
    • Locking in Xv6
    • Concurrency in Xv6
    • Exercise: Socket Programming with Event loop
  • Labs
    • Lab 1 Xv6 and Unix utilities
    • Lab 2 Shell
    • Lab 3 Buddy Allocator
    • Lab 4 Lazy
    • Lab 5 Copy-on-Write Fork for xv6
    • Lab 6 RISC-V assembly
    • Lab 6 Uthread: switching between threads
    • Lab 6 Alarm
    • Lab 7 Lock
    • Lab 8 File System: Large Files
    • Lab 8 File System: Symbolic links
    • Lab 9 mmap
    • Lab 10 Networking Part 1
    • Lab 10 Networking Part 2
  • Hardware, Device, Assembly
    • RISC-V assembly
    • Assembly: Access and Store information in Memory
    • Start xv6 and the first process
    • Why first user process loads another program?
    • What does kernel.ld do in XV6?
    • XV6 Device Driver
Powered by GitBook
On this page
  • Shell Parsing
  • Shell Running Command
  • How on earth is file descriptor? Is it some secrets that OS didn't tell us?
  • Summary

Was this helpful?

  1. File System

How Redirect Shell command works

echo hi > result.txt Write ‘hi’ to result.txt file.

cat < words.txt Cat program reads from words.txt file.

That’s the part we all know.

How it works internally in OS?

Shell Parsing

Parsing logic must identify a redirect command, and treats them differently than normal commands, pipe, etc.

If we have ‘<‘, it is reading the file on right side, feed to the program running on left side.

We create a COMMAND struct with:

1. fd = 0

2. mode is O_RDONLY.

3. command type is redirect

Same thing for ‘>’, which is for writing what we output in left, to a file on the right.

We create a COMMAND struct with:

1. fd = 1

2. mode is O_WRONLY|O_CREATE.

3. command type is redirect

Shell Running Command

case REDIR:
  rc = (struct redircmd *) cmd;
  close(rc->fd);
  if(open(rc->file, rc->mode) < 0){
     fprintf(2, “open %s failed\n”, rc->file);
     exit(1);
  }
  runcmd(rc->cmd);
  1. Close the corresponding file descriptor.

  2. Open file with the set mode, specified file name. The file will use the fd we just closed.

  3. Run the Command, which is the one on the left side. Ex: 'echo hi' or 'cat'.

    Note:

    Case fd == 0:

    Open cmd opens file with fd 0, which is standard input. Thus, when cat needs to read from standard input, it read from the file linked to fd, which is our file.

    Case fd = = 1:

    Open cmd opens file with fd 1, which is standard output. Thus, when echo hi wants to write to standard output, it writes to the file (result.txt) we specified.

How on earth is file descriptor? Is it some secrets that OS didn't tell us?

Concepts

  1. In OS, most resources are represented as files, including deivces, pipes, and real files. This is provided by the file descriptor layer.

  2. Each process has its own table of open files, or file descriptors.

  3. Each open file is defined below

struct file {
    enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type;
    int ref;*// reference count*
    char readable;
    char writable;
    struct pipe *pipe;*// FD_PIPE*
    struct inode *ip;*// FD_INODE and FD_DEVICE*
    uint off;*// FD_INODE and FD_DEVICE*
    short major;*// FD_DEVICE*
    short minor;*// FD_DEVICE*
};

How System Call Open works?

Each call to open creates a new open file.

Since each CPU process has its list of open files, it will add the recently open file to its table, and return the index position of the file to user program.

That’s why we see a fd integer in our user program after calling open

Internally, fd in OS is linked to a file struct, indicating which file, permission, offset, and in memory node info (inode), reference count, file type.

Summary

echo hi > result.txt Create a file called ‘result.txt’ with fd is 1 (standard output). echo always writes its content to standard output (fd 1), now redirects and writes to the file.

cat < words.txt Open a file named ‘words.txt’ with fd is 0 (standard input). cat always read from standard input, now redirects and read from the file.

PreviousWrite FS simulator in pythonNextSpinlock

Last updated 5 years ago

Was this helpful?

I/O and File descriptors