{"id":23300587,"url":"https://github.com/varun0157/seashell","last_synced_at":"2026-05-03T21:32:43.091Z","repository":{"id":216037064,"uuid":"740154376","full_name":"Varun0157/SeaShell","owner":"Varun0157","description":"A custom linux shell written in C for Mini Project 1 of the Operating Systems and Networks course in IIIT-H (Monsoon '23). Score: 94/94. ","archived":false,"fork":false,"pushed_at":"2024-01-07T18:50:09.000Z","size":91,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-31T14:57:19.283Z","etag":null,"topics":["cli","networks","operating-system","shell"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Varun0157.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-07T17:25:16.000Z","updated_at":"2024-09-12T04:58:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"26a143ca-daaa-47b4-8672-7adc898e0ece","html_url":"https://github.com/Varun0157/SeaShell","commit_stats":null,"previous_names":["varun0157/seashell"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Varun0157/SeaShell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Varun0157%2FSeaShell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Varun0157%2FSeaShell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Varun0157%2FSeaShell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Varun0157%2FSeaShell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Varun0157","download_url":"https://codeload.github.com/Varun0157/SeaShell/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Varun0157%2FSeaShell/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32586187,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","networks","operating-system","shell"],"created_at":"2024-12-20T09:17:04.947Z","updated_at":"2026-05-03T21:32:42.716Z","avatar_url":"https://github.com/Varun0157.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Using the Shell\n1. Create the executable by entering the following command in your terminal\n```bash\nmake\n```\n2. Execute the shell\n```bash\n./a.out\n```\n- You may clean the executable and temporary files, using:\n```bash\nmake clean\n```\n___\n___\n# Contents\n* ### [The Unique Factor](https://github.com/Varun0157/SeaShell#the-unique-factor-1)\n* ### [Features](https://github.com/Varun0157/SeaShell#features-1)\n#### [exit](https://github.com/Varun0157/SeaShell#exit) | [neonate](https://github.com/Varun0157/SeaShell#signals) | [signals](https://github.com/Varun0157/SeaShell#signals) |  [fg and bg](https://github.com/Varun0157/SeaShell#fg-and-bg) | [iMan](https://github.com/Varun0157/SeaShell#iman) | [Multi-Command Structures](https://github.com/Varun0157/SeaShell#multi-command-structures) | [I/O Redirection](https://github.com/Varun0157/SeaShell#io-redirection) | [Piping](https://github.com/Varun0157/SeaShell#piping) | [activities](https://github.com/Varun0157/SeaShell#activities) |[warp](https://github.com/Varun0157/SeaShell#warp) | [peek](https://github.com/Varun0157/SeaShell#peek) | [pastevents](https://github.com/Varun0157/SeaShell#pastevents) | [System Commands](https://github.com/Varun0157/SeaShell#system-commands) | [proclore](https://github.com/Varun0157/SeaShell#proclore) | [seek](https://github.com/Varun0157/SeaShell#seek)\n* ### [Improvements on Requirements](https://github.com/Varun0157/SeaShell#improvements-on-requirements-1)\n* ### [Assumptions](https://github.com/Varun0157/SeaShell#assumptions-1)\n* ### [Limitations](https://github.com/Varun0157/SeaShell#limitations-1)\n___\n___\n# The Unique Factor\n- All commands are stored in a cleanly formatted, equivalent manner, performing similar pre-processing as bash for commands. Thus, any value within strings, has its strings omitted and is re-embedded into the string to be treated on it's own. \n- All commands are stored in the format:\n\n    `command args \"\u003c inputRedir\" \"\u003e outputRedir\" | ...`\n    \n    Thus, even if different commands have the same action with respect to redirection, they are stored equivalently. \n    So: `echo   \"hello\" \u003e   a.txt` and `echo\u003ea.txt hello` are stored as one and the same in pastevents. \nBoth of the above points were an attempt to solve a question in the doubts document, which we were told not to solve due to the implementational burden. But, I thought it would improve my shell so I went ahead and did it. \n\nRead more improvements on requirements [here](https://github.com/Varun0157/SeaShell#improvements-on-requirements-1). \n___\n___\n# Features\nThe Shell prompt displays the username, the hostname, the current directory relative to the executable, as well as the time taken by the last command to execute, it it took more than 2 seconds.\nIf there is a background process that has not explcitly exited yet, a * is shown at the beginning of this prompt, similar to the starship shell. \n___\n### Neonate\nHas one optional `-n` flag that must be followed by an integer representing time in seconds. If no time is specified, it is taken as 1 second by default. \n\nThe command prints the process-id of the most recently created process on the system every `time-arg` seconds until the key `x` or `X` is pressed. \n\nThe terminal enters raw mode on execution of the command to allow this. \n- `neonate`\nprints the most recently created process on the system every 1 second. \n- `neonate -n \u003ctime_arg\u003e`\nprints the most recently created process on the system every \u003ctime_arg\u003e seconds. This must be a non-negative integer. \n___\n### Signals\n- ping\nUsing the `ping` command allows us to send particular signals to processes. \n```bash\nping \u003cpid\u003e \u003csignal_number\u003e\n```\nSends the signal `signal_number` (%32) to the process `pid`. \n\nAdditionally, the following signals have been overriden:\n- `Ctrl+C` - interrupts any currently running foreground process by sending it the SIGINT signal. It has no such effect if no foreground process is currently running. In this case, it simply re-prompts with the same session as before (i.e., without handling background processes). \n- `Ctrl+D` - Logs out of the shell (after killing all processes) while having no effect on the actual terminal that the custom shell is running on. Stored as \"exit\" in pastevents. It only has effect while taking input.\n- `Ctrl+Z` - Pushes the running foreground process to the background and changes its state to \"Stopped\". It has no such effect on the shell if no foreground process is running. In this case, it simply re-prompts with the same session as before (i.e., without handling background processes). \n\n#### Note\n- On receiving input, `Ctrl+C` and `Ctrl+D` prompt a new input, partially mimicing the behaviour of bash. \n- `ping 0 9` will kill the shell and this is not unexpected\n___\n### fg and bg\n- `fg \u003cpid\u003e`\nbrings the background process with corresponding pid to foreground, handing it control of terminal. Consequently, it will have no real effect if called on a foreground process. \n- `bg \u003cpid\u003e`\nchanges the state of a background process to running (in the background). Consequently, has no real effect if called on a foreground process. \n___\n### iMan\nWe use sockets to run GET requests to `man.he.net` and retrieve information about any command, using `iMan \u003ccommand_name\u003e`. \n\nAtleast the Name, Synopsis and Description will be printed, if present. \n- `iMan \u003ccommand_name\u003e`\ndoes the following:\n1. DNS resolution for man.he.net\n2. opens a TCP socket to the IP address\n3. Sends a GET request to the website's server\n4. Reads the body of the website\n5. Closes the socket\n___\n### Multi-Command Structures\nWe can send multiple commands to the shell using `\u0026` and `;` delimiters. Any command that is succeeded by a `\u0026` is to be run as a background process.\n```bash\ncommand1 ; command2 \u0026 command3\n``` \nIn the above, `command1` runs in the foreground, followed by `command2` in the background and finally `command3` in the foreground. \n\n#### Note the following:\n- An error is printed in case of erroneous processes. \n- When the command is stored, it is not necessarily stored as it was typed. An equivalent version of the command with cleaner and uniform formatting is stored, to allow for easier comparison with other commands. The command stored is in the form that execvp executes the command, i.e., it attempts to perform the same pre-processing as bash. \n___\n### I/O Redirection\nInput-Output redirection is supported, similar to bash. \n- `\u003e` Writes to the filename specified as output\n- `\u003e\u003e` Appends the file specified as output\n- `\u003c` Reads from the file specified as input\n\nThese can also be executed in the background similar to system calls. They work for both custom commands and bash commands executed using `execvp`.\n___\n### Piping\nPiping is supported, similar to bash. I/O redirection can also be performed within a pipeline. \n\nThis works for all commands, both custom commands and system commands executed using `execvp`.\n\n#### Note\n- If a pipeline is terminated by an ampersand (\u0026), the last command in the pipeline is executed in the background. \n- Continous pipes are somewhat undefined in bash. If the continous pipes are separated by a space, bash throws an error. \n    - To improve on this functionality, we execute continuous pipes if they are separated by a space, treating this space as a 'void' that executes nothing. This can allow us to add commands that are not dependent on previous stages of the pipeline, to it. \n- Piping mimics bash in error handling. If an error is thrown in the middle of a pipeline, the pipeline continues executing after printing the error message. \n___\n### activities\nPrints the list of all processes currently running that were spawned by the shell, in lexicographic order of pid. \nOn calling `activities` we see the list of background processes spawned by our shell, as follows:\n```bash\npid_1:  name_1  state_1\n...\npid_n:  name_2  state_2  \n\n```\n___\n### Warp\nIs our shell's equivalent to cd in bash. It allows to change directories to any directory given as a parameter. Any relative paths are assumed to be relative to the directory containing the executable of the shell. \n```bash\nwarp \u003cpath/name\u003e \u003cpath/name\u003e ...\n```\nThus, \n- `~` or `~/path` is a path relative to the home directory\n- `-` takes us to the previous working directory\n- Any other argument is passed directly to chdir. Thus, if we type `newDir` as an argument it will attempt to cd to `newDir` in the current working directory, and if we type `/` it will take us to the root. \n\n#### Advantages over cd:\n- Multiple inputs allowed\n#### Disadvantages with respect to cd:\n- Cannot directly navigate to a directory with spaces in its name\n___\n### Peek\nis our shell's equivalent to the ls command in bash. it supports the same flags as bash, i.e.:\n- `-l` displays all extra information\n- `-a` displays all files, including hidden files\n\nIt is called as follows:\n```bash\npeek \u003cflags\u003e \u003cpath/name\u003e\n```\nAny permutation of l and a is supported as a flag. \nThe flags are optional. If no path/name is provided however, we peek the current working directory. \n\n#### Note:\n- Stat displays number of blocks in the units of 512 bytes, and this is what is displayed in peek. This may not be the same as ls in all systems. Often, it is double the block size as other systems. \n- We display executables in green, directories in blue, and all other items are considered files, displayed in white. \n___\n### Pastevents\nIs similar to the history in actual shells. We store upto 15 of the most recent executed commands, across sessions.  \n```bash\npastevents\n```\nThe above command displays the past commands, from least recent to most recent, if any. \n```bash\npastevents execute \u003cindex\u003e\n```\nThe above command executes the command at the 1-indexed position `index`, if one is present. This command executes as a standalone, meaning if it is used to redirect to some file, then the output of all the commands will be send to that file. \n\n```bash\npastevents purge\n```\nDeletes the stored history\n\n###### Note:\n- The pastevents command stores an equivalent version of the entered command, and not the command itself, to ensure easy comparison with past and future commands that perform the same purpose. A closing `;` is intentionally not stored, if present, to make sense of pastevents redirecting to files in commands. Consequently, a closing `;` must be explicitly added to denote it as a single command, if required. \n- `pastevents execute \u003cindex\u003e` is considered a separate command entity, i.e., on redirection, if the command in pastevents is composed of multiple commands, then they will all output and input from the redirection as a whole. It gets replaced with the command that is executed by it, in the final display.Any command shown on entering `pastevents` can be executed as part of a multi-command input or an individual input. \n- The history is stored as a hidden file in the same directory as the executable, under the name `._PAST_EVENTS_.txt`. The purpose of the obscure wording is to prevent potential clashes. Modifications to this file will lead to improper working of the pastevents command. \n    - This file can be deleted if the user wishes, but it will be regenerated on re-execution of the shell. \n- Complex string input with double quotes is allowed and accounted for, similar to bash. \n    - `echo \"random word \u003e a.txt\"` is valid and echoes `random word \u003e a.txt` without any redirection, as is `echo \"random word\" | wc | echo \"random word | wc\"`, and it will give the same output as bash. \n    - Even regular system commands work similar to bash. echo random\"word\" prints randomword, same as bash. \n___\n### System Commands\nMost valid system commands in bash can be executed succesfully in this terminal. We just enter the command as usual to execute it. \n- Any command that is succeeded by a `\u0026`, whether as a part of the final argument or as an individual argument, will be executed in the background. \n- Else, it will execute in the foreground. \n- Background execution is not currently allowed for custom commands (warp, peek, seek etc).\n- All arguments are passed directly to execvp(), so things such as paths work as it would in a normal terminal and not necessarily relative to our shell. \n___\n### Proclore\nis used to obtain information regarding any process. \n```bash\nproclore \u003cpid\u003e \u003cpid\u003e ...\n```\nIf no pid is provided, we print the information of our shell. \nWe print the following details:\n- `pid` the id of the process\n- `Process Status` as read from /proc/\u003cpid\u003e/status, including a `+` if it is a foreground process. \n- `Process Group` The process group number of the process\n- `Virtual Memory` The amount of virtual memory used by the process, in kilo-bytes\n- `Executable Path` The path to the executable of the process, if accessible, relative to the shell executable. \n\n___\n### Seek\nThis command looks for a file or directory in the specified target directory. \n```bash\nseek \u003cflags\u003e \u003csearch\u003e \u003ctarget_directory\u003e\n```\nThe search item is the only mandatory component. \nValid flags include:\n-  `-e` - If there is more than one, or less than one match, then this flag is completely ineffective, and does nothing. However, if there is exactly one match, if it is a directory, then we change the current working directory to it, and if it is a file, then we print its contents. \n- `-f` - Only look for files\n- `-d` - Only look for directories\nNote that the `-d` and `-f` flags are ineffective together. \n\n#### Note\n- Any item that passes `S_ISDIR(mode)` where `mode` is the mode of the item, is considered a directory, while anything that passes `S_ISREG(mode)` where `mode` is the mode of the item, is considered a file. \n- Files are coloured in green in the results while directories are blue. \n- Other file types, including devices, pipes, sym-links, sockets, etc. are not considered in seek. \n___\n### exit\nWe can use the command exit with any arguments to provde a clean exit to the shell. Using this command ensures that:\n- Any background processes started by the shell are killed\n- All memory dynamically allocated is freed. \n\n```bash\nexit\n```\nCtrl+D also provides a clean exit. \n___\n___\n# Improvements on Requirements\n- Complex string input with double quotes is allowed and accounted for, similar to bash. \n    - `echo \"random word \u003e a.txt\"` is valid and echoes `random word \u003e a.txt` without any redirection, as is `echo \"random word\" | wc | echo \"random word | wc\"`, and it will give the same output as bash. \n    - Even regular system commands work similar to bash. echo random\"word\" prints randomword, same as bash. \n    - Please read [this](https://github.com/Varun0157/SeaShell#the-unique-factor-1)\n- pastevents stores a uniformly formatted equivalent version of the passed command. This allows for various improvements. For example `sleep    \"5\"` is treated equivalent to `sleep 5`. \n- warp and seek change the working directory even in the middle of commands. Consequently, commands like `seek -e -d newfolder ./doe ; peek -al ;` would peek the new directory entered by seek, if any. \n- Large multi-command calls can be executed by `pastevents execute \u003cindex\u003e`. This acts as a standalone function, meaning redirects lead to the output of all the commands in this call being redirected, and same for input. \n- System commands are allowed to take input and provide output without breaking both parent and child processes, using signals. \n- exit command\n- If a pipeline is terminated by an ampersand (\u0026), the last command in the pipeline is executed in the background. \n- Multiple PIDs can be passed as input in proclore. \n- Any types of flags allowed in peek, seek etc. We can enter any permutation of valid flags, and get verbose errors in case of disallowed ones. You can pass -allaalll as a valid flag in peek. \n- Continous pipes are somewhat undefined in bash. If the continous pipes are separated by a space, bash throws an error. \n    - To improve on this functionality, we execute continuous pipes if they are separated by a space, treating this space as a 'void' that executes nothing. This can allow us to add commands that are not dependent on previous stages of the pipeline, to it.  \n___\n___\n\n# Assumptions \n- Only double quote structures are supported for relevant commands. Eg: echo \"random    word\" will print as expected from the bash terminal, but 'random    word' may not.  \n- Redirection of files when used with relative paths is not relative to the shell executable. ~ will act as the home directory of the shell only for seek, peek and warp. \n- Operating on special files (eg: `sort \u003c /dev/zero`) can lead to undefined behaviour. \n- We need write permissions\n___\n___\n# Limitations\n- Tokenising the input always leads to limitations. Eg: we cannot directly navigate to a file that has spaces in it's name because our shell will assume that two arguments were passed to navigate to. Also, it leads to improper echo outputs when echo contains a strict string which has delimiters within it. \n- Custom commands do not support background execution, and the character \u0026 is intentionally treated purely as \u0026 and not as a special character denoting background execution for them. \n___\n___\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvarun0157%2Fseashell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvarun0157%2Fseashell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvarun0157%2Fseashell/lists"}