kentaniguchi
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # ECS150 Project1 ## Summary This program, `sshell`, offers user interface to the operating system's services. This program supports some well known commands such that cd, ls, pwd and so on. This program also supports commands with up to three pipes. ## Implementation The implementation of this program follows four distinct steps: 1. Parsing the user commands given as user input. 2. Performing based on the user's commands. 3. Response 3(a). Display the return result with a completed message if user's command is correctly executed. 3(b). Display a precise error message if the entered command is not recognized by the program. 4. Repeat step1 to step3 untill a user inputs "exit" and stops the program. ## Parsing 最初にユーザーによって入力されたコマンドラインを分割し、`myobj`と名付けられた構造体に格納する処理を行う。 ## パイプラインでの区切り コマンドラインにパイプ記号(|)があるかをチェックし、パイプの総数とパイプ記号区切りになった文字列をmyobjと名付けられた構造体に保存する。このセクションはperse_by_pipe_charの関数が担っており、ユーザーによって入力されたコマンドにパイプが含まれていた場合、文字列をパイプ区切りでmyobj構造体の中にそれぞれ保存する。ここでパイプの総数も保存する。 ## コマンドごとの区切り パイプラインによって分割されたそれぞれのコマンドライン(1から4つ)の処理を行う。このセクションはparse_each_cmdの関数が担っており、まずコマンドに<または>が含まれていないかをチェックし、もし含まれていた場合は前後に1つのスペースを挿入する。この処理は次に行うスペース区切りで文字列を分割し配列に格納する処理をするためである。文字列をスペース区切りで分割したら構造体に保存する。 ## エラーチェック 先程のユーザーから入力されたコマンドの編成の途中と、終わったあとで正しいコマンドが入力されているかをチェックする機能を追加した。エラーが確認されたら、エラーに応じてユーザーに返すエラー文章をstderrにてターミナルに表示させる。これらのエラーが発生したときにはターミナルを終了するのではなく、ユーザーに新しいインプットをさせるためにsshell@UCD:を表示させる。 実装したエラーのは以下の通りである。 - [x] Error: too many process arguments - [x] Error: missing command - [x] Error: no output file - [x] Error: cannot open output file - [ ] Error: mislocated output redirection - [x] Error: no input file - [x] Error: cannot open input file - [x] Error: cannot cd into directory - [x] Error: command not found - [x] Error: no such directory - [x] Error: directory stack empty ### Error: too many process arguments ex. cd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 このエラーはargumentsが多すぎるときに表示させるエラー。先程説明したそれぞれのパイプラインからargumentsに分けて保存する際に、argumentsの数がargumentsの上限数+メインコマンドの1つを足し合わせた17個より多くなったときにこのエラーを返す。 ### Error: missing command ex. | grep hello このエラーはそれぞれのパイプラインにて、コマンドが入力されていないときに発生する。パイプラインごとにそれぞれのargumentsを確認し、1つ目がNULLであるときはパイプラインにargumentsが1つも入っていないことになる。たとえ1つ目がNULLではなくても、1つ目が<や>などのファイルIOの場合はファイルへのコマンドが存在しないことになる。 ### Error: no output file ex. echo > >が登場する同じパイプライン内で>の次のargumentがNULLである場合はアウトプットが入力されていないためこのエラーを返す ### Error: cannot open output file ex. echo hello > /etc/passwd これはアウトプットファイルは定義されているが、write権限がないために開くことが出来ないときに表示される。 ### Error: no input file `ex. cat <` output errorと同様に<の次のargumentがNULLのときはファイル名が入力されていないとしてエラーを返す。outputとは異なり、入力されたインプットファイルが存在するかを確認して、なければエラーを返す。 ### Error: cannot cd into directory ex.cd doesnotexist cdコマンドはexecvpで呼ばれるのではなく自作したビルトインコマンドで呼ばれる。ここではcdで与えられたdirectoryがない場合にdirectoryを移動せずにエラーを表示する。 ### Error: no such directory このコマンドは上のエラーと同じ意味、実装方法だが、こちらはスタックを使ったpushdのときに表示されるエラーである。 ### Error: command not found ex. windows98 system()関数とwhichコマンドを利用することで実行しているOSに実行しようとしているコマンドファイルが存在するかどうかを確認し、存在しないときにこのエラーを表示する。 ### Error: directory stack empty ex. popd (when thers's no element in the stack) dirs/pushdによって作成されたパスのスタックが空のときにpopdを行うときに、popする要素がないためこのエラーが表示される。 ### Error: mislocated output redirection このエラーは実装できなかった。 ## ビルトインコマンド 実装したビルトインコマンドは以下の5つである。これらはexecvpを通して実行する必要がないためforkを使う前に実行し、完了したらユーザーに次のインプットを聞く。 - exit - cd - pwd - dirs - pushd - popd ### exit exitが入力されたときにはstderrとしてbyeと表示し、listenを中止する。 ### cd chardir()を使ってcdで与えられたdirectoryに遷移する。 ### pwd 現在のパスを取得し、ターミナルに表示する。 ### dirs dirs/pushd/popdはdirectoryの遷移をスタックで管理する。スタックを定義するときに、現在のdirectoryのパスを追加しておく。dirsコマンドでスタックの中に保存されているdirectoriesをターミナルに表示する。 ### pushd cdと実装は同じだが、問題なく遷移できたときに遷移前のパスをスタックに追加し、スタックサイズを1つ増やす。 ### popd 最後に追加したパスを取得し、そのパスに遷移する。スタックのサイズを1つ減らす。スタックサイズが0の場合は、エラーを返す。 ## ビルトインコマンド以外の実装 コマンドはパイプラインの数だけ再帰を行う。まずメインのプロセスからforkして、パイプを作り、更にforkします。親プロセスはstdinをパイプに繋いで右端(右から0番目)のコマンドの実行、子はstdoutをパイプに繋いで更にパイプを作ってforkして、今度は親になった先程の子が右端から1番目のコマンドを実行、子はまたforkしてパイプを作り……と繰り返していって、左端のコマンドに達したら実行する。 再帰を利用することで子のexit時に複数のreturn valueを親に返すことができなくなってしまった。更にforkされた親と子ではアドレスが同じでも環境をまるごとコピーしているため、子の中での変更は親には影響されない。親や子でもreturn valueをグローバルvariableのように利用したかったため、mmap() を利用して、return valuesを格納する配列を作成した。これによって親や子や孫でも共有され最終的にそれぞれのプロセスで実行されたコマンドのreturn valuesを取得し、すべてのコマンドが実行されたあとで表示することが出来た。 更に、それぞれのコマンドを実行する前に、インプットやアウトプット記号があるかを確認し、あればファイルをdup2()を用いてファイルのインプット元、アウトプット先をstdout,stdinに変更する。そして、インプットやアウトプット記号を消去することでそれ以降のコマンドがファイルを通して実行されることになる。 # ECS150 Project1 ## Project Members - Daisuke Horiuchi (919535721) - Ken Taniguchi (919537457) ## Summary This program, `sshell`, offers user interface to the operating system's services. This program supports some well known commands such that cd, ls, pwd and so on. This program also supports commands with up to three pipes. ## Implementation The implementation of this program follows four distinct steps: 1. Parsing the user commands given as user input. 2. Performing based on the user's commands. 3. Response: 3(a). Display the return result with a completed message, if user's command is correctly executed. 3(b). Display a precise error message if the entered command is not recognized by the program. 4. Repeat step1 to step3 until a user inputs "exit" and stops the program. ## Parsing Split the command line arguments entered by the user and store it in a structure named `myobj`. ### Parsing by Pipelines Check if the command line has a pipe symbol (|) and the total number of pipes and the pipe symbol delimited string are stored in a structure named myobj. This section is handled by the function named `perse_by_pipe_char`, which saves each pipe-symbol-delimited string in the structure. We also store the total number of pipes to the structure here. ### Parsing by space characters The entire user's command line was divided into one to four string(s) by the function named `perse_by_pipe_char`. Now we need to parse those strings by space characters. This section is handled by the function named `parse_each_cmd`, which first checks to see if the strings contain '<' or '>', and if so inserts a single space before and after it. This process is for the next process of dividing the strings by space characters and storing those divided strings in an array. After parsing the string with space characters, save it in a structure. ## Error checking Added functions to check whether the correct command is entered during and after the command input from the user. When an error is confirmed, display the error message to the user using `stderr`. Instead of exiting the terminal when these errors occur, print `sshell@UCD:` to prompt the user for new input. The error messages we implemented is following: - [x] Error: too many process arguments - [x] Error: missing command - [x] Error: no output file - [x] Error: cannot open output file - [ ] Error: mislocated output redirection - [x] Error: no input file - [x] Error: cannot open input file - [x] Error: cannot cd into directory - [x] Error: command not found - [x] Error: no such directory - [x] Error: directory stack empty ### Error: too many process arguments `ex. cd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16` This error is displayed when there are too many arguments. When dividing and saving arguments from each pipeline explained earlier, this error is returned when the number of arguments exceeds 16. ### Error: missing command `ex. | grep hello` This error occurs when no commands have been entered in each pipeline. Check each argument for each pipeline, and if the first is `NULL`, the pipeline does not contain any arguments. Even if the first is not `NULL`, if the first is a file Input/Output/Redirection such as '<' or '>', there will be no command to the file. ### Error: no output file `ex. echo >` In the same pipeline where '>' appears, if the next argument of '>' is `NULL`, this error is returned because the output has not been input. ### Error: cannot open output file `ex. echo hello > /etc/passwd` This is displayed when an output file is defined but cannot be opened due to lack of write permission. ### Error: no input file `ex.cat<` Similar to output error, if the argument next to '<' is `NULL`, an error will be returned as no file name has been entered. Unlike output, it checks if the input file exists and returns an error if it doesn't. ### Error: cannot cd into directory `ex.cd doesnotexist` The `cd` command is not called by `execvp` but by a self-made built-in command. Here, if there is no directory given by `cd`, an error is displayed without moving the directory. ### Error: no such directory This command has the same meaning and implementation method as the above error, but this is the error displayed when pushing with the stack. ### Error: command not found `ex. windows98` By using the `system()` function and the `which` command, it checks whether the command file to be executed exists in the OS, and displays this error if the file does not exist. ### Error: directory stack empty `ex. popd (when there's no element in the stack)` If a user inputs `popd` when the stack of paths created by dirs/pushd is empty, the user gets this error because there is no elements to pop. ### Error: mislocated output redirection This error could not be implemented. ## Built-in commands The implemented built-in commands are the following five. These don't need to be run through `execvp` so they are executed before using fork and ask the user for further input after the process is done. - exit - cd - pwd - dirs - pushd - popd ### exit When exit is typed, print "bye..." as stderr and stop listening user inputs. ### cd Using `chardir()` to transition to the directory given by cd. ### pwd Get the current path and display it in the terminal. ### dirs dirs/pushd/popd manage directory transitions in the stack. Display the directories saved in the stack with the dirs command on the terminal. Also the dirs always shows the current path. ### pushd The implementation is the same as `cd`, but when the transition is successful, the path before transition is added to the stack and the stack size is increased by one. ### popd Get the last added path and make a transition to that path. Reduce the stack size by one. If the stack size is 0, return an error. ## Implementations for the other than built-in commands The program is called recursively as many times as there are pipelines. First fork from the main process, create a pipe, and fork again. The parent process connects stdin to the pipe and after the wait of the child process, executes the rightmost command. The child connects stdout to the pipe, creates another pipe and forks, and this time the child who became the parent starts executing from the second command from the rightmost, fork the child again to create a pipe. Repeating this process until the leftmost command is reached and executed. With recursion, it becomes impossible to return multiple return values ​​to the parent when the child exited. Since fork copies the entire environment, the forked parent and child have exactly the same address. However, changes in the child are not affected to the parent because the forked parent and child have different physical memories (They have the same virtual memories). We wanted to store the return value into like a global variable in the parent and child, so we used `mmap()` to create an array that stores the return values from the forked parent, child, and grandchildren and so on. This made it possible to keep storing the return values ​​of commands after all commands were executed. Furthermore, before executing each command, check if there is an input or output symbol. If so, use `dup2()` to change the input source and output destination of the file to stdout and stdin. Then, by deleting the arguments after the input or output symbols, subsequent commands, which do not have file redirection arguments, will be executed through the file.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully