diff --git a/src/builtin/builtin.go b/src/builtin/builtin.go
index 215c59c4ae8156aa37a399682ccc099c3230b091..af01aea5dd79f4713cbdf52d3d03c5ff629b5380 100644
--- a/src/builtin/builtin.go
+++ b/src/builtin/builtin.go
@@ -247,7 +247,7 @@ func imag(c ComplexType) FloatType
 // to the zero value of the respective element type. If the argument
 // type is a type parameter, the type parameter's type set must
 // contain only map or slice types, and clear performs the operation
-// implied by the type argument.
+// implied by the type argument. If t is nil, clear is a no-op.
 func clear[T ~[]Type | ~map[Type]Type1](t T)
 
 // The close built-in function closes a channel, which must be either
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 9ff5fd41901c9034d72dc04f01b0795f1b82eda5..ef5272299bbf077ce3167d1d0f37818e6471e28d 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -796,7 +796,7 @@ Instead, the build process generates an object file using dynamic
 linkage to the desired libraries. The main function is provided by
 _cgo_main.c:
 
-	int main() { return 0; }
+	int main(int argc, char **argv) { return 0; }
 	void crosscall2(void(*fn)(void*), void *a, int c, uintptr_t ctxt) { }
 	uintptr_t _cgo_wait_runtime_init_done(void) { return 0; }
 	void _cgo_release_context(uintptr_t ctxt) { }
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 954c4b70c954ebbf884b66443d828686df24c92a..5e67cc2d3345985d9ac114f12cfd50accbd90789 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -59,7 +59,7 @@ func (p *Package) writeDefs() {
 
 	// Write C main file for using gcc to resolve imports.
 	fmt.Fprintf(fm, "#include <stddef.h>\n") // For size_t below.
-	fmt.Fprintf(fm, "int main() { return 0; }\n")
+	fmt.Fprintf(fm, "int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) { return 0; }\n")
 	if *importRuntimeCgo {
 		fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*) __attribute__((unused)), void *a __attribute__((unused)), int c __attribute__((unused)), size_t ctxt __attribute__((unused))) { }\n")
 		fmt.Fprintf(fm, "size_t _cgo_wait_runtime_init_done(void) { return 0; }\n")
diff --git a/src/internal/poll/sendfile_unix.go b/src/internal/poll/sendfile_unix.go
index f5aee38a054683f6c98abb750d51e1de89e4cc99..1105e0569110fb68afbd0aecb55c989a6ee5748e 100644
--- a/src/internal/poll/sendfile_unix.go
+++ b/src/internal/poll/sendfile_unix.go
@@ -110,12 +110,20 @@ func sendFile(dstFD *FD, src int, offset *int64, size int64) (written int64, err
 			// Retry.
 		case syscall.ENOSYS, syscall.EOPNOTSUPP, syscall.EINVAL:
 			// ENOSYS indicates no kernel support for sendfile.
-			// EINVAL indicates a FD type which does not support sendfile.
+			// EINVAL indicates a FD type that does not support sendfile.
 			//
 			// On Linux, copy_file_range can return EOPNOTSUPP when copying
 			// to a NFS file (issue #40731); check for it here just in case.
 			return written, err, written > 0
 		default:
+			// We want to handle ENOTSUP like EOPNOTSUPP.
+			// It's a pain to put it as a switch case
+			// because on Linux systems ENOTSUP == EOPNOTSUPP,
+			// so the compiler complains about a duplicate case.
+			if err == syscall.ENOTSUP {
+				return written, err, written > 0
+			}
+
 			// Not a retryable error.
 			return written, err, true
 		}
diff --git a/src/net/sendfile_unix_test.go b/src/net/sendfile_unix_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..79fb23b31010d569bbd7c431432275a77716b42b
--- /dev/null
+++ b/src/net/sendfile_unix_test.go
@@ -0,0 +1,86 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package net
+
+import (
+	"internal/testpty"
+	"io"
+	"os"
+	"sync"
+	"syscall"
+	"testing"
+)
+
+// Issue 70763: test that we don't fail on sendfile from a tty.
+func TestCopyFromTTY(t *testing.T) {
+	pty, ttyName, err := testpty.Open()
+	if err != nil {
+		t.Skipf("skipping test because pty open failed: %v", err)
+	}
+	defer pty.Close()
+
+	// Use syscall.Open so that the tty is blocking.
+	ttyFD, err := syscall.Open(ttyName, syscall.O_RDWR, 0)
+	if err != nil {
+		t.Skipf("skipping test because tty open failed: %v", err)
+	}
+	defer syscall.Close(ttyFD)
+
+	tty := os.NewFile(uintptr(ttyFD), "tty")
+	defer tty.Close()
+
+	ln := newLocalListener(t, "tcp")
+	defer ln.Close()
+
+	ch := make(chan bool)
+
+	const data = "data\n"
+
+	var wg sync.WaitGroup
+	defer wg.Wait()
+
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		conn, err := ln.Accept()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		defer conn.Close()
+
+		buf := make([]byte, len(data))
+		if _, err := io.ReadFull(conn, buf); err != nil {
+			t.Error(err)
+		}
+
+		ch <- true
+	}()
+
+	conn, err := Dial("tcp", ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		if _, err := pty.Write([]byte(data)); err != nil {
+			t.Error(err)
+		}
+		<-ch
+		if err := pty.Close(); err != nil {
+			t.Error(err)
+		}
+	}()
+
+	lr := io.LimitReader(tty, int64(len(data)))
+	if _, err := io.Copy(conn, lr); err != nil {
+		t.Error(err)
+	}
+}