summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/cd.go7
-rw-r--r--cmds/env.go17
-rw-r--r--cmds/external.go12
-rw-r--r--cmds/test.go13
-rw-r--r--cmds/trap.go14
-rw-r--r--global/global.go7
-rw-r--r--main.go31
7 files changed, 73 insertions, 28 deletions
diff --git a/cmds/cd.go b/cmds/cd.go
index 3a5e9d0..8fa3c5e 100644
--- a/cmds/cd.go
+++ b/cmds/cd.go
@@ -4,12 +4,15 @@ import "os"
// chDir: changes the current working directory
// if no directory is specifed sets it to home
-func ChDir(args []string) error {
+func ChDir(args []string) (int, error) {
var dir string
if len(args) == 1 {
dir, _ = os.UserHomeDir()
} else {
dir = args[1]
}
- return os.Chdir(dir)
+ if err := os.Chdir(dir); err != nil {
+ return 1, err
+ }
+ return 0, nil
}
diff --git a/cmds/env.go b/cmds/env.go
index 17b220d..63ee7f6 100644
--- a/cmds/env.go
+++ b/cmds/env.go
@@ -36,23 +36,26 @@ func Set(args []string) {
}
// unset: unsets an environment variable
-func Unset(args []string) error {
+func Unset(args []string) (int, error) {
if len(args) == 1 || len(args) >= 3 {
- return errors.New("usage: unset [name]")
+ return 1, errors.New("usage: unset [name]")
}
os.Unsetenv(args[1])
- return nil
+ return 0, nil
}
// export: exports a key-value pair to the environment
// in the form of `name=value`
-func Export(args []string) error {
+func Export(args []string) (int, error) {
if len(args) == 1 || len(args) >= 3 {
- return errors.New("usage: export [name=value]")
+ return 1, errors.New("usage: export [name=value]")
}
tmp := strings.Split(args[1], "=")
if len(tmp) != 2 {
- return errors.New("usage: export [name=value]")
+ return 1, errors.New("usage: export [name=value]")
}
- return os.Setenv(tmp[0], tmp[1])
+ if err := os.Setenv(tmp[0], tmp[1]); err != nil {
+ return 2, err
+ }
+ return 0, nil
}
diff --git a/cmds/external.go b/cmds/external.go
index 79c73eb..748ce7d 100644
--- a/cmds/external.go
+++ b/cmds/external.go
@@ -9,7 +9,7 @@ import (
"gosh/global"
)
-func External(args []string) {
+func External(args []string) int {
cmd := ""
found := false
for i := range global.Paths {
@@ -24,9 +24,13 @@ func External(args []string) {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
-
- cmd.Run()
- return
+
+ err := cmd.Run()
+ if exitErr, ok := err.(*exec.ExitError); ok {
+ return exitErr.ExitCode()
+ }
+ return 0
}
fmt.Fprintf(os.Stderr, "%s: Command not found\n", args[0])
+ return 1
}
diff --git a/cmds/test.go b/cmds/test.go
index f952384..efe4d97 100644
--- a/cmds/test.go
+++ b/cmds/test.go
@@ -1,6 +1,7 @@
package cmds
import (
+ "errors"
"os"
"os/user"
"strconv"
@@ -8,22 +9,22 @@ import (
"syscall"
)
-func Test(args []string) int {
+func Test(args []string) (int, error) {
if len(args) <= 2 {
- return 1
+ return 1, errors.New("test requires at least two arguments")
}
if strings.HasPrefix(args[1], "-") {
- return genTest(args[1:])
+ return genTest(args[1:]), nil
} else {
if len(args) != 4 {
- return 1
+ return 1, nil
}
_, err := strconv.Atoi(args[1])
if err != nil {
- return testString(args[1:])
+ return testString(args[1:]), nil
} else {
- return testNumber(args[1:])
+ return testNumber(args[1:]), nil
}
}
}
diff --git a/cmds/trap.go b/cmds/trap.go
new file mode 100644
index 0000000..5faf3e3
--- /dev/null
+++ b/cmds/trap.go
@@ -0,0 +1,14 @@
+package cmds
+
+import (
+ "errors"
+ "fmt"
+)
+
+func Trap(args []string) (int, error) {
+ if len(args) <= 3 {
+ return 1, errors.New("usage: trap: [[arg] signal]")
+ }
+ fmt.Println(len(args), args)
+ return 0, nil
+}
diff --git a/global/global.go b/global/global.go
index 708f05a..e7d8d79 100644
--- a/global/global.go
+++ b/global/global.go
@@ -5,12 +5,15 @@ import (
"strings"
)
-var Options []string
+
var ReturnCode int
var Paths []string
+var Options []string
+var Traps map[os.Signal]string
func init() {
- Options = make([]string, 0)
ReturnCode = 0
+ Options = make([]string, 0)
+ Traps = make(map[os.Signal]string)
Paths = strings.Split(os.Getenv("PATH"), ":")
}
diff --git a/main.go b/main.go
index 5334796..f7520ee 100644
--- a/main.go
+++ b/main.go
@@ -4,14 +4,22 @@ import (
"bufio"
"fmt"
"os"
+ "os/signal"
"strings"
"gosh/cmds"
"gosh/global"
)
+// TODO: iterate through args ahead of time to make things run better
func main() {
r := bufio.NewReader(os.Stdin)
+ ch := make(chan os.Signal, 1)
+
+ go func() {
+ signal.Notify(ch)
+ signal.Ignore(<-ch)
+ }()
for {
d, _ := os.Getwd()
@@ -24,19 +32,19 @@ func main() {
cmd = strings.TrimSuffix(cmd, "\n")
args := strings.Split(cmd, " ")
- switch (args[0]) {
+ switch args[0] {
case "cd":
- if err := cmds.ChDir(args); err != nil {
+ if global.ReturnCode, err = cmds.ChDir(args); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
break
case "export":
- if err := cmds.Export(args); err != nil {
+ if global.ReturnCode, err = cmds.Export(args); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
break
case "unset":
- if err := cmds.Unset(args); err != nil {
+ if global.ReturnCode, err = cmds.Unset(args); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
break
@@ -48,17 +56,26 @@ func main() {
}
break
case "test", "[":
- global.ReturnCode = cmds.Test(args)
+ if global.ReturnCode, err = cmds.Test(args); err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ }
+ break
+ case "trap":
+ if global.ReturnCode, err = cmds.Trap(args); err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ }
break
case ":":
+ global.ReturnCode = 0
+ err = nil
break
case "exit":
- if err := cmds.Exit(args); err != nil {
+ if err = cmds.Exit(args); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
break
default:
- cmds.External(args)
+ global.ReturnCode = cmds.External(args)
break
}
}