forked from hugelgupf/u-root
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request u-root#74 from GanShun/master
Added Chmod command
- Loading branch information
Showing
2 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2016 the u-root Authors. All rights reserved | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// chmod command in Go. | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"log" | ||
"strconv" | ||
"syscall" | ||
) | ||
|
||
func main() { | ||
flag.Parse() | ||
if len(flag.Args()) < 2 { | ||
flag.PrintDefaults() | ||
log.Fatalf("usage: chmod mode filepath") | ||
} | ||
|
||
octval, err := strconv.ParseUint(flag.Args()[0], 8, 32) | ||
if err != nil { | ||
log.Fatalf("Unable to decode mode. Please use an octal value. arg was %s, err was %v", flag.Args()[0], err) | ||
} else if octval > 0777 { | ||
log.Fatalf("Invalid octal value. Value larger than 777, was %o", octval) | ||
} | ||
|
||
mode := uint32(octval) | ||
|
||
var errors string | ||
for _, arg := range flag.Args()[1:] { | ||
if err := syscall.Chmod(arg, mode); err != nil { | ||
errors += fmt.Sprintf("Unable to chmod, filename was %s, err was %v\n", arg, err) | ||
} | ||
} | ||
if errors != "" { | ||
log.Fatalf(errors) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"testing" | ||
) | ||
|
||
var ( | ||
testPath = "." | ||
// if true removeAll the testPath on the end | ||
remove = true | ||
) | ||
|
||
type test struct { | ||
args []string | ||
expects string | ||
} | ||
|
||
func run(c *exec.Cmd) (string, string, error) { | ||
var o, e bytes.Buffer | ||
c.Stdout, c.Stderr = &o, &e | ||
err := c.Run() | ||
return o.String(), e.String(), err | ||
} | ||
|
||
func TestChmodSimple(t *testing.T) { | ||
tempDir, err := ioutil.TempDir("", "TestChmodSimple") | ||
if err != nil { | ||
t.Fatalf("cannot create temporary directory: %v", err) | ||
} | ||
if remove { | ||
defer os.RemoveAll(tempDir) | ||
} | ||
f, err := ioutil.TempFile(tempDir, "BLAH1") | ||
if err != nil { | ||
t.Fatalf("cannot create temporary file: %v", err) | ||
} | ||
defer f.Close() | ||
|
||
testpath := filepath.Join(tempDir, "testchmod.exe") | ||
out, err := exec.Command("go", "build", "-o", testpath, ".").CombinedOutput() | ||
if err != nil { | ||
t.Fatalf("go build -o %v cmds/chmod: %v\n%s", testpath, err, string(out)) | ||
} | ||
|
||
// Set permissions and check that they are correct | ||
c := exec.Command(testpath, "0777", f.Name()) | ||
c.Run() | ||
fileinfo, _ := os.Stat(f.Name()) | ||
fileperm := fileinfo.Mode().Perm() | ||
if fileperm != 0777 { | ||
t.Errorf("Wrong file permissions") | ||
} | ||
|
||
// Change permissions and check that they are correct | ||
c = exec.Command(testpath, "0644", f.Name()) | ||
c.Run() | ||
fileinfo, _ = os.Stat(f.Name()) | ||
fileperm = fileinfo.Mode().Perm() | ||
if fileperm != 0644 { | ||
t.Errorf("Wrong file permissions") | ||
} | ||
} | ||
|
||
func TestInvocationErrors(t *testing.T) { | ||
tempDir, err := ioutil.TempDir("", "TestInvocationErrors") | ||
if err != nil { | ||
t.Fatalf("cannot create temporary directory: %v", err) | ||
} | ||
if remove { | ||
defer os.RemoveAll(tempDir) | ||
} | ||
f, err := ioutil.TempFile(tempDir, "BLAH1") | ||
if err != nil { | ||
t.Fatalf("cannot create temporary file: %v", err) | ||
} | ||
defer f.Close() | ||
|
||
testpath := filepath.Join(tempDir, "testchmod.exe") | ||
out, err := exec.Command("go", "build", "-o", testpath, ".").CombinedOutput() | ||
if err != nil { | ||
t.Fatalf("go build -o %v cmds/chmod: %v\n%s", testpath, err, string(out)) | ||
} | ||
|
||
var tests = []test{ | ||
{args: []string{f.Name()}, expects: "usage: chmod mode filepath\n"}, | ||
{args: []string{""}, expects: "usage: chmod mode filepath\n"}, | ||
{args: []string{"01777", f.Name()}, expects: "Invalid octal value. Value larger than 777, was 1777\n"}, | ||
{args: []string{"0abas", f.Name()}, expects: "Unable to decode mode. Please use an octal value. arg was 0abas, err was strconv.ParseUint: parsing \"0abas\": invalid syntax\n"}, | ||
{args: []string{"0777", "blah1234"}, expects: "Unable to chmod, filename was blah1234, err was no such file or directory\n"}, | ||
} | ||
|
||
for _, v := range tests { | ||
c := exec.Command(testpath, v.args...) | ||
_, e, err := run(c) | ||
// Ignore the date and time because we're using Log.Fatalf | ||
if e[20:] != v.expects { | ||
t.Errorf("Chmod for '%v' failed: got '%s', want '%s'", v.args, e[20:], v.expects) | ||
} | ||
if err == nil { | ||
t.Errorf("Kill for '%v' failed: got nil want err", v.args) | ||
} | ||
} | ||
} |