Skip to content

Commit 5aafd0b

Browse files
committed
all: rebase
1 parent 18e038c commit 5aafd0b

File tree

2 files changed

+207
-6
lines changed

2 files changed

+207
-6
lines changed

Diff for: unix/syscall_zos_s390x.go

+56
Original file line numberDiff line numberDiff line change
@@ -3155,3 +3155,59 @@ func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {
31553155
}
31563156
return
31573157
}
3158+
3159+
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
3160+
if raceenabled {
3161+
raceReleaseMerge(unsafe.Pointer(&ioSync))
3162+
}
3163+
return sendfile(outfd, infd, offset, count)
3164+
}
3165+
3166+
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
3167+
// TODO: use LE call instead if the call is implemented
3168+
originalOffset, err := Seek(infd, 0, SEEK_CUR)
3169+
if err != nil {
3170+
return -1, err
3171+
}
3172+
//start reading data from in_fd
3173+
if offset != nil {
3174+
_, err := Seek(infd, *offset, SEEK_SET)
3175+
if err != nil {
3176+
return -1, err
3177+
}
3178+
}
3179+
3180+
buf := make([]byte, count)
3181+
readBuf := make([]byte, 0)
3182+
var n int = 0
3183+
for i := 0; i < count; i += n {
3184+
n, err := Read(infd, buf)
3185+
if n == 0 {
3186+
if err != nil {
3187+
return -1, err
3188+
} else { // EOF
3189+
break
3190+
}
3191+
}
3192+
readBuf = append(readBuf, buf...)
3193+
buf = buf[0:0]
3194+
}
3195+
3196+
n2, err := Write(outfd, readBuf)
3197+
if err != nil {
3198+
return -1, err
3199+
}
3200+
3201+
//When sendfile() returns, this variable will be set to the
3202+
// offset of the byte following the last byte that was read.
3203+
if offset != nil {
3204+
*offset = *offset + int64(n)
3205+
// If offset is not NULL, then sendfile() does not modify the file
3206+
// offset of in_fd
3207+
_, err := Seek(infd, originalOffset, SEEK_SET)
3208+
if err != nil {
3209+
return -1, err
3210+
}
3211+
}
3212+
return n2, nil
3213+
}

Diff for: unix/syscall_zos_test.go

+151-6
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,11 @@ func TestPassFD(t *testing.T) {
295295
defer writeFile.Close()
296296
defer readFile.Close()
297297

298-
cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", t.TempDir())
298+
exe, err := os.Executable()
299+
if err != nil {
300+
t.Fatal(err)
301+
}
302+
cmd := exec.Command(exe, "-test.run=^TestPassFD$", "--", t.TempDir())
299303
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
300304
if lp := os.Getenv("LD_LIBRARY_PATH"); lp != "" {
301305
cmd.Env = append(cmd.Env, "LD_LIBRARY_PATH="+lp)
@@ -940,7 +944,11 @@ func TestFlock(t *testing.T) {
940944
p2status := BLOCKED
941945
done := make(chan bool)
942946
execP2 := func(isBlock bool) {
943-
cmd := exec.Command(os.Args[0], "-test.run=^TestFlock$", strconv.Itoa(c.p2mode), f.Name())
947+
exe, err := os.Executable()
948+
if err != nil {
949+
t.Fatal(err)
950+
}
951+
cmd := exec.Command(exe, "-test.run=^TestFlock$", strconv.Itoa(c.p2mode), f.Name())
944952
cmd.Env = append(os.Environ(), "TEST_FLOCK_HELPER=1")
945953
out, _ := cmd.CombinedOutput()
946954
if p2status, err = strconv.Atoi(string(out)); err != nil {
@@ -1007,7 +1015,11 @@ func TestLegacyFlock(t *testing.T) {
10071015
if err != nil {
10081016
t.Fatalf("Flock: %s", err.Error())
10091017
}
1010-
cmd := exec.Command(os.Args[0], "-test.run=TestLegacyFlock", f.Name())
1018+
exe, err := os.Executable()
1019+
if err != nil {
1020+
t.Fatal(err)
1021+
}
1022+
cmd := exec.Command(exe, "-test.run=TestLegacyFlock", f.Name())
10111023
cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
10121024
out, err := cmd.CombinedOutput()
10131025
if len(out) > 0 || err != nil {
@@ -2375,7 +2387,11 @@ func TestWait4(t *testing.T) {
23752387

23762388
for _, c := range testCases {
23772389
t.Run(c.name, func(t *testing.T) {
2378-
cmd := exec.Command(os.Args[0], "-test.run=^TestWait4$", fmt.Sprint(c.exitCode))
2390+
exe, err := os.Executable()
2391+
if err != nil {
2392+
t.Fatal(err)
2393+
}
2394+
cmd := exec.Command(exe, "-test.run=^TestWait4$", fmt.Sprint(c.exitCode))
23792395
cmd.Env = []string{"TEST_WAIT4_HELPER=1"}
23802396
if err := cmd.Start(); err != nil {
23812397
t.Fatal(err)
@@ -2676,7 +2692,11 @@ func TestMountNamespace(t *testing.T) {
26762692
defer os.Remove(f.Name())
26772693
f.Close()
26782694

2679-
cmd := exec.Command(os.Args[0], "-test.v", "-test.run=^TestMountNamespace$")
2695+
exe, err := os.Executable()
2696+
if err != nil {
2697+
t.Fatal(err)
2698+
}
2699+
cmd := exec.Command(exe, "-test.v", "-test.run=^TestMountNamespace$")
26802700
cmd.Env = append(os.Environ(), "SETNS_HELPER_PROCESS=1")
26812701
cmd.Env = append(cmd.Env, "MNT_NS_FILE="+f.Name())
26822702

@@ -3670,7 +3690,11 @@ func TestSetns(t *testing.T) {
36703690
}
36713691
}
36723692

3673-
cmd := exec.Command(os.Args[0], "-test.run=^TestSetns$")
3693+
exe, err := os.Executable()
3694+
if err != nil {
3695+
t.Fatal(err)
3696+
}
3697+
cmd := exec.Command(exe, "-test.run=^TestSetns$")
36743698
cmd.Env = append(os.Environ(), "SETNS_HELPER_PROCESS=1")
36753699
stdin, err := cmd.StdinPipe()
36763700
if err != nil {
@@ -3869,5 +3893,126 @@ func TestTty(t *testing.T) {
38693893

38703894
if !bytes.Equal(text, buffer[:n]) {
38713895
t.Fatalf("Expected %+v, read %+v\n", text, buffer[:n])
3896+
3897+
}
3898+
3899+
}
3900+
3901+
func TestSendfile(t *testing.T) {
3902+
srcContent := "hello, world"
3903+
srcFile, err := os.Create(filepath.Join(t.TempDir(), "source"))
3904+
if err != nil {
3905+
t.Fatal("error: ", err)
3906+
}
3907+
defer srcFile.Close()
3908+
3909+
dstFile, err := os.Create(filepath.Join(t.TempDir(), "dst"))
3910+
if err != nil {
3911+
t.Fatal("error: ", err)
3912+
}
3913+
defer dstFile.Close()
3914+
3915+
err = os.WriteFile(srcFile.Name(), []byte(srcContent), 0644)
3916+
if err != nil {
3917+
t.Fatal("error: ", err)
3918+
}
3919+
3920+
n, err := unix.Sendfile(int(dstFile.Fd()), int(srcFile.Fd()), nil, len(srcContent))
3921+
if n != len(srcContent) {
3922+
t.Fatal("error: mismatch content length want ", len(srcContent), " got ", n)
3923+
}
3924+
if err != nil {
3925+
t.Fatal("error: ", err)
3926+
}
3927+
3928+
b, err := os.ReadFile(dstFile.Name())
3929+
if err != nil {
3930+
t.Fatal("error: ", err)
3931+
}
3932+
3933+
content := string(b)
3934+
if content != srcContent {
3935+
t.Fatal("content mismatch: ", content, " vs ", srcContent)
38723936
}
38733937
}
3938+
3939+
func TestSendfileSocket(t *testing.T) {
3940+
// Set up source data file.
3941+
name := filepath.Join(t.TempDir(), "source")
3942+
const contents = "contents"
3943+
err := os.WriteFile(name, []byte(contents), 0666)
3944+
if err != nil {
3945+
t.Fatal(err)
3946+
}
3947+
3948+
done := make(chan bool)
3949+
3950+
// Start server listening on a socket.
3951+
ln, err := net.Listen("tcp", "127.0.0.1:0")
3952+
if err != nil {
3953+
t.Skipf("listen failed: %s\n", err)
3954+
}
3955+
defer ln.Close()
3956+
go func() {
3957+
conn, err := ln.Accept()
3958+
if err != nil {
3959+
t.Errorf("failed to accept: %v", err)
3960+
return
3961+
}
3962+
defer conn.Close()
3963+
b, err := io.ReadAll(conn)
3964+
if err != nil {
3965+
t.Errorf("failed to read: %v", err)
3966+
return
3967+
}
3968+
if string(b) != contents {
3969+
t.Errorf("contents not transmitted: got %s (len=%d), want %s", string(b), len(b), contents)
3970+
}
3971+
done <- true
3972+
}()
3973+
3974+
// Open source file.
3975+
src, err := os.Open(name)
3976+
if err != nil {
3977+
t.Fatal(err)
3978+
}
3979+
3980+
// Send source file to server.
3981+
conn, err := net.Dial("tcp", ln.Addr().String())
3982+
if err != nil {
3983+
t.Fatal(err)
3984+
}
3985+
file, err := conn.(*net.TCPConn).File()
3986+
if err != nil {
3987+
t.Fatal(err)
3988+
}
3989+
var off int64
3990+
n, err := unix.Sendfile(int(file.Fd()), int(src.Fd()), &off, len(contents))
3991+
if err != nil {
3992+
t.Errorf("Sendfile failed %s\n", err)
3993+
}
3994+
if n != len(contents) {
3995+
t.Errorf("written count wrong: want %d, got %d", len(contents), n)
3996+
}
3997+
// Note: off is updated on some systems and not others. Oh well.
3998+
// Linux: increments off by the amount sent.
3999+
// Darwin: leaves off unchanged.
4000+
// It would be nice to fix Darwin if we can.
4001+
if off != 0 && off != int64(len(contents)) {
4002+
t.Errorf("offset wrong: god %d, want %d or %d", off, 0, len(contents))
4003+
}
4004+
// The cursor position should be unchanged.
4005+
pos, err := src.Seek(0, 1)
4006+
if err != nil {
4007+
t.Errorf("can't get cursor position %s\n", err)
4008+
}
4009+
if pos != 0 {
4010+
t.Errorf("cursor position wrong: got %d, want 0", pos)
4011+
}
4012+
4013+
file.Close() // Note: required to have the close below really send EOF to the server.
4014+
conn.Close()
4015+
4016+
// Wait for server to close.
4017+
<-done
4018+
}

0 commit comments

Comments
 (0)