Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle shell built-in commands #47

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

Itai-Nelken
Copy link
Collaborator

@Itai-Nelken Itai-Nelken commented Dec 31, 2021

This handles built-in shell commands.
this is done by using 2 arrays:

  1. unhandled_shell_builtins: A string array containing the names of built-in commands that don't work through DollarSkip (cd for example).
  2. handled_shell_builtins: An array for Wrapper (struct wrapper) that holds commands we wrapped so they work through DollarSkip.

To show how the handled shell built-ins work I added an "easter egg" command (e_egg). I thought about doing pwd, but I don't want to rewrite the bash version.

Closes #46

Signed-off-by: Itai-Nelken [email protected]

dollarskip.c Outdated Show resolved Hide resolved
Comment on lines +12 to +15
int easter_egg() {
printf("You found the DollarSkip easter egg!\n");
return 0;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I skipped past this part, i think this is pretty pointless, fun but pointless and dollarskip is made to merely pass the commands through, not be an actual application.

It should be a possibility that we remove this.

Copy link
Collaborator Author

@Itai-Nelken Itai-Nelken Dec 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with removing it. I added it just as an example of how to override shell commands that are important enough to implement ourselves.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also rename it to dollarskip and make it print about and version info. If that's what we do, I'll remove the overriding shell commands as we can check for arguments in main(). That will also improve speed as we remove one loop.
A faster way to do this would be with a hash table (map in go), but I didn't want to add my implementation (that is pretty big and not so readable).

Co-authored-by: CleanMachine1 <[email protected]>
@Itai-Nelken
Copy link
Collaborator Author

Something I forgot to mention: this slows down dollarskip by about 0.030 seconds.

dollarskip.c Outdated Show resolved Hide resolved
@CleanMachine1
Copy link
Owner

Something I forgot to mention: this slows down dollarskip by about 0.030 seconds.

Thats an extremely long time. I'm sure the average person will notice 😄

There is no issue.

@Itai-Nelken
Copy link
Collaborator Author

I made a version of the changes here (excluding the "wrapping" of commands) for DollarSkip-go.
the true in all entries of the map don't do anything and are there because I wanted to use a map as it makes it possible to not use loops, and so is faster.

package main

import (
	"fmt" // for printing errors
	"os"      // for capturing argv
	"os/exec" // for running the commands
	"strings" // for unslicing the array
)

var unhandled_commands = map[string]bool{
	"cd": true,
	"alias" : true,
	"unalias" : true,
	"pushd" : true,
	"popd" : true,
	"dirs" : true,
	"read" : true,
	"set" : true,
	"readonly" : true,
	"unset" : true,
	"typeset" : true,
	"declare" : true,
	"disown" : true,
	"enable" : true,
	"export" : true,
	"exit" : true, // doesn't do anything when run through DollarSkip
	"fc" : true,
	"history" : true,
	"fg" : true,
	"getopts" : true,
	"hash" : true, // we don't want it to report fake data for the current shell (true for the shell in which it is run)
	"jobs" : true, // same reason as the one for 'hash'
	"times" : true, // same as above
	"local" : true,
}

func main() {
	if len(os.Args) < 2 {
		os.Exit(1)
	}
	if _, ok := unhandled_commands[os.Args[1]]; ok {
		fmt.Fprintf(os.Stderr, "\x1b[31;1m[DollarSkip: error]: '\x1b[97m%s\x1b[0;1;31m': built-in shell commands aren't supported!\x1b[0m\n", os.Args[1])
		os.Exit(1)
	}
	args := os.Args[1:]                               // collects given arguments and 1: removes the binary name
	unsliced_string := strings.Join(args, " ")        // convert to string rather than type []string from args
	shell := os.Getenv("SHELL")                       // Using the env, save the shell
	cmd := exec.Command(shell, `-c`, unsliced_string) // Define the command to be run
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin

	err := cmd.Run() // Run the command
	if exitErr, ok := err.(*exec.ExitError); ok {
		exitCode := exitErr.ExitCode()
		os.Exit(exitCode)

	} else if err != nil {
		exitCode := 1
		os.Exit(exitCode)

	}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: cd doesn't do anything when used with DollarSkip
2 participants