TUN-6937: Bump golang.org/x/* packages to new release tags
This commit is contained in:
parent
85b44695f0
commit
1fe4878264
17
go.mod
17
go.mod
|
@ -35,11 +35,11 @@ require (
|
||||||
go.opentelemetry.io/otel/trace v1.6.3
|
go.opentelemetry.io/otel/trace v1.6.3
|
||||||
go.opentelemetry.io/proto/otlp v0.15.0
|
go.opentelemetry.io/proto/otlp v0.15.0
|
||||||
go.uber.org/automaxprocs v1.4.0
|
go.uber.org/automaxprocs v1.4.0
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
golang.org/x/crypto v0.2.0
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
|
golang.org/x/net v0.2.0
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
|
golang.org/x/sync v0.1.0
|
||||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664
|
golang.org/x/sys v0.2.0
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
golang.org/x/term v0.2.0
|
||||||
google.golang.org/protobuf v1.28.0
|
google.golang.org/protobuf v1.28.0
|
||||||
gopkg.in/coreos/go-oidc.v2 v2.2.1
|
gopkg.in/coreos/go-oidc.v2 v2.2.1
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
|
@ -89,11 +89,10 @@ require (
|
||||||
github.com/prometheus/common v0.32.1 // indirect
|
github.com/prometheus/common v0.32.1 // indirect
|
||||||
github.com/prometheus/procfs v0.7.3 // indirect
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
golang.org/x/mod v0.4.2 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
|
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.4.0 // indirect
|
||||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
|
golang.org/x/tools v0.1.12 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
||||||
google.golang.org/grpc v1.47.0 // indirect
|
google.golang.org/grpc v1.47.0 // indirect
|
||||||
|
|
26
go.sum
26
go.sum
|
@ -644,8 +644,9 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
||||||
|
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -681,8 +682,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -742,8 +744,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
||||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
|
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -780,8 +782,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
|
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -865,12 +868,14 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
|
|
||||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
|
||||||
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -879,8 +884,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||||
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -945,15 +951,15 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
|
|
||||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
"golang.org/x/crypto/internal/subtle"
|
"golang.org/x/crypto/internal/alias"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -189,7 +189,7 @@ func (s *Cipher) XORKeyStream(dst, src []byte) {
|
||||||
panic("chacha20: output smaller than input")
|
panic("chacha20: output smaller than input")
|
||||||
}
|
}
|
||||||
dst = dst[:len(src)]
|
dst = dst[:len(src)]
|
||||||
if subtle.InexactOverlap(dst, src) {
|
if alias.InexactOverlap(dst, src) {
|
||||||
panic("chacha20: invalid buffer overlap")
|
panic("chacha20: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ package chacha20poly1305
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"golang.org/x/crypto/internal/subtle"
|
"golang.org/x/crypto/internal/alias"
|
||||||
"golang.org/x/sys/cpu"
|
"golang.org/x/sys/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []
|
||||||
setupState(&state, &c.key, nonce)
|
setupState(&state, &c.key, nonce)
|
||||||
|
|
||||||
ret, out := sliceForAppend(dst, len(plaintext)+16)
|
ret, out := sliceForAppend(dst, len(plaintext)+16)
|
||||||
if subtle.InexactOverlap(out, plaintext) {
|
if alias.InexactOverlap(out, plaintext) {
|
||||||
panic("chacha20poly1305: invalid buffer overlap")
|
panic("chacha20poly1305: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
|
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
|
||||||
|
@ -73,7 +73,7 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) (
|
||||||
|
|
||||||
ciphertext = ciphertext[:len(ciphertext)-16]
|
ciphertext = ciphertext[:len(ciphertext)-16]
|
||||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
ret, out := sliceForAppend(dst, len(ciphertext))
|
||||||
if subtle.InexactOverlap(out, ciphertext) {
|
if alias.InexactOverlap(out, ciphertext) {
|
||||||
panic("chacha20poly1305: invalid buffer overlap")
|
panic("chacha20poly1305: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
|
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"golang.org/x/crypto/chacha20"
|
"golang.org/x/crypto/chacha20"
|
||||||
|
"golang.org/x/crypto/internal/alias"
|
||||||
"golang.org/x/crypto/internal/poly1305"
|
"golang.org/x/crypto/internal/poly1305"
|
||||||
"golang.org/x/crypto/internal/subtle"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeWithPadding(p *poly1305.MAC, b []byte) {
|
func writeWithPadding(p *poly1305.MAC, b []byte) {
|
||||||
|
@ -30,7 +30,7 @@ func writeUint64(p *poly1305.MAC, n int) {
|
||||||
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
|
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||||
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
|
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
|
||||||
ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
|
ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
|
||||||
if subtle.InexactOverlap(out, plaintext) {
|
if alias.InexactOverlap(out, plaintext) {
|
||||||
panic("chacha20poly1305: invalid buffer overlap")
|
panic("chacha20poly1305: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
|
||||||
writeUint64(p, len(ciphertext))
|
writeUint64(p, len(ciphertext))
|
||||||
|
|
||||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
ret, out := sliceForAppend(dst, len(ciphertext))
|
||||||
if subtle.InexactOverlap(out, ciphertext) {
|
if alias.InexactOverlap(out, ciphertext) {
|
||||||
panic("chacha20poly1305: invalid buffer overlap")
|
panic("chacha20poly1305: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
if !p.Verify(tag) {
|
if !p.Verify(tag) {
|
||||||
|
|
|
@ -95,6 +95,11 @@ func (b *Builder) AddUint32(v uint32) {
|
||||||
b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddUint64 appends a big-endian, 64-bit value to the byte string.
|
||||||
|
func (b *Builder) AddUint64(v uint64) {
|
||||||
|
b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
||||||
|
}
|
||||||
|
|
||||||
// AddBytes appends a sequence of bytes to the byte string.
|
// AddBytes appends a sequence of bytes to the byte string.
|
||||||
func (b *Builder) AddBytes(v []byte) {
|
func (b *Builder) AddBytes(v []byte) {
|
||||||
b.add(v...)
|
b.add(v...)
|
||||||
|
|
|
@ -81,6 +81,17 @@ func (s *String) ReadUint32(out *uint32) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it.
|
||||||
|
// It reports whether the read was successful.
|
||||||
|
func (s *String) ReadUint64(out *uint64) bool {
|
||||||
|
v := s.read(8)
|
||||||
|
if v == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (s *String) readUnsigned(out *uint32, length int) bool {
|
func (s *String) readUnsigned(out *uint32, length int) bool {
|
||||||
v := s.read(length)
|
v := s.read(length)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
//go:build !purego
|
//go:build !purego
|
||||||
// +build !purego
|
// +build !purego
|
||||||
|
|
||||||
// Package subtle implements functions that are often useful in cryptographic
|
// Package alias implements memory aliasing tests.
|
||||||
// code but require careful thought to use correctly.
|
package alias
|
||||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
//go:build purego
|
//go:build purego
|
||||||
// +build purego
|
// +build purego
|
||||||
|
|
||||||
// Package subtle implements functions that are often useful in cryptographic
|
// Package alias implements memory aliasing tests.
|
||||||
// code but require careful thought to use correctly.
|
package alias
|
||||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
|
||||||
|
|
||||||
// This is the Google App Engine standard variant based on reflect
|
// This is the Google App Engine standard variant based on reflect
|
||||||
// because the unsafe package and cgo are disallowed.
|
// because the unsafe package and cgo are disallowed.
|
|
@ -35,8 +35,8 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
|
||||||
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
|
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"golang.org/x/crypto/internal/alias"
|
||||||
"golang.org/x/crypto/internal/poly1305"
|
"golang.org/x/crypto/internal/poly1305"
|
||||||
"golang.org/x/crypto/internal/subtle"
|
|
||||||
"golang.org/x/crypto/salsa20/salsa"
|
"golang.org/x/crypto/salsa20/salsa"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
|
||||||
copy(poly1305Key[:], firstBlock[:])
|
copy(poly1305Key[:], firstBlock[:])
|
||||||
|
|
||||||
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
|
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
|
||||||
if subtle.AnyOverlap(out, message) {
|
if alias.AnyOverlap(out, message) {
|
||||||
panic("nacl: invalid buffer overlap")
|
panic("nacl: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, out := sliceForAppend(out, len(box)-Overhead)
|
ret, out := sliceForAppend(out, len(box)-Overhead)
|
||||||
if subtle.AnyOverlap(out, box) {
|
if alias.AnyOverlap(out, box) {
|
||||||
panic("nacl: invalid buffer overlap")
|
panic("nacl: invalid buffer overlap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
// Package salsa provides low-level access to functions in the Salsa family.
|
// Package salsa provides low-level access to functions in the Salsa family.
|
||||||
package salsa // import "golang.org/x/crypto/salsa20/salsa"
|
package salsa // import "golang.org/x/crypto/salsa20/salsa"
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
// Sigma is the Salsa20 constant for 256-bit keys.
|
// Sigma is the Salsa20 constant for 256-bit keys.
|
||||||
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
|
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
|
||||||
|
|
||||||
|
@ -31,76 +33,76 @@ func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||||
|
|
||||||
for i := 0; i < 20; i += 2 {
|
for i := 0; i < 20; i += 2 {
|
||||||
u := x0 + x12
|
u := x0 + x12
|
||||||
x4 ^= u<<7 | u>>(32-7)
|
x4 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x4 + x0
|
u = x4 + x0
|
||||||
x8 ^= u<<9 | u>>(32-9)
|
x8 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x8 + x4
|
u = x8 + x4
|
||||||
x12 ^= u<<13 | u>>(32-13)
|
x12 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x12 + x8
|
u = x12 + x8
|
||||||
x0 ^= u<<18 | u>>(32-18)
|
x0 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x5 + x1
|
u = x5 + x1
|
||||||
x9 ^= u<<7 | u>>(32-7)
|
x9 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x9 + x5
|
u = x9 + x5
|
||||||
x13 ^= u<<9 | u>>(32-9)
|
x13 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x13 + x9
|
u = x13 + x9
|
||||||
x1 ^= u<<13 | u>>(32-13)
|
x1 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x1 + x13
|
u = x1 + x13
|
||||||
x5 ^= u<<18 | u>>(32-18)
|
x5 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x10 + x6
|
u = x10 + x6
|
||||||
x14 ^= u<<7 | u>>(32-7)
|
x14 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x14 + x10
|
u = x14 + x10
|
||||||
x2 ^= u<<9 | u>>(32-9)
|
x2 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x2 + x14
|
u = x2 + x14
|
||||||
x6 ^= u<<13 | u>>(32-13)
|
x6 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x6 + x2
|
u = x6 + x2
|
||||||
x10 ^= u<<18 | u>>(32-18)
|
x10 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x15 + x11
|
u = x15 + x11
|
||||||
x3 ^= u<<7 | u>>(32-7)
|
x3 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x3 + x15
|
u = x3 + x15
|
||||||
x7 ^= u<<9 | u>>(32-9)
|
x7 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x7 + x3
|
u = x7 + x3
|
||||||
x11 ^= u<<13 | u>>(32-13)
|
x11 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x11 + x7
|
u = x11 + x7
|
||||||
x15 ^= u<<18 | u>>(32-18)
|
x15 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x0 + x3
|
u = x0 + x3
|
||||||
x1 ^= u<<7 | u>>(32-7)
|
x1 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x1 + x0
|
u = x1 + x0
|
||||||
x2 ^= u<<9 | u>>(32-9)
|
x2 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x2 + x1
|
u = x2 + x1
|
||||||
x3 ^= u<<13 | u>>(32-13)
|
x3 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x3 + x2
|
u = x3 + x2
|
||||||
x0 ^= u<<18 | u>>(32-18)
|
x0 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x5 + x4
|
u = x5 + x4
|
||||||
x6 ^= u<<7 | u>>(32-7)
|
x6 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x6 + x5
|
u = x6 + x5
|
||||||
x7 ^= u<<9 | u>>(32-9)
|
x7 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x7 + x6
|
u = x7 + x6
|
||||||
x4 ^= u<<13 | u>>(32-13)
|
x4 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x4 + x7
|
u = x4 + x7
|
||||||
x5 ^= u<<18 | u>>(32-18)
|
x5 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x10 + x9
|
u = x10 + x9
|
||||||
x11 ^= u<<7 | u>>(32-7)
|
x11 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x11 + x10
|
u = x11 + x10
|
||||||
x8 ^= u<<9 | u>>(32-9)
|
x8 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x8 + x11
|
u = x8 + x11
|
||||||
x9 ^= u<<13 | u>>(32-13)
|
x9 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x9 + x8
|
u = x9 + x8
|
||||||
x10 ^= u<<18 | u>>(32-18)
|
x10 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x15 + x14
|
u = x15 + x14
|
||||||
x12 ^= u<<7 | u>>(32-7)
|
x12 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x12 + x15
|
u = x12 + x15
|
||||||
x13 ^= u<<9 | u>>(32-9)
|
x13 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x13 + x12
|
u = x13 + x12
|
||||||
x14 ^= u<<13 | u>>(32-13)
|
x14 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x14 + x13
|
u = x14 + x13
|
||||||
x15 ^= u<<18 | u>>(32-18)
|
x15 ^= bits.RotateLeft32(u, 18)
|
||||||
}
|
}
|
||||||
out[0] = byte(x0)
|
out[0] = byte(x0)
|
||||||
out[1] = byte(x0 >> 8)
|
out[1] = byte(x0 >> 8)
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package salsa
|
package salsa
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
|
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
|
||||||
// the result into the 64-byte array out. The input and output may be the same array.
|
// the result into the 64-byte array out. The input and output may be the same array.
|
||||||
func Core208(out *[64]byte, in *[64]byte) {
|
func Core208(out *[64]byte, in *[64]byte) {
|
||||||
|
@ -29,76 +31,76 @@ func Core208(out *[64]byte, in *[64]byte) {
|
||||||
|
|
||||||
for i := 0; i < 8; i += 2 {
|
for i := 0; i < 8; i += 2 {
|
||||||
u := x0 + x12
|
u := x0 + x12
|
||||||
x4 ^= u<<7 | u>>(32-7)
|
x4 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x4 + x0
|
u = x4 + x0
|
||||||
x8 ^= u<<9 | u>>(32-9)
|
x8 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x8 + x4
|
u = x8 + x4
|
||||||
x12 ^= u<<13 | u>>(32-13)
|
x12 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x12 + x8
|
u = x12 + x8
|
||||||
x0 ^= u<<18 | u>>(32-18)
|
x0 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x5 + x1
|
u = x5 + x1
|
||||||
x9 ^= u<<7 | u>>(32-7)
|
x9 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x9 + x5
|
u = x9 + x5
|
||||||
x13 ^= u<<9 | u>>(32-9)
|
x13 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x13 + x9
|
u = x13 + x9
|
||||||
x1 ^= u<<13 | u>>(32-13)
|
x1 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x1 + x13
|
u = x1 + x13
|
||||||
x5 ^= u<<18 | u>>(32-18)
|
x5 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x10 + x6
|
u = x10 + x6
|
||||||
x14 ^= u<<7 | u>>(32-7)
|
x14 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x14 + x10
|
u = x14 + x10
|
||||||
x2 ^= u<<9 | u>>(32-9)
|
x2 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x2 + x14
|
u = x2 + x14
|
||||||
x6 ^= u<<13 | u>>(32-13)
|
x6 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x6 + x2
|
u = x6 + x2
|
||||||
x10 ^= u<<18 | u>>(32-18)
|
x10 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x15 + x11
|
u = x15 + x11
|
||||||
x3 ^= u<<7 | u>>(32-7)
|
x3 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x3 + x15
|
u = x3 + x15
|
||||||
x7 ^= u<<9 | u>>(32-9)
|
x7 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x7 + x3
|
u = x7 + x3
|
||||||
x11 ^= u<<13 | u>>(32-13)
|
x11 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x11 + x7
|
u = x11 + x7
|
||||||
x15 ^= u<<18 | u>>(32-18)
|
x15 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x0 + x3
|
u = x0 + x3
|
||||||
x1 ^= u<<7 | u>>(32-7)
|
x1 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x1 + x0
|
u = x1 + x0
|
||||||
x2 ^= u<<9 | u>>(32-9)
|
x2 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x2 + x1
|
u = x2 + x1
|
||||||
x3 ^= u<<13 | u>>(32-13)
|
x3 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x3 + x2
|
u = x3 + x2
|
||||||
x0 ^= u<<18 | u>>(32-18)
|
x0 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x5 + x4
|
u = x5 + x4
|
||||||
x6 ^= u<<7 | u>>(32-7)
|
x6 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x6 + x5
|
u = x6 + x5
|
||||||
x7 ^= u<<9 | u>>(32-9)
|
x7 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x7 + x6
|
u = x7 + x6
|
||||||
x4 ^= u<<13 | u>>(32-13)
|
x4 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x4 + x7
|
u = x4 + x7
|
||||||
x5 ^= u<<18 | u>>(32-18)
|
x5 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x10 + x9
|
u = x10 + x9
|
||||||
x11 ^= u<<7 | u>>(32-7)
|
x11 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x11 + x10
|
u = x11 + x10
|
||||||
x8 ^= u<<9 | u>>(32-9)
|
x8 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x8 + x11
|
u = x8 + x11
|
||||||
x9 ^= u<<13 | u>>(32-13)
|
x9 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x9 + x8
|
u = x9 + x8
|
||||||
x10 ^= u<<18 | u>>(32-18)
|
x10 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x15 + x14
|
u = x15 + x14
|
||||||
x12 ^= u<<7 | u>>(32-7)
|
x12 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x12 + x15
|
u = x12 + x15
|
||||||
x13 ^= u<<9 | u>>(32-9)
|
x13 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x13 + x12
|
u = x13 + x12
|
||||||
x14 ^= u<<13 | u>>(32-13)
|
x14 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x14 + x13
|
u = x14 + x13
|
||||||
x15 ^= u<<18 | u>>(32-18)
|
x15 ^= bits.RotateLeft32(u, 18)
|
||||||
}
|
}
|
||||||
x0 += j0
|
x0 += j0
|
||||||
x1 += j1
|
x1 += j1
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package salsa
|
package salsa
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
const rounds = 20
|
const rounds = 20
|
||||||
|
|
||||||
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
|
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
|
||||||
|
@ -31,76 +33,76 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||||
|
|
||||||
for i := 0; i < rounds; i += 2 {
|
for i := 0; i < rounds; i += 2 {
|
||||||
u := x0 + x12
|
u := x0 + x12
|
||||||
x4 ^= u<<7 | u>>(32-7)
|
x4 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x4 + x0
|
u = x4 + x0
|
||||||
x8 ^= u<<9 | u>>(32-9)
|
x8 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x8 + x4
|
u = x8 + x4
|
||||||
x12 ^= u<<13 | u>>(32-13)
|
x12 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x12 + x8
|
u = x12 + x8
|
||||||
x0 ^= u<<18 | u>>(32-18)
|
x0 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x5 + x1
|
u = x5 + x1
|
||||||
x9 ^= u<<7 | u>>(32-7)
|
x9 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x9 + x5
|
u = x9 + x5
|
||||||
x13 ^= u<<9 | u>>(32-9)
|
x13 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x13 + x9
|
u = x13 + x9
|
||||||
x1 ^= u<<13 | u>>(32-13)
|
x1 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x1 + x13
|
u = x1 + x13
|
||||||
x5 ^= u<<18 | u>>(32-18)
|
x5 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x10 + x6
|
u = x10 + x6
|
||||||
x14 ^= u<<7 | u>>(32-7)
|
x14 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x14 + x10
|
u = x14 + x10
|
||||||
x2 ^= u<<9 | u>>(32-9)
|
x2 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x2 + x14
|
u = x2 + x14
|
||||||
x6 ^= u<<13 | u>>(32-13)
|
x6 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x6 + x2
|
u = x6 + x2
|
||||||
x10 ^= u<<18 | u>>(32-18)
|
x10 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x15 + x11
|
u = x15 + x11
|
||||||
x3 ^= u<<7 | u>>(32-7)
|
x3 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x3 + x15
|
u = x3 + x15
|
||||||
x7 ^= u<<9 | u>>(32-9)
|
x7 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x7 + x3
|
u = x7 + x3
|
||||||
x11 ^= u<<13 | u>>(32-13)
|
x11 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x11 + x7
|
u = x11 + x7
|
||||||
x15 ^= u<<18 | u>>(32-18)
|
x15 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x0 + x3
|
u = x0 + x3
|
||||||
x1 ^= u<<7 | u>>(32-7)
|
x1 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x1 + x0
|
u = x1 + x0
|
||||||
x2 ^= u<<9 | u>>(32-9)
|
x2 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x2 + x1
|
u = x2 + x1
|
||||||
x3 ^= u<<13 | u>>(32-13)
|
x3 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x3 + x2
|
u = x3 + x2
|
||||||
x0 ^= u<<18 | u>>(32-18)
|
x0 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x5 + x4
|
u = x5 + x4
|
||||||
x6 ^= u<<7 | u>>(32-7)
|
x6 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x6 + x5
|
u = x6 + x5
|
||||||
x7 ^= u<<9 | u>>(32-9)
|
x7 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x7 + x6
|
u = x7 + x6
|
||||||
x4 ^= u<<13 | u>>(32-13)
|
x4 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x4 + x7
|
u = x4 + x7
|
||||||
x5 ^= u<<18 | u>>(32-18)
|
x5 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x10 + x9
|
u = x10 + x9
|
||||||
x11 ^= u<<7 | u>>(32-7)
|
x11 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x11 + x10
|
u = x11 + x10
|
||||||
x8 ^= u<<9 | u>>(32-9)
|
x8 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x8 + x11
|
u = x8 + x11
|
||||||
x9 ^= u<<13 | u>>(32-13)
|
x9 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x9 + x8
|
u = x9 + x8
|
||||||
x10 ^= u<<18 | u>>(32-18)
|
x10 ^= bits.RotateLeft32(u, 18)
|
||||||
|
|
||||||
u = x15 + x14
|
u = x15 + x14
|
||||||
x12 ^= u<<7 | u>>(32-7)
|
x12 ^= bits.RotateLeft32(u, 7)
|
||||||
u = x12 + x15
|
u = x12 + x15
|
||||||
x13 ^= u<<9 | u>>(32-9)
|
x13 ^= bits.RotateLeft32(u, 9)
|
||||||
u = x13 + x12
|
u = x13 + x12
|
||||||
x14 ^= u<<13 | u>>(32-13)
|
x14 ^= bits.RotateLeft32(u, 13)
|
||||||
u = x14 + x13
|
u = x14 + x13
|
||||||
x15 ^= u<<18 | u>>(32-18)
|
x15 ^= bits.RotateLeft32(u, 18)
|
||||||
}
|
}
|
||||||
x0 += j0
|
x0 += j0
|
||||||
x1 += j1
|
x1 += j1
|
||||||
|
|
|
@ -251,7 +251,7 @@ type algorithmOpenSSHCertSigner struct {
|
||||||
// private key is held by signer. It returns an error if the public key in cert
|
// private key is held by signer. It returns an error if the public key in cert
|
||||||
// doesn't match the key used by signer.
|
// doesn't match the key used by signer.
|
||||||
func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
|
func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
|
||||||
if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
|
if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
|
||||||
return nil, errors.New("ssh: signer and cert have different public key")
|
return nil, errors.New("ssh: signer and cert have different public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/chacha20"
|
"golang.org/x/crypto/chacha20"
|
||||||
"golang.org/x/crypto/internal/poly1305"
|
"golang.org/x/crypto/internal/poly1305"
|
||||||
|
@ -97,13 +96,13 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream,
|
||||||
// are not supported and will not be negotiated, even if explicitly requested in
|
// are not supported and will not be negotiated, even if explicitly requested in
|
||||||
// ClientConfig.Crypto.Ciphers.
|
// ClientConfig.Crypto.Ciphers.
|
||||||
var cipherModes = map[string]*cipherMode{
|
var cipherModes = map[string]*cipherMode{
|
||||||
// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
|
// Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
|
||||||
// are defined in the order specified in the RFC.
|
// are defined in the order specified in the RFC.
|
||||||
"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||||
"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||||
"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||||
|
|
||||||
// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
|
// Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
|
||||||
// They are defined in the order specified in the RFC.
|
// They are defined in the order specified in the RFC.
|
||||||
"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
|
"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
|
||||||
"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
|
"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
|
||||||
|
@ -111,7 +110,7 @@ var cipherModes = map[string]*cipherMode{
|
||||||
// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
|
// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
|
||||||
// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
|
// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
|
||||||
// RC4) has problems with weak keys, and should be used with caution."
|
// RC4) has problems with weak keys, and should be used with caution."
|
||||||
// RFC4345 introduces improved versions of Arcfour.
|
// RFC 4345 introduces improved versions of Arcfour.
|
||||||
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
|
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
|
||||||
|
|
||||||
// AEAD ciphers
|
// AEAD ciphers
|
||||||
|
@ -497,7 +496,7 @@ func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
|
||||||
// data, to make distinguishing between
|
// data, to make distinguishing between
|
||||||
// failing MAC and failing length check more
|
// failing MAC and failing length check more
|
||||||
// difficult.
|
// difficult.
|
||||||
io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage))
|
io.CopyN(io.Discard, r, int64(c.oracleCamouflage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p, err
|
return p, err
|
||||||
|
@ -642,7 +641,7 @@ const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
|
||||||
//
|
//
|
||||||
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
|
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
|
||||||
//
|
//
|
||||||
// the methods here also implement padding, which RFC4253 Section 6
|
// the methods here also implement padding, which RFC 4253 Section 6
|
||||||
// also requires of stream ciphers.
|
// also requires of stream ciphers.
|
||||||
type chacha20Poly1305Cipher struct {
|
type chacha20Poly1305Cipher struct {
|
||||||
lengthKey [32]byte
|
lengthKey [32]byte
|
||||||
|
|
|
@ -149,7 +149,7 @@ type directionAlgorithms struct {
|
||||||
|
|
||||||
// rekeyBytes returns a rekeying intervals in bytes.
|
// rekeyBytes returns a rekeying intervals in bytes.
|
||||||
func (a *directionAlgorithms) rekeyBytes() int64 {
|
func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||||
// According to RFC4344 block ciphers should rekey after
|
// According to RFC 4344 block ciphers should rekey after
|
||||||
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
|
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
|
||||||
// 128.
|
// 128.
|
||||||
switch a.Cipher {
|
switch a.Cipher {
|
||||||
|
@ -158,7 +158,7 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For others, stick with RFC4253 recommendation to rekey after 1 Gb of data.
|
// For others, stick with RFC 4253 recommendation to rekey after 1 Gb of data.
|
||||||
return 1 << 30
|
return 1 << 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ type Conn interface {
|
||||||
|
|
||||||
// SendRequest sends a global request, and returns the
|
// SendRequest sends a global request, and returns the
|
||||||
// reply. If wantReply is true, it returns the response status
|
// reply. If wantReply is true, it returns the response status
|
||||||
// and payload. See also RFC4254, section 4.
|
// and payload. See also RFC 4254, section 4.
|
||||||
SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
|
SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
|
||||||
|
|
||||||
// OpenChannel tries to open an channel. If the request is
|
// OpenChannel tries to open an channel. If the request is
|
||||||
|
|
|
@ -184,7 +184,7 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey
|
||||||
return "", nil, nil, "", nil, io.EOF
|
return "", nil, nil, "", nil, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseAuthorizedKeys parses a public key from an authorized_keys
|
// ParseAuthorizedKey parses a public key from an authorized_keys
|
||||||
// file used in OpenSSH according to the sshd(8) manual page.
|
// file used in OpenSSH according to the sshd(8) manual page.
|
||||||
func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
|
func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
|
||||||
for len(in) > 0 {
|
for len(in) > 0 {
|
||||||
|
|
|
@ -68,7 +68,7 @@ type kexInitMsg struct {
|
||||||
|
|
||||||
// See RFC 4253, section 8.
|
// See RFC 4253, section 8.
|
||||||
|
|
||||||
// Diffie-Helman
|
// Diffie-Hellman
|
||||||
const msgKexDHInit = 30
|
const msgKexDHInit = 30
|
||||||
|
|
||||||
type kexDHInitMsg struct {
|
type kexDHInitMsg struct {
|
||||||
|
|
|
@ -68,8 +68,16 @@ type ServerConfig struct {
|
||||||
|
|
||||||
// NoClientAuth is true if clients are allowed to connect without
|
// NoClientAuth is true if clients are allowed to connect without
|
||||||
// authenticating.
|
// authenticating.
|
||||||
|
// To determine NoClientAuth at runtime, set NoClientAuth to true
|
||||||
|
// and the optional NoClientAuthCallback to a non-nil value.
|
||||||
NoClientAuth bool
|
NoClientAuth bool
|
||||||
|
|
||||||
|
// NoClientAuthCallback, if non-nil, is called when a user
|
||||||
|
// attempts to authenticate with auth method "none".
|
||||||
|
// NoClientAuth must also be set to true for this be used, or
|
||||||
|
// this func is unused.
|
||||||
|
NoClientAuthCallback func(ConnMetadata) (*Permissions, error)
|
||||||
|
|
||||||
// MaxAuthTries specifies the maximum number of authentication attempts
|
// MaxAuthTries specifies the maximum number of authentication attempts
|
||||||
// permitted per connection. If set to a negative number, the number of
|
// permitted per connection. If set to a negative number, the number of
|
||||||
// attempts are unlimited. If set to zero, the number of attempts are limited
|
// attempts are unlimited. If set to zero, the number of attempts are limited
|
||||||
|
@ -455,7 +463,11 @@ userAuthLoop:
|
||||||
switch userAuthReq.Method {
|
switch userAuthReq.Method {
|
||||||
case "none":
|
case "none":
|
||||||
if config.NoClientAuth {
|
if config.NoClientAuth {
|
||||||
authErr = nil
|
if config.NoClientAuthCallback != nil {
|
||||||
|
perms, authErr = config.NoClientAuthCallback(s)
|
||||||
|
} else {
|
||||||
|
authErr = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow initial attempt of 'none' without penalty
|
// allow initial attempt of 'none' without penalty
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -124,7 +123,7 @@ type Session struct {
|
||||||
// output and error.
|
// output and error.
|
||||||
//
|
//
|
||||||
// If either is nil, Run connects the corresponding file
|
// If either is nil, Run connects the corresponding file
|
||||||
// descriptor to an instance of ioutil.Discard. There is a
|
// descriptor to an instance of io.Discard. There is a
|
||||||
// fixed amount of buffering that is shared for the two streams.
|
// fixed amount of buffering that is shared for the two streams.
|
||||||
// If either blocks it may eventually cause the remote
|
// If either blocks it may eventually cause the remote
|
||||||
// command to block.
|
// command to block.
|
||||||
|
@ -506,7 +505,7 @@ func (s *Session) stdout() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.Stdout == nil {
|
if s.Stdout == nil {
|
||||||
s.Stdout = ioutil.Discard
|
s.Stdout = io.Discard
|
||||||
}
|
}
|
||||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||||
_, err := io.Copy(s.Stdout, s.ch)
|
_, err := io.Copy(s.Stdout, s.ch)
|
||||||
|
@ -519,7 +518,7 @@ func (s *Session) stderr() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.Stderr == nil {
|
if s.Stderr == nil {
|
||||||
s.Stderr = ioutil.Discard
|
s.Stderr = io.Discard
|
||||||
}
|
}
|
||||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||||
_, err := io.Copy(s.Stderr, s.ch.Stderr())
|
_, err := io.Copy(s.Stderr, s.ch.Stderr())
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// Package lazyregexp is a thin wrapper over regexp, allowing the use of global
|
||||||
|
// regexp variables without forcing them to be compiled at init.
|
||||||
|
package lazyregexp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
|
||||||
|
// compiled the first time it is needed.
|
||||||
|
type Regexp struct {
|
||||||
|
str string
|
||||||
|
once sync.Once
|
||||||
|
rx *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) re() *regexp.Regexp {
|
||||||
|
r.once.Do(r.build)
|
||||||
|
return r.rx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) build() {
|
||||||
|
r.rx = regexp.MustCompile(r.str)
|
||||||
|
r.str = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) FindSubmatch(s []byte) [][]byte {
|
||||||
|
return r.re().FindSubmatch(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) FindStringSubmatch(s string) []string {
|
||||||
|
return r.re().FindStringSubmatch(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) FindStringSubmatchIndex(s string) []int {
|
||||||
|
return r.re().FindStringSubmatchIndex(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) ReplaceAllString(src, repl string) string {
|
||||||
|
return r.re().ReplaceAllString(src, repl)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) FindString(s string) string {
|
||||||
|
return r.re().FindString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) FindAllString(s string, n int) []string {
|
||||||
|
return r.re().FindAllString(s, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) MatchString(s string) bool {
|
||||||
|
return r.re().MatchString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Regexp) SubexpNames() []string {
|
||||||
|
return r.re().SubexpNames()
|
||||||
|
}
|
||||||
|
|
||||||
|
var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
|
||||||
|
|
||||||
|
// New creates a new lazy regexp, delaying the compiling work until it is first
|
||||||
|
// needed. If the code is being run as part of tests, the regexp compiling will
|
||||||
|
// happen immediately.
|
||||||
|
func New(str string) *Regexp {
|
||||||
|
lr := &Regexp{str: str}
|
||||||
|
if inTest {
|
||||||
|
// In tests, always compile the regexps early.
|
||||||
|
lr.re()
|
||||||
|
}
|
||||||
|
return lr
|
||||||
|
}
|
|
@ -15,7 +15,7 @@
|
||||||
// but additional checking functions, most notably Check, verify that
|
// but additional checking functions, most notably Check, verify that
|
||||||
// a particular path, version pair is valid.
|
// a particular path, version pair is valid.
|
||||||
//
|
//
|
||||||
// Escaped Paths
|
// # Escaped Paths
|
||||||
//
|
//
|
||||||
// Module paths appear as substrings of file system paths
|
// Module paths appear as substrings of file system paths
|
||||||
// (in the download cache) and of web server URLs in the proxy protocol.
|
// (in the download cache) and of web server URLs in the proxy protocol.
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
// Import paths have never allowed exclamation marks, so there is no
|
// Import paths have never allowed exclamation marks, so there is no
|
||||||
// need to define how to escape a literal !.
|
// need to define how to escape a literal !.
|
||||||
//
|
//
|
||||||
// Unicode Restrictions
|
// # Unicode Restrictions
|
||||||
//
|
//
|
||||||
// Today, paths are disallowed from using Unicode.
|
// Today, paths are disallowed from using Unicode.
|
||||||
//
|
//
|
||||||
|
@ -102,9 +102,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
errors "golang.org/x/xerrors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Version (for clients, a module.Version) is defined by a module path and version pair.
|
// A Version (for clients, a module.Version) is defined by a module path and version pair.
|
||||||
|
@ -192,6 +192,21 @@ func (e *InvalidVersionError) Error() string {
|
||||||
|
|
||||||
func (e *InvalidVersionError) Unwrap() error { return e.Err }
|
func (e *InvalidVersionError) Unwrap() error { return e.Err }
|
||||||
|
|
||||||
|
// An InvalidPathError indicates a module, import, or file path doesn't
|
||||||
|
// satisfy all naming constraints. See CheckPath, CheckImportPath,
|
||||||
|
// and CheckFilePath for specific restrictions.
|
||||||
|
type InvalidPathError struct {
|
||||||
|
Kind string // "module", "import", or "file"
|
||||||
|
Path string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *InvalidPathError) Error() string {
|
||||||
|
return fmt.Sprintf("malformed %s path %q: %v", e.Kind, e.Path, e.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *InvalidPathError) Unwrap() error { return e.Err }
|
||||||
|
|
||||||
// Check checks that a given module path, version pair is valid.
|
// Check checks that a given module path, version pair is valid.
|
||||||
// In addition to the path being a valid module path
|
// In addition to the path being a valid module path
|
||||||
// and the version being a valid semantic version,
|
// and the version being a valid semantic version,
|
||||||
|
@ -271,12 +286,7 @@ func fileNameOK(r rune) bool {
|
||||||
if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' {
|
if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for i := 0; i < len(allowed); i++ {
|
return strings.ContainsRune(allowed, r)
|
||||||
if rune(allowed[i]) == r {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
// It may be OK to add more ASCII punctuation here, but only carefully.
|
// It may be OK to add more ASCII punctuation here, but only carefully.
|
||||||
// For example Windows disallows < > \, and macOS disallows :, so we must not allow those.
|
// For example Windows disallows < > \, and macOS disallows :, so we must not allow those.
|
||||||
|
@ -296,30 +306,36 @@ func fileNameOK(r rune) bool {
|
||||||
// this second requirement is replaced by a requirement that the path
|
// this second requirement is replaced by a requirement that the path
|
||||||
// follow the gopkg.in server's conventions.
|
// follow the gopkg.in server's conventions.
|
||||||
// Third, no path element may begin with a dot.
|
// Third, no path element may begin with a dot.
|
||||||
func CheckPath(path string) error {
|
func CheckPath(path string) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
err = &InvalidPathError{Kind: "module", Path: path, Err: err}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if err := checkPath(path, modulePath); err != nil {
|
if err := checkPath(path, modulePath); err != nil {
|
||||||
return fmt.Errorf("malformed module path %q: %v", path, err)
|
return err
|
||||||
}
|
}
|
||||||
i := strings.Index(path, "/")
|
i := strings.Index(path, "/")
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
i = len(path)
|
i = len(path)
|
||||||
}
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return fmt.Errorf("malformed module path %q: leading slash", path)
|
return fmt.Errorf("leading slash")
|
||||||
}
|
}
|
||||||
if !strings.Contains(path[:i], ".") {
|
if !strings.Contains(path[:i], ".") {
|
||||||
return fmt.Errorf("malformed module path %q: missing dot in first path element", path)
|
return fmt.Errorf("missing dot in first path element")
|
||||||
}
|
}
|
||||||
if path[0] == '-' {
|
if path[0] == '-' {
|
||||||
return fmt.Errorf("malformed module path %q: leading dash in first path element", path)
|
return fmt.Errorf("leading dash in first path element")
|
||||||
}
|
}
|
||||||
for _, r := range path[:i] {
|
for _, r := range path[:i] {
|
||||||
if !firstPathOK(r) {
|
if !firstPathOK(r) {
|
||||||
return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r)
|
return fmt.Errorf("invalid char %q in first path element", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, _, ok := SplitPathVersion(path); !ok {
|
if _, _, ok := SplitPathVersion(path); !ok {
|
||||||
return fmt.Errorf("malformed module path %q: invalid version", path)
|
return fmt.Errorf("invalid version")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -343,7 +359,7 @@ func CheckPath(path string) error {
|
||||||
// subtleties of Unicode.
|
// subtleties of Unicode.
|
||||||
func CheckImportPath(path string) error {
|
func CheckImportPath(path string) error {
|
||||||
if err := checkPath(path, importPath); err != nil {
|
if err := checkPath(path, importPath); err != nil {
|
||||||
return fmt.Errorf("malformed import path %q: %v", path, err)
|
return &InvalidPathError{Kind: "import", Path: path, Err: err}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -358,12 +374,13 @@ const (
|
||||||
filePath
|
filePath
|
||||||
)
|
)
|
||||||
|
|
||||||
// checkPath checks that a general path is valid.
|
// checkPath checks that a general path is valid. kind indicates what
|
||||||
// It returns an error describing why but not mentioning path.
|
// specific constraints should be applied.
|
||||||
// Because these checks apply to both module paths and import paths,
|
//
|
||||||
// the caller is expected to add the "malformed ___ path %q: " prefix.
|
// checkPath returns an error describing why the path is not valid.
|
||||||
// fileName indicates whether the final element of the path is a file name
|
// Because these checks apply to module, import, and file paths,
|
||||||
// (as opposed to a directory name).
|
// and because other checks may be applied, the caller is expected to wrap
|
||||||
|
// this error with InvalidPathError.
|
||||||
func checkPath(path string, kind pathKind) error {
|
func checkPath(path string, kind pathKind) error {
|
||||||
if !utf8.ValidString(path) {
|
if !utf8.ValidString(path) {
|
||||||
return fmt.Errorf("invalid UTF-8")
|
return fmt.Errorf("invalid UTF-8")
|
||||||
|
@ -371,7 +388,7 @@ func checkPath(path string, kind pathKind) error {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return fmt.Errorf("empty string")
|
return fmt.Errorf("empty string")
|
||||||
}
|
}
|
||||||
if path[0] == '-' {
|
if path[0] == '-' && kind != filePath {
|
||||||
return fmt.Errorf("leading dash")
|
return fmt.Errorf("leading dash")
|
||||||
}
|
}
|
||||||
if strings.Contains(path, "//") {
|
if strings.Contains(path, "//") {
|
||||||
|
@ -477,7 +494,7 @@ func checkElem(elem string, kind pathKind) error {
|
||||||
// subtleties of Unicode.
|
// subtleties of Unicode.
|
||||||
func CheckFilePath(path string) error {
|
func CheckFilePath(path string) error {
|
||||||
if err := checkPath(path, filePath); err != nil {
|
if err := checkPath(path, filePath); err != nil {
|
||||||
return fmt.Errorf("malformed file path %q: %v", path, err)
|
return &InvalidPathError{Kind: "file", Path: path, Err: err}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -781,6 +798,7 @@ func unescapeString(escaped string) (string, bool) {
|
||||||
// GOPRIVATE environment variable, as described by 'go help module-private'.
|
// GOPRIVATE environment variable, as described by 'go help module-private'.
|
||||||
//
|
//
|
||||||
// It ignores any empty or malformed patterns in the list.
|
// It ignores any empty or malformed patterns in the list.
|
||||||
|
// Trailing slashes on patterns are ignored.
|
||||||
func MatchPrefixPatterns(globs, target string) bool {
|
func MatchPrefixPatterns(globs, target string) bool {
|
||||||
for globs != "" {
|
for globs != "" {
|
||||||
// Extract next non-empty glob in comma-separated list.
|
// Extract next non-empty glob in comma-separated list.
|
||||||
|
@ -790,6 +808,7 @@ func MatchPrefixPatterns(globs, target string) bool {
|
||||||
} else {
|
} else {
|
||||||
glob, globs = globs, ""
|
glob, globs = globs, ""
|
||||||
}
|
}
|
||||||
|
glob = strings.TrimSuffix(glob, "/")
|
||||||
if glob == "" {
|
if glob == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// Pseudo-versions
|
||||||
|
//
|
||||||
|
// Code authors are expected to tag the revisions they want users to use,
|
||||||
|
// including prereleases. However, not all authors tag versions at all,
|
||||||
|
// and not all commits a user might want to try will have tags.
|
||||||
|
// A pseudo-version is a version with a special form that allows us to
|
||||||
|
// address an untagged commit and order that version with respect to
|
||||||
|
// other versions we might encounter.
|
||||||
|
//
|
||||||
|
// A pseudo-version takes one of the general forms:
|
||||||
|
//
|
||||||
|
// (1) vX.0.0-yyyymmddhhmmss-abcdef123456
|
||||||
|
// (2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456
|
||||||
|
// (3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible
|
||||||
|
// (4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456
|
||||||
|
// (5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible
|
||||||
|
//
|
||||||
|
// If there is no recently tagged version with the right major version vX,
|
||||||
|
// then form (1) is used, creating a space of pseudo-versions at the bottom
|
||||||
|
// of the vX version range, less than any tagged version, including the unlikely v0.0.0.
|
||||||
|
//
|
||||||
|
// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible,
|
||||||
|
// then the pseudo-version uses form (2) or (3), making it a prerelease for the next
|
||||||
|
// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string
|
||||||
|
// ensures that the pseudo-version compares less than possible future explicit prereleases
|
||||||
|
// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1.
|
||||||
|
//
|
||||||
|
// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible,
|
||||||
|
// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease.
|
||||||
|
|
||||||
|
package module
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/mod/internal/lazyregexp"
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`)
|
||||||
|
|
||||||
|
const PseudoVersionTimestampFormat = "20060102150405"
|
||||||
|
|
||||||
|
// PseudoVersion returns a pseudo-version for the given major version ("v1")
|
||||||
|
// preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time,
|
||||||
|
// and revision identifier (usually a 12-byte commit hash prefix).
|
||||||
|
func PseudoVersion(major, older string, t time.Time, rev string) string {
|
||||||
|
if major == "" {
|
||||||
|
major = "v0"
|
||||||
|
}
|
||||||
|
segment := fmt.Sprintf("%s-%s", t.UTC().Format(PseudoVersionTimestampFormat), rev)
|
||||||
|
build := semver.Build(older)
|
||||||
|
older = semver.Canonical(older)
|
||||||
|
if older == "" {
|
||||||
|
return major + ".0.0-" + segment // form (1)
|
||||||
|
}
|
||||||
|
if semver.Prerelease(older) != "" {
|
||||||
|
return older + ".0." + segment + build // form (4), (5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form (2), (3).
|
||||||
|
// Extract patch from vMAJOR.MINOR.PATCH
|
||||||
|
i := strings.LastIndex(older, ".") + 1
|
||||||
|
v, patch := older[:i], older[i:]
|
||||||
|
|
||||||
|
// Reassemble.
|
||||||
|
return v + incDecimal(patch) + "-0." + segment + build
|
||||||
|
}
|
||||||
|
|
||||||
|
// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and
|
||||||
|
// revision, which may be used as a placeholder.
|
||||||
|
func ZeroPseudoVersion(major string) string {
|
||||||
|
return PseudoVersion(major, "", time.Time{}, "000000000000")
|
||||||
|
}
|
||||||
|
|
||||||
|
// incDecimal returns the decimal string incremented by 1.
|
||||||
|
func incDecimal(decimal string) string {
|
||||||
|
// Scan right to left turning 9s to 0s until you find a digit to increment.
|
||||||
|
digits := []byte(decimal)
|
||||||
|
i := len(digits) - 1
|
||||||
|
for ; i >= 0 && digits[i] == '9'; i-- {
|
||||||
|
digits[i] = '0'
|
||||||
|
}
|
||||||
|
if i >= 0 {
|
||||||
|
digits[i]++
|
||||||
|
} else {
|
||||||
|
// digits is all zeros
|
||||||
|
digits[0] = '1'
|
||||||
|
digits = append(digits, '0')
|
||||||
|
}
|
||||||
|
return string(digits)
|
||||||
|
}
|
||||||
|
|
||||||
|
// decDecimal returns the decimal string decremented by 1, or the empty string
|
||||||
|
// if the decimal is all zeroes.
|
||||||
|
func decDecimal(decimal string) string {
|
||||||
|
// Scan right to left turning 0s to 9s until you find a digit to decrement.
|
||||||
|
digits := []byte(decimal)
|
||||||
|
i := len(digits) - 1
|
||||||
|
for ; i >= 0 && digits[i] == '0'; i-- {
|
||||||
|
digits[i] = '9'
|
||||||
|
}
|
||||||
|
if i < 0 {
|
||||||
|
// decimal is all zeros
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if i == 0 && digits[i] == '1' && len(digits) > 1 {
|
||||||
|
digits = digits[1:]
|
||||||
|
} else {
|
||||||
|
digits[i]--
|
||||||
|
}
|
||||||
|
return string(digits)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPseudoVersion reports whether v is a pseudo-version.
|
||||||
|
func IsPseudoVersion(v string) bool {
|
||||||
|
return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base,
|
||||||
|
// timestamp, and revision, as returned by ZeroPseudoVersion.
|
||||||
|
func IsZeroPseudoVersion(v string) bool {
|
||||||
|
return v == ZeroPseudoVersion(semver.Major(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PseudoVersionTime returns the time stamp of the pseudo-version v.
|
||||||
|
// It returns an error if v is not a pseudo-version or if the time stamp
|
||||||
|
// embedded in the pseudo-version is not a valid time.
|
||||||
|
func PseudoVersionTime(v string) (time.Time, error) {
|
||||||
|
_, timestamp, _, _, err := parsePseudoVersion(v)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
t, err := time.Parse("20060102150405", timestamp)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, &InvalidVersionError{
|
||||||
|
Version: v,
|
||||||
|
Pseudo: true,
|
||||||
|
Err: fmt.Errorf("malformed time %q", timestamp),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PseudoVersionRev returns the revision identifier of the pseudo-version v.
|
||||||
|
// It returns an error if v is not a pseudo-version.
|
||||||
|
func PseudoVersionRev(v string) (rev string, err error) {
|
||||||
|
_, _, rev, _, err = parsePseudoVersion(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// PseudoVersionBase returns the canonical parent version, if any, upon which
|
||||||
|
// the pseudo-version v is based.
|
||||||
|
//
|
||||||
|
// If v has no parent version (that is, if it is "vX.0.0-[…]"),
|
||||||
|
// PseudoVersionBase returns the empty string and a nil error.
|
||||||
|
func PseudoVersionBase(v string) (string, error) {
|
||||||
|
base, _, _, build, err := parsePseudoVersion(v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pre := semver.Prerelease(base); pre {
|
||||||
|
case "":
|
||||||
|
// vX.0.0-yyyymmddhhmmss-abcdef123456 → ""
|
||||||
|
if build != "" {
|
||||||
|
// Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible
|
||||||
|
// are nonsensical: the "vX.0.0-" prefix implies that there is no parent tag,
|
||||||
|
// but the "+incompatible" suffix implies that the major version of
|
||||||
|
// the parent tag is not compatible with the module's import path.
|
||||||
|
//
|
||||||
|
// There are a few such entries in the index generated by proxy.golang.org,
|
||||||
|
// but we believe those entries were generated by the proxy itself.
|
||||||
|
return "", &InvalidVersionError{
|
||||||
|
Version: v,
|
||||||
|
Pseudo: true,
|
||||||
|
Err: fmt.Errorf("lacks base version, but has build metadata %q", build),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
|
||||||
|
case "-0":
|
||||||
|
// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z
|
||||||
|
// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible
|
||||||
|
base = strings.TrimSuffix(base, pre)
|
||||||
|
i := strings.LastIndexByte(base, '.')
|
||||||
|
if i < 0 {
|
||||||
|
panic("base from parsePseudoVersion missing patch number: " + base)
|
||||||
|
}
|
||||||
|
patch := decDecimal(base[i+1:])
|
||||||
|
if patch == "" {
|
||||||
|
// vX.0.0-0 is invalid, but has been observed in the wild in the index
|
||||||
|
// generated by requests to proxy.golang.org.
|
||||||
|
//
|
||||||
|
// NOTE(bcmills): I cannot find a historical bug that accounts for
|
||||||
|
// pseudo-versions of this form, nor have I seen such versions in any
|
||||||
|
// actual go.mod files. If we find actual examples of this form and a
|
||||||
|
// reasonable theory of how they came into existence, it seems fine to
|
||||||
|
// treat them as equivalent to vX.0.0 (especially since the invalid
|
||||||
|
// pseudo-versions have lower precedence than the real ones). For now, we
|
||||||
|
// reject them.
|
||||||
|
return "", &InvalidVersionError{
|
||||||
|
Version: v,
|
||||||
|
Pseudo: true,
|
||||||
|
Err: fmt.Errorf("version before %s would have negative patch number", base),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base[:i+1] + patch + build, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre
|
||||||
|
// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible
|
||||||
|
if !strings.HasSuffix(base, ".0") {
|
||||||
|
panic(`base from parsePseudoVersion missing ".0" before date: ` + base)
|
||||||
|
}
|
||||||
|
return strings.TrimSuffix(base, ".0") + build, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var errPseudoSyntax = errors.New("syntax error")
|
||||||
|
|
||||||
|
func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) {
|
||||||
|
if !IsPseudoVersion(v) {
|
||||||
|
return "", "", "", "", &InvalidVersionError{
|
||||||
|
Version: v,
|
||||||
|
Pseudo: true,
|
||||||
|
Err: errPseudoSyntax,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build = semver.Build(v)
|
||||||
|
v = strings.TrimSuffix(v, build)
|
||||||
|
j := strings.LastIndex(v, "-")
|
||||||
|
v, rev = v[:j], v[j+1:]
|
||||||
|
i := strings.LastIndex(v, "-")
|
||||||
|
if j := strings.LastIndex(v, "."); j > i {
|
||||||
|
base = v[:j] // "vX.Y.Z-pre.0" or "vX.Y.(Z+1)-0"
|
||||||
|
timestamp = v[j+1:]
|
||||||
|
} else {
|
||||||
|
base = v[:i] // "vX.0.0"
|
||||||
|
timestamp = v[i+1:]
|
||||||
|
}
|
||||||
|
return base, timestamp, rev, build, nil
|
||||||
|
}
|
|
@ -22,6 +22,8 @@
|
||||||
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
|
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
|
||||||
package semver
|
package semver
|
||||||
|
|
||||||
|
import "sort"
|
||||||
|
|
||||||
// parsed returns the parsed form of a semantic version string.
|
// parsed returns the parsed form of a semantic version string.
|
||||||
type parsed struct {
|
type parsed struct {
|
||||||
major string
|
major string
|
||||||
|
@ -30,7 +32,6 @@ type parsed struct {
|
||||||
short string
|
short string
|
||||||
prerelease string
|
prerelease string
|
||||||
build string
|
build string
|
||||||
err string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid reports whether v is a valid semantic version string.
|
// IsValid reports whether v is a valid semantic version string.
|
||||||
|
@ -150,14 +151,30 @@ func Max(v, w string) string {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByVersion implements sort.Interface for sorting semantic version strings.
|
||||||
|
type ByVersion []string
|
||||||
|
|
||||||
|
func (vs ByVersion) Len() int { return len(vs) }
|
||||||
|
func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
|
||||||
|
func (vs ByVersion) Less(i, j int) bool {
|
||||||
|
cmp := Compare(vs[i], vs[j])
|
||||||
|
if cmp != 0 {
|
||||||
|
return cmp < 0
|
||||||
|
}
|
||||||
|
return vs[i] < vs[j]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sorts a list of semantic version strings using ByVersion.
|
||||||
|
func Sort(list []string) {
|
||||||
|
sort.Sort(ByVersion(list))
|
||||||
|
}
|
||||||
|
|
||||||
func parse(v string) (p parsed, ok bool) {
|
func parse(v string) (p parsed, ok bool) {
|
||||||
if v == "" || v[0] != 'v' {
|
if v == "" || v[0] != 'v' {
|
||||||
p.err = "missing v prefix"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.major, v, ok = parseInt(v[1:])
|
p.major, v, ok = parseInt(v[1:])
|
||||||
if !ok {
|
if !ok {
|
||||||
p.err = "bad major version"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v == "" {
|
if v == "" {
|
||||||
|
@ -167,13 +184,11 @@ func parse(v string) (p parsed, ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v[0] != '.' {
|
if v[0] != '.' {
|
||||||
p.err = "bad minor prefix"
|
|
||||||
ok = false
|
ok = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.minor, v, ok = parseInt(v[1:])
|
p.minor, v, ok = parseInt(v[1:])
|
||||||
if !ok {
|
if !ok {
|
||||||
p.err = "bad minor version"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v == "" {
|
if v == "" {
|
||||||
|
@ -182,31 +197,26 @@ func parse(v string) (p parsed, ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v[0] != '.' {
|
if v[0] != '.' {
|
||||||
p.err = "bad patch prefix"
|
|
||||||
ok = false
|
ok = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.patch, v, ok = parseInt(v[1:])
|
p.patch, v, ok = parseInt(v[1:])
|
||||||
if !ok {
|
if !ok {
|
||||||
p.err = "bad patch version"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(v) > 0 && v[0] == '-' {
|
if len(v) > 0 && v[0] == '-' {
|
||||||
p.prerelease, v, ok = parsePrerelease(v)
|
p.prerelease, v, ok = parsePrerelease(v)
|
||||||
if !ok {
|
if !ok {
|
||||||
p.err = "bad prerelease"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(v) > 0 && v[0] == '+' {
|
if len(v) > 0 && v[0] == '+' {
|
||||||
p.build, v, ok = parseBuild(v)
|
p.build, v, ok = parseBuild(v)
|
||||||
if !ok {
|
if !ok {
|
||||||
p.err = "bad build"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v != "" {
|
if v != "" {
|
||||||
p.err = "junk on end"
|
|
||||||
ok = false
|
ok = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,14 @@ func buildCommonHeaderMaps() {
|
||||||
"accept-language",
|
"accept-language",
|
||||||
"accept-ranges",
|
"accept-ranges",
|
||||||
"age",
|
"age",
|
||||||
|
"access-control-allow-credentials",
|
||||||
|
"access-control-allow-headers",
|
||||||
|
"access-control-allow-methods",
|
||||||
"access-control-allow-origin",
|
"access-control-allow-origin",
|
||||||
|
"access-control-expose-headers",
|
||||||
|
"access-control-max-age",
|
||||||
|
"access-control-request-headers",
|
||||||
|
"access-control-request-method",
|
||||||
"allow",
|
"allow",
|
||||||
"authorization",
|
"authorization",
|
||||||
"cache-control",
|
"cache-control",
|
||||||
|
@ -53,6 +60,7 @@ func buildCommonHeaderMaps() {
|
||||||
"link",
|
"link",
|
||||||
"location",
|
"location",
|
||||||
"max-forwards",
|
"max-forwards",
|
||||||
|
"origin",
|
||||||
"proxy-authenticate",
|
"proxy-authenticate",
|
||||||
"proxy-authorization",
|
"proxy-authorization",
|
||||||
"range",
|
"range",
|
||||||
|
@ -68,6 +76,8 @@ func buildCommonHeaderMaps() {
|
||||||
"vary",
|
"vary",
|
||||||
"via",
|
"via",
|
||||||
"www-authenticate",
|
"www-authenticate",
|
||||||
|
"x-forwarded-for",
|
||||||
|
"x-forwarded-proto",
|
||||||
}
|
}
|
||||||
commonLowerHeader = make(map[string]string, len(common))
|
commonLowerHeader = make(map[string]string, len(common))
|
||||||
commonCanonHeader = make(map[string]string, len(common))
|
commonCanonHeader = make(map[string]string, len(common))
|
||||||
|
@ -85,3 +95,11 @@ func lowerHeader(v string) (lower string, ascii bool) {
|
||||||
}
|
}
|
||||||
return asciiToLower(v)
|
return asciiToLower(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canonicalHeader(v string) string {
|
||||||
|
buildCommonHeaderMapsOnce()
|
||||||
|
if s, ok := commonCanonHeader[v]; ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return http.CanonicalHeaderKey(v)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
// go generate gen.go
|
||||||
|
// Code generated by the command above; DO NOT EDIT.
|
||||||
|
|
||||||
|
package hpack
|
||||||
|
|
||||||
|
var staticTable = &headerFieldTable{
|
||||||
|
evictCount: 0,
|
||||||
|
byName: map[string]uint64{
|
||||||
|
":authority": 1,
|
||||||
|
":method": 3,
|
||||||
|
":path": 5,
|
||||||
|
":scheme": 7,
|
||||||
|
":status": 14,
|
||||||
|
"accept-charset": 15,
|
||||||
|
"accept-encoding": 16,
|
||||||
|
"accept-language": 17,
|
||||||
|
"accept-ranges": 18,
|
||||||
|
"accept": 19,
|
||||||
|
"access-control-allow-origin": 20,
|
||||||
|
"age": 21,
|
||||||
|
"allow": 22,
|
||||||
|
"authorization": 23,
|
||||||
|
"cache-control": 24,
|
||||||
|
"content-disposition": 25,
|
||||||
|
"content-encoding": 26,
|
||||||
|
"content-language": 27,
|
||||||
|
"content-length": 28,
|
||||||
|
"content-location": 29,
|
||||||
|
"content-range": 30,
|
||||||
|
"content-type": 31,
|
||||||
|
"cookie": 32,
|
||||||
|
"date": 33,
|
||||||
|
"etag": 34,
|
||||||
|
"expect": 35,
|
||||||
|
"expires": 36,
|
||||||
|
"from": 37,
|
||||||
|
"host": 38,
|
||||||
|
"if-match": 39,
|
||||||
|
"if-modified-since": 40,
|
||||||
|
"if-none-match": 41,
|
||||||
|
"if-range": 42,
|
||||||
|
"if-unmodified-since": 43,
|
||||||
|
"last-modified": 44,
|
||||||
|
"link": 45,
|
||||||
|
"location": 46,
|
||||||
|
"max-forwards": 47,
|
||||||
|
"proxy-authenticate": 48,
|
||||||
|
"proxy-authorization": 49,
|
||||||
|
"range": 50,
|
||||||
|
"referer": 51,
|
||||||
|
"refresh": 52,
|
||||||
|
"retry-after": 53,
|
||||||
|
"server": 54,
|
||||||
|
"set-cookie": 55,
|
||||||
|
"strict-transport-security": 56,
|
||||||
|
"transfer-encoding": 57,
|
||||||
|
"user-agent": 58,
|
||||||
|
"vary": 59,
|
||||||
|
"via": 60,
|
||||||
|
"www-authenticate": 61,
|
||||||
|
},
|
||||||
|
byNameValue: map[pairNameValue]uint64{
|
||||||
|
{name: ":authority", value: ""}: 1,
|
||||||
|
{name: ":method", value: "GET"}: 2,
|
||||||
|
{name: ":method", value: "POST"}: 3,
|
||||||
|
{name: ":path", value: "/"}: 4,
|
||||||
|
{name: ":path", value: "/index.html"}: 5,
|
||||||
|
{name: ":scheme", value: "http"}: 6,
|
||||||
|
{name: ":scheme", value: "https"}: 7,
|
||||||
|
{name: ":status", value: "200"}: 8,
|
||||||
|
{name: ":status", value: "204"}: 9,
|
||||||
|
{name: ":status", value: "206"}: 10,
|
||||||
|
{name: ":status", value: "304"}: 11,
|
||||||
|
{name: ":status", value: "400"}: 12,
|
||||||
|
{name: ":status", value: "404"}: 13,
|
||||||
|
{name: ":status", value: "500"}: 14,
|
||||||
|
{name: "accept-charset", value: ""}: 15,
|
||||||
|
{name: "accept-encoding", value: "gzip, deflate"}: 16,
|
||||||
|
{name: "accept-language", value: ""}: 17,
|
||||||
|
{name: "accept-ranges", value: ""}: 18,
|
||||||
|
{name: "accept", value: ""}: 19,
|
||||||
|
{name: "access-control-allow-origin", value: ""}: 20,
|
||||||
|
{name: "age", value: ""}: 21,
|
||||||
|
{name: "allow", value: ""}: 22,
|
||||||
|
{name: "authorization", value: ""}: 23,
|
||||||
|
{name: "cache-control", value: ""}: 24,
|
||||||
|
{name: "content-disposition", value: ""}: 25,
|
||||||
|
{name: "content-encoding", value: ""}: 26,
|
||||||
|
{name: "content-language", value: ""}: 27,
|
||||||
|
{name: "content-length", value: ""}: 28,
|
||||||
|
{name: "content-location", value: ""}: 29,
|
||||||
|
{name: "content-range", value: ""}: 30,
|
||||||
|
{name: "content-type", value: ""}: 31,
|
||||||
|
{name: "cookie", value: ""}: 32,
|
||||||
|
{name: "date", value: ""}: 33,
|
||||||
|
{name: "etag", value: ""}: 34,
|
||||||
|
{name: "expect", value: ""}: 35,
|
||||||
|
{name: "expires", value: ""}: 36,
|
||||||
|
{name: "from", value: ""}: 37,
|
||||||
|
{name: "host", value: ""}: 38,
|
||||||
|
{name: "if-match", value: ""}: 39,
|
||||||
|
{name: "if-modified-since", value: ""}: 40,
|
||||||
|
{name: "if-none-match", value: ""}: 41,
|
||||||
|
{name: "if-range", value: ""}: 42,
|
||||||
|
{name: "if-unmodified-since", value: ""}: 43,
|
||||||
|
{name: "last-modified", value: ""}: 44,
|
||||||
|
{name: "link", value: ""}: 45,
|
||||||
|
{name: "location", value: ""}: 46,
|
||||||
|
{name: "max-forwards", value: ""}: 47,
|
||||||
|
{name: "proxy-authenticate", value: ""}: 48,
|
||||||
|
{name: "proxy-authorization", value: ""}: 49,
|
||||||
|
{name: "range", value: ""}: 50,
|
||||||
|
{name: "referer", value: ""}: 51,
|
||||||
|
{name: "refresh", value: ""}: 52,
|
||||||
|
{name: "retry-after", value: ""}: 53,
|
||||||
|
{name: "server", value: ""}: 54,
|
||||||
|
{name: "set-cookie", value: ""}: 55,
|
||||||
|
{name: "strict-transport-security", value: ""}: 56,
|
||||||
|
{name: "transfer-encoding", value: ""}: 57,
|
||||||
|
{name: "user-agent", value: ""}: 58,
|
||||||
|
{name: "vary", value: ""}: 59,
|
||||||
|
{name: "via", value: ""}: 60,
|
||||||
|
{name: "www-authenticate", value: ""}: 61,
|
||||||
|
},
|
||||||
|
ents: []HeaderField{
|
||||||
|
{Name: ":authority", Value: "", Sensitive: false},
|
||||||
|
{Name: ":method", Value: "GET", Sensitive: false},
|
||||||
|
{Name: ":method", Value: "POST", Sensitive: false},
|
||||||
|
{Name: ":path", Value: "/", Sensitive: false},
|
||||||
|
{Name: ":path", Value: "/index.html", Sensitive: false},
|
||||||
|
{Name: ":scheme", Value: "http", Sensitive: false},
|
||||||
|
{Name: ":scheme", Value: "https", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "200", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "204", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "206", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "304", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "400", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "404", Sensitive: false},
|
||||||
|
{Name: ":status", Value: "500", Sensitive: false},
|
||||||
|
{Name: "accept-charset", Value: "", Sensitive: false},
|
||||||
|
{Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false},
|
||||||
|
{Name: "accept-language", Value: "", Sensitive: false},
|
||||||
|
{Name: "accept-ranges", Value: "", Sensitive: false},
|
||||||
|
{Name: "accept", Value: "", Sensitive: false},
|
||||||
|
{Name: "access-control-allow-origin", Value: "", Sensitive: false},
|
||||||
|
{Name: "age", Value: "", Sensitive: false},
|
||||||
|
{Name: "allow", Value: "", Sensitive: false},
|
||||||
|
{Name: "authorization", Value: "", Sensitive: false},
|
||||||
|
{Name: "cache-control", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-disposition", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-encoding", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-language", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-length", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-location", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-range", Value: "", Sensitive: false},
|
||||||
|
{Name: "content-type", Value: "", Sensitive: false},
|
||||||
|
{Name: "cookie", Value: "", Sensitive: false},
|
||||||
|
{Name: "date", Value: "", Sensitive: false},
|
||||||
|
{Name: "etag", Value: "", Sensitive: false},
|
||||||
|
{Name: "expect", Value: "", Sensitive: false},
|
||||||
|
{Name: "expires", Value: "", Sensitive: false},
|
||||||
|
{Name: "from", Value: "", Sensitive: false},
|
||||||
|
{Name: "host", Value: "", Sensitive: false},
|
||||||
|
{Name: "if-match", Value: "", Sensitive: false},
|
||||||
|
{Name: "if-modified-since", Value: "", Sensitive: false},
|
||||||
|
{Name: "if-none-match", Value: "", Sensitive: false},
|
||||||
|
{Name: "if-range", Value: "", Sensitive: false},
|
||||||
|
{Name: "if-unmodified-since", Value: "", Sensitive: false},
|
||||||
|
{Name: "last-modified", Value: "", Sensitive: false},
|
||||||
|
{Name: "link", Value: "", Sensitive: false},
|
||||||
|
{Name: "location", Value: "", Sensitive: false},
|
||||||
|
{Name: "max-forwards", Value: "", Sensitive: false},
|
||||||
|
{Name: "proxy-authenticate", Value: "", Sensitive: false},
|
||||||
|
{Name: "proxy-authorization", Value: "", Sensitive: false},
|
||||||
|
{Name: "range", Value: "", Sensitive: false},
|
||||||
|
{Name: "referer", Value: "", Sensitive: false},
|
||||||
|
{Name: "refresh", Value: "", Sensitive: false},
|
||||||
|
{Name: "retry-after", Value: "", Sensitive: false},
|
||||||
|
{Name: "server", Value: "", Sensitive: false},
|
||||||
|
{Name: "set-cookie", Value: "", Sensitive: false},
|
||||||
|
{Name: "strict-transport-security", Value: "", Sensitive: false},
|
||||||
|
{Name: "transfer-encoding", Value: "", Sensitive: false},
|
||||||
|
{Name: "user-agent", Value: "", Sensitive: false},
|
||||||
|
{Name: "vary", Value: "", Sensitive: false},
|
||||||
|
{Name: "via", Value: "", Sensitive: false},
|
||||||
|
{Name: "www-authenticate", Value: "", Sensitive: false},
|
||||||
|
},
|
||||||
|
}
|
|
@ -96,8 +96,7 @@ func (t *headerFieldTable) evictOldest(n int) {
|
||||||
// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
|
// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
|
||||||
// table, the return value i actually refers to the entry t.ents[t.len()-i].
|
// table, the return value i actually refers to the entry t.ents[t.len()-i].
|
||||||
//
|
//
|
||||||
// All tables are assumed to be a dynamic tables except for the global
|
// All tables are assumed to be a dynamic tables except for the global staticTable.
|
||||||
// staticTable pointer.
|
|
||||||
//
|
//
|
||||||
// See Section 2.3.3.
|
// See Section 2.3.3.
|
||||||
func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
|
func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
|
||||||
|
@ -125,81 +124,6 @@ func (t *headerFieldTable) idToIndex(id uint64) uint64 {
|
||||||
return k + 1
|
return k + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
|
|
||||||
var staticTable = newStaticTable()
|
|
||||||
var staticTableEntries = [...]HeaderField{
|
|
||||||
{Name: ":authority"},
|
|
||||||
{Name: ":method", Value: "GET"},
|
|
||||||
{Name: ":method", Value: "POST"},
|
|
||||||
{Name: ":path", Value: "/"},
|
|
||||||
{Name: ":path", Value: "/index.html"},
|
|
||||||
{Name: ":scheme", Value: "http"},
|
|
||||||
{Name: ":scheme", Value: "https"},
|
|
||||||
{Name: ":status", Value: "200"},
|
|
||||||
{Name: ":status", Value: "204"},
|
|
||||||
{Name: ":status", Value: "206"},
|
|
||||||
{Name: ":status", Value: "304"},
|
|
||||||
{Name: ":status", Value: "400"},
|
|
||||||
{Name: ":status", Value: "404"},
|
|
||||||
{Name: ":status", Value: "500"},
|
|
||||||
{Name: "accept-charset"},
|
|
||||||
{Name: "accept-encoding", Value: "gzip, deflate"},
|
|
||||||
{Name: "accept-language"},
|
|
||||||
{Name: "accept-ranges"},
|
|
||||||
{Name: "accept"},
|
|
||||||
{Name: "access-control-allow-origin"},
|
|
||||||
{Name: "age"},
|
|
||||||
{Name: "allow"},
|
|
||||||
{Name: "authorization"},
|
|
||||||
{Name: "cache-control"},
|
|
||||||
{Name: "content-disposition"},
|
|
||||||
{Name: "content-encoding"},
|
|
||||||
{Name: "content-language"},
|
|
||||||
{Name: "content-length"},
|
|
||||||
{Name: "content-location"},
|
|
||||||
{Name: "content-range"},
|
|
||||||
{Name: "content-type"},
|
|
||||||
{Name: "cookie"},
|
|
||||||
{Name: "date"},
|
|
||||||
{Name: "etag"},
|
|
||||||
{Name: "expect"},
|
|
||||||
{Name: "expires"},
|
|
||||||
{Name: "from"},
|
|
||||||
{Name: "host"},
|
|
||||||
{Name: "if-match"},
|
|
||||||
{Name: "if-modified-since"},
|
|
||||||
{Name: "if-none-match"},
|
|
||||||
{Name: "if-range"},
|
|
||||||
{Name: "if-unmodified-since"},
|
|
||||||
{Name: "last-modified"},
|
|
||||||
{Name: "link"},
|
|
||||||
{Name: "location"},
|
|
||||||
{Name: "max-forwards"},
|
|
||||||
{Name: "proxy-authenticate"},
|
|
||||||
{Name: "proxy-authorization"},
|
|
||||||
{Name: "range"},
|
|
||||||
{Name: "referer"},
|
|
||||||
{Name: "refresh"},
|
|
||||||
{Name: "retry-after"},
|
|
||||||
{Name: "server"},
|
|
||||||
{Name: "set-cookie"},
|
|
||||||
{Name: "strict-transport-security"},
|
|
||||||
{Name: "transfer-encoding"},
|
|
||||||
{Name: "user-agent"},
|
|
||||||
{Name: "vary"},
|
|
||||||
{Name: "via"},
|
|
||||||
{Name: "www-authenticate"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStaticTable() *headerFieldTable {
|
|
||||||
t := &headerFieldTable{}
|
|
||||||
t.init()
|
|
||||||
for _, e := range staticTableEntries[:] {
|
|
||||||
t.addEntry(e)
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
var huffmanCodes = [256]uint32{
|
var huffmanCodes = [256]uint32{
|
||||||
0x1ff8,
|
0x1ff8,
|
||||||
0x7fffd8,
|
0x7fffd8,
|
||||||
|
|
|
@ -143,7 +143,7 @@ type Server struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) initialConnRecvWindowSize() int32 {
|
func (s *Server) initialConnRecvWindowSize() int32 {
|
||||||
if s.MaxUploadBufferPerConnection > initialWindowSize {
|
if s.MaxUploadBufferPerConnection >= initialWindowSize {
|
||||||
return s.MaxUploadBufferPerConnection
|
return s.MaxUploadBufferPerConnection
|
||||||
}
|
}
|
||||||
return 1 << 20
|
return 1 << 20
|
||||||
|
@ -622,7 +622,9 @@ type stream struct {
|
||||||
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
|
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
|
||||||
gotTrailerHeader bool // HEADER frame for trailers was seen
|
gotTrailerHeader bool // HEADER frame for trailers was seen
|
||||||
wroteHeaders bool // whether we wrote headers (not status 100)
|
wroteHeaders bool // whether we wrote headers (not status 100)
|
||||||
|
readDeadline *time.Timer // nil if unused
|
||||||
writeDeadline *time.Timer // nil if unused
|
writeDeadline *time.Timer // nil if unused
|
||||||
|
closeErr error // set before cw is closed
|
||||||
|
|
||||||
trailer http.Header // accumulated trailers
|
trailer http.Header // accumulated trailers
|
||||||
reqTrailer http.Header // handler's Request.Trailer
|
reqTrailer http.Header // handler's Request.Trailer
|
||||||
|
@ -948,6 +950,8 @@ func (sc *serverConn) serve() {
|
||||||
}
|
}
|
||||||
case *startPushRequest:
|
case *startPushRequest:
|
||||||
sc.startPush(v)
|
sc.startPush(v)
|
||||||
|
case func(*serverConn):
|
||||||
|
v(sc)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unexpected type %T", v))
|
panic(fmt.Sprintf("unexpected type %T", v))
|
||||||
}
|
}
|
||||||
|
@ -1461,6 +1465,21 @@ func (sc *serverConn) processFrame(f Frame) error {
|
||||||
sc.sawFirstSettings = true
|
sc.sawFirstSettings = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Discard frames for streams initiated after the identified last
|
||||||
|
// stream sent in a GOAWAY, or all frames after sending an error.
|
||||||
|
// We still need to return connection-level flow control for DATA frames.
|
||||||
|
// RFC 9113 Section 6.8.
|
||||||
|
if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {
|
||||||
|
|
||||||
|
if f, ok := f.(*DataFrame); ok {
|
||||||
|
if sc.inflow.available() < int32(f.Length) {
|
||||||
|
return sc.countError("data_flow", streamError(f.Header().StreamID, ErrCodeFlowControl))
|
||||||
|
}
|
||||||
|
sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
switch f := f.(type) {
|
switch f := f.(type) {
|
||||||
case *SettingsFrame:
|
case *SettingsFrame:
|
||||||
return sc.processSettings(f)
|
return sc.processSettings(f)
|
||||||
|
@ -1503,9 +1522,6 @@ func (sc *serverConn) processPing(f *PingFrame) error {
|
||||||
// PROTOCOL_ERROR."
|
// PROTOCOL_ERROR."
|
||||||
return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol))
|
return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
|
sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1567,6 +1583,9 @@ func (sc *serverConn) closeStream(st *stream, err error) {
|
||||||
panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
|
panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
|
||||||
}
|
}
|
||||||
st.state = stateClosed
|
st.state = stateClosed
|
||||||
|
if st.readDeadline != nil {
|
||||||
|
st.readDeadline.Stop()
|
||||||
|
}
|
||||||
if st.writeDeadline != nil {
|
if st.writeDeadline != nil {
|
||||||
st.writeDeadline.Stop()
|
st.writeDeadline.Stop()
|
||||||
}
|
}
|
||||||
|
@ -1592,6 +1611,14 @@ func (sc *serverConn) closeStream(st *stream, err error) {
|
||||||
|
|
||||||
p.CloseWithError(err)
|
p.CloseWithError(err)
|
||||||
}
|
}
|
||||||
|
if e, ok := err.(StreamError); ok {
|
||||||
|
if e.Cause != nil {
|
||||||
|
err = e.Cause
|
||||||
|
} else {
|
||||||
|
err = errStreamClosed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
st.closeErr = err
|
||||||
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
|
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
|
||||||
sc.writeSched.CloseStream(st.id)
|
sc.writeSched.CloseStream(st.id)
|
||||||
}
|
}
|
||||||
|
@ -1688,16 +1715,6 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
|
||||||
func (sc *serverConn) processData(f *DataFrame) error {
|
func (sc *serverConn) processData(f *DataFrame) error {
|
||||||
sc.serveG.check()
|
sc.serveG.check()
|
||||||
id := f.Header().StreamID
|
id := f.Header().StreamID
|
||||||
if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || id > sc.maxClientStreamID) {
|
|
||||||
// Discard all DATA frames if the GOAWAY is due to an
|
|
||||||
// error, or:
|
|
||||||
//
|
|
||||||
// Section 6.8: After sending a GOAWAY frame, the sender
|
|
||||||
// can discard frames for streams initiated by the
|
|
||||||
// receiver with identifiers higher than the identified
|
|
||||||
// last stream.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
data := f.Data()
|
data := f.Data()
|
||||||
state, st := sc.state(id)
|
state, st := sc.state(id)
|
||||||
|
@ -1840,19 +1857,27 @@ func (st *stream) copyTrailersToHandlerRequest() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// onReadTimeout is run on its own goroutine (from time.AfterFunc)
|
||||||
|
// when the stream's ReadTimeout has fired.
|
||||||
|
func (st *stream) onReadTimeout() {
|
||||||
|
// Wrap the ErrDeadlineExceeded to avoid callers depending on us
|
||||||
|
// returning the bare error.
|
||||||
|
st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
|
||||||
|
}
|
||||||
|
|
||||||
// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
|
// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
|
||||||
// when the stream's WriteTimeout has fired.
|
// when the stream's WriteTimeout has fired.
|
||||||
func (st *stream) onWriteTimeout() {
|
func (st *stream) onWriteTimeout() {
|
||||||
st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)})
|
st.sc.writeFrameFromHandler(FrameWriteRequest{write: StreamError{
|
||||||
|
StreamID: st.id,
|
||||||
|
Code: ErrCodeInternal,
|
||||||
|
Cause: os.ErrDeadlineExceeded,
|
||||||
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
||||||
sc.serveG.check()
|
sc.serveG.check()
|
||||||
id := f.StreamID
|
id := f.StreamID
|
||||||
if sc.inGoAway {
|
|
||||||
// Ignore.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// http://tools.ietf.org/html/rfc7540#section-5.1.1
|
// http://tools.ietf.org/html/rfc7540#section-5.1.1
|
||||||
// Streams initiated by a client MUST use odd-numbered stream
|
// Streams initiated by a client MUST use odd-numbered stream
|
||||||
// identifiers. [...] An endpoint that receives an unexpected
|
// identifiers. [...] An endpoint that receives an unexpected
|
||||||
|
@ -1955,6 +1980,9 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
||||||
// (in Go 1.8), though. That's a more sane option anyway.
|
// (in Go 1.8), though. That's a more sane option anyway.
|
||||||
if sc.hs.ReadTimeout != 0 {
|
if sc.hs.ReadTimeout != 0 {
|
||||||
sc.conn.SetReadDeadline(time.Time{})
|
sc.conn.SetReadDeadline(time.Time{})
|
||||||
|
if st.body != nil {
|
||||||
|
st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go sc.runHandler(rw, req, handler)
|
go sc.runHandler(rw, req, handler)
|
||||||
|
@ -2023,9 +2051,6 @@ func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *serverConn) processPriority(f *PriorityFrame) error {
|
func (sc *serverConn) processPriority(f *PriorityFrame) error {
|
||||||
if sc.inGoAway {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
|
if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2099,12 +2124,6 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
||||||
return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
|
return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyOpen := !f.StreamEnded()
|
|
||||||
if rp.method == "HEAD" && bodyOpen {
|
|
||||||
// HEAD requests can't have bodies
|
|
||||||
return nil, nil, sc.countError("head_body", streamError(f.StreamID, ErrCodeProtocol))
|
|
||||||
}
|
|
||||||
|
|
||||||
rp.header = make(http.Header)
|
rp.header = make(http.Header)
|
||||||
for _, hf := range f.RegularFields() {
|
for _, hf := range f.RegularFields() {
|
||||||
rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
|
rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
|
||||||
|
@ -2117,6 +2136,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
bodyOpen := !f.StreamEnded()
|
||||||
if bodyOpen {
|
if bodyOpen {
|
||||||
if vv, ok := rp.header["Content-Length"]; ok {
|
if vv, ok := rp.header["Content-Length"]; ok {
|
||||||
if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
|
if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
|
||||||
|
@ -2346,7 +2366,7 @@ func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
|
||||||
// a larger Read than this. Very unlikely, but we handle it here
|
// a larger Read than this. Very unlikely, but we handle it here
|
||||||
// rather than elsewhere for now.
|
// rather than elsewhere for now.
|
||||||
const maxUint31 = 1<<31 - 1
|
const maxUint31 = 1<<31 - 1
|
||||||
for n >= maxUint31 {
|
for n > maxUint31 {
|
||||||
sc.sendWindowUpdate32(st, maxUint31)
|
sc.sendWindowUpdate32(st, maxUint31)
|
||||||
n -= maxUint31
|
n -= maxUint31
|
||||||
}
|
}
|
||||||
|
@ -2466,7 +2486,15 @@ type responseWriterState struct {
|
||||||
|
|
||||||
type chunkWriter struct{ rws *responseWriterState }
|
type chunkWriter struct{ rws *responseWriterState }
|
||||||
|
|
||||||
func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
|
func (cw chunkWriter) Write(p []byte) (n int, err error) {
|
||||||
|
n, err = cw.rws.writeChunk(p)
|
||||||
|
if err == errStreamClosed {
|
||||||
|
// If writing failed because the stream has been closed,
|
||||||
|
// return the reason it was closed.
|
||||||
|
err = cw.rws.stream.closeErr
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
|
func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
|
||||||
|
|
||||||
|
@ -2505,6 +2533,10 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
||||||
rws.writeHeader(200)
|
rws.writeHeader(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rws.handlerDone {
|
||||||
|
rws.promoteUndeclaredTrailers()
|
||||||
|
}
|
||||||
|
|
||||||
isHeadResp := rws.req.Method == "HEAD"
|
isHeadResp := rws.req.Method == "HEAD"
|
||||||
if !rws.sentHeader {
|
if !rws.sentHeader {
|
||||||
rws.sentHeader = true
|
rws.sentHeader = true
|
||||||
|
@ -2576,10 +2608,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if rws.handlerDone {
|
|
||||||
rws.promoteUndeclaredTrailers()
|
|
||||||
}
|
|
||||||
|
|
||||||
// only send trailers if they have actually been defined by the
|
// only send trailers if they have actually been defined by the
|
||||||
// server handler.
|
// server handler.
|
||||||
hasNonemptyTrailers := rws.hasNonemptyTrailers()
|
hasNonemptyTrailers := rws.hasNonemptyTrailers()
|
||||||
|
@ -2660,23 +2688,85 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
|
||||||
|
st := w.rws.stream
|
||||||
|
if !deadline.IsZero() && deadline.Before(time.Now()) {
|
||||||
|
// If we're setting a deadline in the past, reset the stream immediately
|
||||||
|
// so writes after SetWriteDeadline returns will fail.
|
||||||
|
st.onReadTimeout()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
w.rws.conn.sendServeMsg(func(sc *serverConn) {
|
||||||
|
if st.readDeadline != nil {
|
||||||
|
if !st.readDeadline.Stop() {
|
||||||
|
// Deadline already exceeded, or stream has been closed.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deadline.IsZero() {
|
||||||
|
st.readDeadline = nil
|
||||||
|
} else if st.readDeadline == nil {
|
||||||
|
st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
|
||||||
|
} else {
|
||||||
|
st.readDeadline.Reset(deadline.Sub(time.Now()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
|
||||||
|
st := w.rws.stream
|
||||||
|
if !deadline.IsZero() && deadline.Before(time.Now()) {
|
||||||
|
// If we're setting a deadline in the past, reset the stream immediately
|
||||||
|
// so writes after SetWriteDeadline returns will fail.
|
||||||
|
st.onWriteTimeout()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
w.rws.conn.sendServeMsg(func(sc *serverConn) {
|
||||||
|
if st.writeDeadline != nil {
|
||||||
|
if !st.writeDeadline.Stop() {
|
||||||
|
// Deadline already exceeded, or stream has been closed.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deadline.IsZero() {
|
||||||
|
st.writeDeadline = nil
|
||||||
|
} else if st.writeDeadline == nil {
|
||||||
|
st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
|
||||||
|
} else {
|
||||||
|
st.writeDeadline.Reset(deadline.Sub(time.Now()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *responseWriter) Flush() {
|
func (w *responseWriter) Flush() {
|
||||||
|
w.FlushError()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *responseWriter) FlushError() error {
|
||||||
rws := w.rws
|
rws := w.rws
|
||||||
if rws == nil {
|
if rws == nil {
|
||||||
panic("Header called after Handler finished")
|
panic("Header called after Handler finished")
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
if rws.bw.Buffered() > 0 {
|
if rws.bw.Buffered() > 0 {
|
||||||
if err := rws.bw.Flush(); err != nil {
|
err = rws.bw.Flush()
|
||||||
// Ignore the error. The frame writer already knows.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// The bufio.Writer won't call chunkWriter.Write
|
// The bufio.Writer won't call chunkWriter.Write
|
||||||
// (writeChunk with zero bytes, so we have to do it
|
// (writeChunk with zero bytes, so we have to do it
|
||||||
// ourselves to force the HTTP response header and/or
|
// ourselves to force the HTTP response header and/or
|
||||||
// final DATA frame (with END_STREAM) to be sent.
|
// final DATA frame (with END_STREAM) to be sent.
|
||||||
rws.writeChunk(nil)
|
_, err = chunkWriter{rws}.Write(nil)
|
||||||
|
if err == nil {
|
||||||
|
select {
|
||||||
|
case <-rws.stream.cw:
|
||||||
|
err = rws.stream.closeErr
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *responseWriter) CloseNotify() <-chan bool {
|
func (w *responseWriter) CloseNotify() <-chan bool {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
mathrand "math/rand"
|
mathrand "math/rand"
|
||||||
|
@ -258,7 +259,8 @@ func (t *Transport) initConnPool() {
|
||||||
// HTTP/2 server.
|
// HTTP/2 server.
|
||||||
type ClientConn struct {
|
type ClientConn struct {
|
||||||
t *Transport
|
t *Transport
|
||||||
tconn net.Conn // usually *tls.Conn, except specialized impls
|
tconn net.Conn // usually *tls.Conn, except specialized impls
|
||||||
|
tconnClosed bool
|
||||||
tlsState *tls.ConnectionState // nil only for specialized impls
|
tlsState *tls.ConnectionState // nil only for specialized impls
|
||||||
reused uint32 // whether conn is being reused; atomic
|
reused uint32 // whether conn is being reused; atomic
|
||||||
singleUse bool // whether being used for a single http.Request
|
singleUse bool // whether being used for a single http.Request
|
||||||
|
@ -344,8 +346,8 @@ type clientStream struct {
|
||||||
readErr error // sticky read error; owned by transportResponseBody.Read
|
readErr error // sticky read error; owned by transportResponseBody.Read
|
||||||
|
|
||||||
reqBody io.ReadCloser
|
reqBody io.ReadCloser
|
||||||
reqBodyContentLength int64 // -1 means unknown
|
reqBodyContentLength int64 // -1 means unknown
|
||||||
reqBodyClosed bool // body has been closed; guarded by cc.mu
|
reqBodyClosed chan struct{} // guarded by cc.mu; non-nil on Close, closed when done
|
||||||
|
|
||||||
// owned by writeRequest:
|
// owned by writeRequest:
|
||||||
sentEndStream bool // sent an END_STREAM flag to the peer
|
sentEndStream bool // sent an END_STREAM flag to the peer
|
||||||
|
@ -385,9 +387,8 @@ func (cs *clientStream) abortStreamLocked(err error) {
|
||||||
cs.abortErr = err
|
cs.abortErr = err
|
||||||
close(cs.abort)
|
close(cs.abort)
|
||||||
})
|
})
|
||||||
if cs.reqBody != nil && !cs.reqBodyClosed {
|
if cs.reqBody != nil {
|
||||||
cs.reqBody.Close()
|
cs.closeReqBodyLocked()
|
||||||
cs.reqBodyClosed = true
|
|
||||||
}
|
}
|
||||||
// TODO(dneil): Clean up tests where cs.cc.cond is nil.
|
// TODO(dneil): Clean up tests where cs.cc.cond is nil.
|
||||||
if cs.cc.cond != nil {
|
if cs.cc.cond != nil {
|
||||||
|
@ -400,13 +401,24 @@ func (cs *clientStream) abortRequestBodyWrite() {
|
||||||
cc := cs.cc
|
cc := cs.cc
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
defer cc.mu.Unlock()
|
defer cc.mu.Unlock()
|
||||||
if cs.reqBody != nil && !cs.reqBodyClosed {
|
if cs.reqBody != nil && cs.reqBodyClosed == nil {
|
||||||
cs.reqBody.Close()
|
cs.closeReqBodyLocked()
|
||||||
cs.reqBodyClosed = true
|
|
||||||
cc.cond.Broadcast()
|
cc.cond.Broadcast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *clientStream) closeReqBodyLocked() {
|
||||||
|
if cs.reqBodyClosed != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cs.reqBodyClosed = make(chan struct{})
|
||||||
|
reqBodyClosed := cs.reqBodyClosed
|
||||||
|
go func() {
|
||||||
|
cs.reqBody.Close()
|
||||||
|
close(reqBodyClosed)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
type stickyErrWriter struct {
|
type stickyErrWriter struct {
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
@ -490,6 +502,15 @@ func authorityAddr(scheme string, authority string) (addr string) {
|
||||||
return net.JoinHostPort(host, port)
|
return net.JoinHostPort(host, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var retryBackoffHook func(time.Duration) *time.Timer
|
||||||
|
|
||||||
|
func backoffNewTimer(d time.Duration) *time.Timer {
|
||||||
|
if retryBackoffHook != nil {
|
||||||
|
return retryBackoffHook(d)
|
||||||
|
}
|
||||||
|
return time.NewTimer(d)
|
||||||
|
}
|
||||||
|
|
||||||
// RoundTripOpt is like RoundTrip, but takes options.
|
// RoundTripOpt is like RoundTrip, but takes options.
|
||||||
func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
|
func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
|
||||||
if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
|
if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
|
||||||
|
@ -515,11 +536,14 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
|
||||||
}
|
}
|
||||||
backoff := float64(uint(1) << (uint(retry) - 1))
|
backoff := float64(uint(1) << (uint(retry) - 1))
|
||||||
backoff += backoff * (0.1 * mathrand.Float64())
|
backoff += backoff * (0.1 * mathrand.Float64())
|
||||||
|
d := time.Second * time.Duration(backoff)
|
||||||
|
timer := backoffNewTimer(d)
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Second * time.Duration(backoff)):
|
case <-timer.C:
|
||||||
t.vlogf("RoundTrip retrying after failure: %v", err)
|
t.vlogf("RoundTrip retrying after failure: %v", err)
|
||||||
continue
|
continue
|
||||||
case <-req.Context().Done():
|
case <-req.Context().Done():
|
||||||
|
timer.Stop()
|
||||||
err = req.Context().Err()
|
err = req.Context().Err()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -921,10 +945,10 @@ func (cc *ClientConn) onIdleTimeout() {
|
||||||
cc.closeIfIdle()
|
cc.closeIfIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ClientConn) closeConn() error {
|
func (cc *ClientConn) closeConn() {
|
||||||
t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
|
t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
return cc.tconn.Close()
|
cc.tconn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A tls.Conn.Close can hang for a long time if the peer is unresponsive.
|
// A tls.Conn.Close can hang for a long time if the peer is unresponsive.
|
||||||
|
@ -990,7 +1014,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
|
||||||
shutdownEnterWaitStateHook()
|
shutdownEnterWaitStateHook()
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
return cc.closeConn()
|
cc.closeConn()
|
||||||
|
return nil
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
// Free the goroutine above
|
// Free the goroutine above
|
||||||
|
@ -1027,7 +1052,7 @@ func (cc *ClientConn) sendGoAway() error {
|
||||||
|
|
||||||
// closes the client connection immediately. In-flight requests are interrupted.
|
// closes the client connection immediately. In-flight requests are interrupted.
|
||||||
// err is sent to streams.
|
// err is sent to streams.
|
||||||
func (cc *ClientConn) closeForError(err error) error {
|
func (cc *ClientConn) closeForError(err error) {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
cc.closed = true
|
cc.closed = true
|
||||||
for _, cs := range cc.streams {
|
for _, cs := range cc.streams {
|
||||||
|
@ -1035,7 +1060,7 @@ func (cc *ClientConn) closeForError(err error) error {
|
||||||
}
|
}
|
||||||
cc.cond.Broadcast()
|
cc.cond.Broadcast()
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
return cc.closeConn()
|
cc.closeConn()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the client connection immediately.
|
// Close closes the client connection immediately.
|
||||||
|
@ -1043,16 +1068,17 @@ func (cc *ClientConn) closeForError(err error) error {
|
||||||
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
|
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
|
||||||
func (cc *ClientConn) Close() error {
|
func (cc *ClientConn) Close() error {
|
||||||
err := errors.New("http2: client connection force closed via ClientConn.Close")
|
err := errors.New("http2: client connection force closed via ClientConn.Close")
|
||||||
return cc.closeForError(err)
|
cc.closeForError(err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// closes the client connection immediately. In-flight requests are interrupted.
|
// closes the client connection immediately. In-flight requests are interrupted.
|
||||||
func (cc *ClientConn) closeForLostPing() error {
|
func (cc *ClientConn) closeForLostPing() {
|
||||||
err := errors.New("http2: client connection lost")
|
err := errors.New("http2: client connection lost")
|
||||||
if f := cc.t.CountError; f != nil {
|
if f := cc.t.CountError; f != nil {
|
||||||
f("conn_close_lost_ping")
|
f("conn_close_lost_ping")
|
||||||
}
|
}
|
||||||
return cc.closeForError(err)
|
cc.closeForError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
|
// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
|
||||||
|
@ -1062,7 +1088,7 @@ var errRequestCanceled = errors.New("net/http: request canceled")
|
||||||
func commaSeparatedTrailers(req *http.Request) (string, error) {
|
func commaSeparatedTrailers(req *http.Request) (string, error) {
|
||||||
keys := make([]string, 0, len(req.Trailer))
|
keys := make([]string, 0, len(req.Trailer))
|
||||||
for k := range req.Trailer {
|
for k := range req.Trailer {
|
||||||
k = http.CanonicalHeaderKey(k)
|
k = canonicalHeader(k)
|
||||||
switch k {
|
switch k {
|
||||||
case "Transfer-Encoding", "Trailer", "Content-Length":
|
case "Transfer-Encoding", "Trailer", "Content-Length":
|
||||||
return "", fmt.Errorf("invalid Trailer key %q", k)
|
return "", fmt.Errorf("invalid Trailer key %q", k)
|
||||||
|
@ -1430,11 +1456,19 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
|
||||||
// and in multiple cases: server replies <=299 and >299
|
// and in multiple cases: server replies <=299 and >299
|
||||||
// while still writing request body
|
// while still writing request body
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
|
mustCloseBody := false
|
||||||
|
if cs.reqBody != nil && cs.reqBodyClosed == nil {
|
||||||
|
mustCloseBody = true
|
||||||
|
cs.reqBodyClosed = make(chan struct{})
|
||||||
|
}
|
||||||
bodyClosed := cs.reqBodyClosed
|
bodyClosed := cs.reqBodyClosed
|
||||||
cs.reqBodyClosed = true
|
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
if !bodyClosed && cs.reqBody != nil {
|
if mustCloseBody {
|
||||||
cs.reqBody.Close()
|
cs.reqBody.Close()
|
||||||
|
close(bodyClosed)
|
||||||
|
}
|
||||||
|
if bodyClosed != nil {
|
||||||
|
<-bodyClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil && cs.sentEndStream {
|
if err != nil && cs.sentEndStream {
|
||||||
|
@ -1591,7 +1625,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) {
|
||||||
|
|
||||||
var sawEOF bool
|
var sawEOF bool
|
||||||
for !sawEOF {
|
for !sawEOF {
|
||||||
n, err := body.Read(buf[:len(buf)])
|
n, err := body.Read(buf)
|
||||||
if hasContentLen {
|
if hasContentLen {
|
||||||
remainLen -= int64(n)
|
remainLen -= int64(n)
|
||||||
if remainLen == 0 && err == nil {
|
if remainLen == 0 && err == nil {
|
||||||
|
@ -1614,7 +1648,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) {
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
bodyClosed := cs.reqBodyClosed
|
bodyClosed := cs.reqBodyClosed != nil
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
switch {
|
switch {
|
||||||
case bodyClosed:
|
case bodyClosed:
|
||||||
|
@ -1709,7 +1743,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
|
||||||
if cc.closed {
|
if cc.closed {
|
||||||
return 0, errClientConnClosed
|
return 0, errClientConnClosed
|
||||||
}
|
}
|
||||||
if cs.reqBodyClosed {
|
if cs.reqBodyClosed != nil {
|
||||||
return 0, errStopReqBodyWrite
|
return 0, errStopReqBodyWrite
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
@ -1894,7 +1928,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
|
||||||
|
|
||||||
// Header list size is ok. Write the headers.
|
// Header list size is ok. Write the headers.
|
||||||
enumerateHeaders(func(name, value string) {
|
enumerateHeaders(func(name, value string) {
|
||||||
name, ascii := asciiToLower(name)
|
name, ascii := lowerHeader(name)
|
||||||
if !ascii {
|
if !ascii {
|
||||||
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
|
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
|
||||||
// field names have to be ASCII characters (just as in HTTP/1.x).
|
// field names have to be ASCII characters (just as in HTTP/1.x).
|
||||||
|
@ -1947,7 +1981,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, vv := range trailer {
|
for k, vv := range trailer {
|
||||||
lowKey, ascii := asciiToLower(k)
|
lowKey, ascii := lowerHeader(k)
|
||||||
if !ascii {
|
if !ascii {
|
||||||
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
|
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
|
||||||
// field names have to be ASCII characters (just as in HTTP/1.x).
|
// field names have to be ASCII characters (just as in HTTP/1.x).
|
||||||
|
@ -2005,7 +2039,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
|
||||||
// wake up RoundTrip if there is a pending request.
|
// wake up RoundTrip if there is a pending request.
|
||||||
cc.cond.Broadcast()
|
cc.cond.Broadcast()
|
||||||
|
|
||||||
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives()
|
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
|
||||||
if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
|
if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
|
||||||
if VerboseLogs {
|
if VerboseLogs {
|
||||||
cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
|
cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
|
||||||
|
@ -2081,6 +2115,7 @@ func (rl *clientConnReadLoop) cleanup() {
|
||||||
err = io.ErrUnexpectedEOF
|
err = io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
cc.closed = true
|
cc.closed = true
|
||||||
|
|
||||||
for _, cs := range cc.streams {
|
for _, cs := range cc.streams {
|
||||||
select {
|
select {
|
||||||
case <-cs.peerClosed:
|
case <-cs.peerClosed:
|
||||||
|
@ -2279,7 +2314,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
||||||
Status: status + " " + http.StatusText(statusCode),
|
Status: status + " " + http.StatusText(statusCode),
|
||||||
}
|
}
|
||||||
for _, hf := range regularFields {
|
for _, hf := range regularFields {
|
||||||
key := http.CanonicalHeaderKey(hf.Name)
|
key := canonicalHeader(hf.Name)
|
||||||
if key == "Trailer" {
|
if key == "Trailer" {
|
||||||
t := res.Trailer
|
t := res.Trailer
|
||||||
if t == nil {
|
if t == nil {
|
||||||
|
@ -2287,7 +2322,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
||||||
res.Trailer = t
|
res.Trailer = t
|
||||||
}
|
}
|
||||||
foreachHeaderElement(hf.Value, func(v string) {
|
foreachHeaderElement(hf.Value, func(v string) {
|
||||||
t[http.CanonicalHeaderKey(v)] = nil
|
t[canonicalHeader(v)] = nil
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
vv := header[key]
|
vv := header[key]
|
||||||
|
@ -2392,7 +2427,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr
|
||||||
|
|
||||||
trailer := make(http.Header)
|
trailer := make(http.Header)
|
||||||
for _, hf := range f.RegularFields() {
|
for _, hf := range f.RegularFields() {
|
||||||
key := http.CanonicalHeaderKey(hf.Name)
|
key := canonicalHeader(hf.Name)
|
||||||
trailer[key] = append(trailer[key], hf.Value)
|
trailer[key] = append(trailer[key], hf.Value)
|
||||||
}
|
}
|
||||||
cs.trailer = trailer
|
cs.trailer = trailer
|
||||||
|
@ -2674,7 +2709,6 @@ func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
|
||||||
if fn := cc.t.CountError; fn != nil {
|
if fn := cc.t.CountError; fn != nil {
|
||||||
fn("recv_goaway_" + f.ErrCode.stringToken())
|
fn("recv_goaway_" + f.ErrCode.stringToken())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
cc.setGoAway(f)
|
cc.setGoAway(f)
|
||||||
return nil
|
return nil
|
||||||
|
@ -2964,7 +2998,11 @@ func (gz *gzipReader) Read(p []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gz *gzipReader) Close() error {
|
func (gz *gzipReader) Close() error {
|
||||||
return gz.body.Close()
|
if err := gz.body.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gz.zerr = fs.ErrClosed
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type errorReader struct{ err error }
|
type errorReader struct{ err error }
|
||||||
|
@ -3028,7 +3066,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
ci.WasIdle = len(cc.streams) == 0 && reused
|
ci.WasIdle = len(cc.streams) == 0 && reused
|
||||||
if ci.WasIdle && !cc.lastActive.IsZero() {
|
if ci.WasIdle && !cc.lastActive.IsZero() {
|
||||||
ci.IdleTime = time.Now().Sub(cc.lastActive)
|
ci.IdleTime = time.Since(cc.lastActive)
|
||||||
}
|
}
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,23 @@ type mmsgTmpsPool struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mmsgTmpsPool) Get() *mmsgTmps {
|
func (p *mmsgTmpsPool) Get() *mmsgTmps {
|
||||||
return p.p.Get().(*mmsgTmps)
|
m := p.p.Get().(*mmsgTmps)
|
||||||
|
// Clear fields up to the len (not the cap) of the slice,
|
||||||
|
// assuming that the previous caller only used that many elements.
|
||||||
|
for i := range m.packer.sockaddrs {
|
||||||
|
m.packer.sockaddrs[i] = 0
|
||||||
|
}
|
||||||
|
m.packer.sockaddrs = m.packer.sockaddrs[:0]
|
||||||
|
for i := range m.packer.vs {
|
||||||
|
m.packer.vs[i] = iovec{}
|
||||||
|
}
|
||||||
|
m.packer.vs = m.packer.vs[:0]
|
||||||
|
for i := range m.packer.hs {
|
||||||
|
m.packer.hs[i].Len = 0
|
||||||
|
m.packer.hs[i].Hdr = msghdr{}
|
||||||
|
}
|
||||||
|
m.packer.hs = m.packer.hs[:0]
|
||||||
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
|
func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
|
||||||
|
|
|
@ -17,9 +17,6 @@ func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||||
if sa != nil {
|
if sa != nil {
|
||||||
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||||
h.Namelen = uint32(len(sa))
|
h.Namelen = uint32(len(sa))
|
||||||
} else {
|
|
||||||
h.Name = nil
|
|
||||||
h.Namelen = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
|
// cgo -godefs defs_openbsd.go
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
type iovec struct {
|
||||||
|
Base *byte
|
||||||
|
Len uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type msghdr struct {
|
||||||
|
Name *byte
|
||||||
|
Namelen uint32
|
||||||
|
Iov *iovec
|
||||||
|
Iovlen uint32
|
||||||
|
Control *byte
|
||||||
|
Controllen uint32
|
||||||
|
Flags int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type cmsghdr struct {
|
||||||
|
Len uint32
|
||||||
|
Level int32
|
||||||
|
Type int32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = 0x10
|
||||||
|
sizeofMsghdr = 0x30
|
||||||
|
)
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
|
// cgo -godefs defs_openbsd.go
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
type iovec struct {
|
||||||
|
Base *byte
|
||||||
|
Len uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type msghdr struct {
|
||||||
|
Name *byte
|
||||||
|
Namelen uint32
|
||||||
|
Iov *iovec
|
||||||
|
Iovlen uint32
|
||||||
|
Control *byte
|
||||||
|
Controllen uint32
|
||||||
|
Flags int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type cmsghdr struct {
|
||||||
|
Len uint32
|
||||||
|
Level int32
|
||||||
|
Type int32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = 0x10
|
||||||
|
sizeofMsghdr = 0x30
|
||||||
|
)
|
|
@ -395,7 +395,7 @@ func New(family, title string) Trace {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr *trace) Finish() {
|
func (tr *trace) Finish() {
|
||||||
elapsed := time.Now().Sub(tr.Start)
|
elapsed := time.Since(tr.Start)
|
||||||
tr.mu.Lock()
|
tr.mu.Lock()
|
||||||
tr.Elapsed = elapsed
|
tr.Elapsed = elapsed
|
||||||
tr.mu.Unlock()
|
tr.mu.Unlock()
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# This source code refers to The Go Authors for copyright purposes.
|
|
||||||
# The master list of authors is in the main Go distribution,
|
|
||||||
# visible at http://tip.golang.org/AUTHORS.
|
|
|
@ -1,3 +0,0 @@
|
||||||
# This source code was written by the Go contributors.
|
|
||||||
# The master list of contributors is in the main Go distribution,
|
|
||||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
|
|
@ -61,8 +61,8 @@ func (g *Group) Wait() error {
|
||||||
// It blocks until the new goroutine can be added without the number of
|
// It blocks until the new goroutine can be added without the number of
|
||||||
// active goroutines in the group exceeding the configured limit.
|
// active goroutines in the group exceeding the configured limit.
|
||||||
//
|
//
|
||||||
// The first call to return a non-nil error cancels the group; its error will be
|
// The first call to return a non-nil error cancels the group's context, if the
|
||||||
// returned by Wait.
|
// group was created by calling WithContext. The error will be returned by Wait.
|
||||||
func (g *Group) Go(f func() error) {
|
func (g *Group) Go(f func() error) {
|
||||||
if g.sem != nil {
|
if g.sem != nil {
|
||||||
g.sem <- token{}
|
g.sem <- token{}
|
||||||
|
|
|
@ -6,7 +6,10 @@ package cpu
|
||||||
|
|
||||||
import "runtime"
|
import "runtime"
|
||||||
|
|
||||||
const cacheLineSize = 64
|
// cacheLineSize is used to prevent false sharing of cache lines.
|
||||||
|
// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
|
||||||
|
// It doesn't cost much and is much more future-proof.
|
||||||
|
const cacheLineSize = 128
|
||||||
|
|
||||||
func initOptions() {
|
func initOptions() {
|
||||||
options = []option{
|
options = []option{
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2022 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 !aix && !linux && (ppc64 || ppc64le)
|
||||||
|
// +build !aix
|
||||||
|
// +build !linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func archInit() {
|
||||||
|
PPC64.IsPOWER8 = true
|
||||||
|
Initialized = true
|
||||||
|
}
|
|
@ -126,7 +126,7 @@ errors=$(
|
||||||
signals=$(
|
signals=$(
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
|
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
|
||||||
sort
|
sort
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
sort >_error.grep
|
sort >_error.grep
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
|
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
|
||||||
sort >_signal.grep
|
sort >_signal.grep
|
||||||
|
|
||||||
echo '// mkerrors.sh' "$@"
|
echo '// mkerrors.sh' "$@"
|
||||||
|
|
|
@ -29,8 +29,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
||||||
|
@ -82,13 +80,7 @@ func BytePtrToString(p *byte) string {
|
||||||
ptr = unsafe.Pointer(uintptr(ptr) + 1)
|
ptr = unsafe.Pointer(uintptr(ptr) + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var s []byte
|
return string(unsafe.Slice(p, n))
|
||||||
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
|
||||||
h.Data = unsafe.Pointer(p)
|
|
||||||
h.Len = n
|
|
||||||
h.Cap = n
|
|
||||||
|
|
||||||
return string(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2022 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 (darwin || freebsd || netbsd || openbsd) && gc
|
||||||
|
// +build darwin freebsd netbsd openbsd
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ppc64, BSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
|
@ -2,8 +2,8 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import "unsafe"
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IoctlRetInt performs an ioctl operation specified by req on a device
|
// IoctlRetInt performs an ioctl operation specified by req on a device
|
||||||
// associated with opened file descriptor fd, and returns a non-negative
|
// associated with opened file descriptor fd, and returns a non-negative
|
||||||
|
@ -217,3 +215,19 @@ func IoctlKCMAttach(fd int, info KCMAttach) error {
|
||||||
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
|
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
|
||||||
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
|
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IoctlLoopGetStatus64 gets the status of the loop device associated with the
|
||||||
|
// file descriptor fd using the LOOP_GET_STATUS64 operation.
|
||||||
|
func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
|
||||||
|
var value LoopInfo64
|
||||||
|
if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IoctlLoopSetStatus64 sets the status of the loop device associated with the
|
||||||
|
// file descriptor fd using the LOOP_SET_STATUS64 operation.
|
||||||
|
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
|
||||||
|
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
|
||||||
|
}
|
||||||
|
|
|
@ -142,33 +142,33 @@ netbsd_arm64)
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
;;
|
;;
|
||||||
openbsd_386)
|
openbsd_386)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors -m32"
|
mkerrors="$mkerrors -m32"
|
||||||
mksyscall="go run mksyscall.go -l32 -openbsd"
|
mksyscall="go run mksyscall.go -l32 -openbsd -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
;;
|
;;
|
||||||
openbsd_amd64)
|
openbsd_amd64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
mksyscall="go run mksyscall.go -openbsd"
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
;;
|
;;
|
||||||
openbsd_arm)
|
openbsd_arm)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors"
|
mkerrors="$mkerrors"
|
||||||
mksyscall="go run mksyscall.go -l32 -openbsd -arm"
|
mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
# Let the type of C char be signed for making the bare syscall
|
||||||
# API consistent across platforms.
|
# API consistent across platforms.
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
;;
|
;;
|
||||||
openbsd_arm64)
|
openbsd_arm64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
mksyscall="go run mksyscall.go -openbsd"
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
# Let the type of C char be signed for making the bare syscall
|
||||||
# API consistent across platforms.
|
# API consistent across platforms.
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
|
@ -182,6 +182,24 @@ openbsd_mips64)
|
||||||
# API consistent across platforms.
|
# API consistent across platforms.
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
;;
|
;;
|
||||||
|
openbsd_ppc64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
|
mkerrors="$mkerrors -m64"
|
||||||
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
|
# Let the type of C char be signed for making the bare syscall
|
||||||
|
# API consistent across platforms.
|
||||||
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
|
;;
|
||||||
|
openbsd_riscv64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
|
mkerrors="$mkerrors -m64"
|
||||||
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
|
# Let the type of C char be signed for making the bare syscall
|
||||||
|
# API consistent across platforms.
|
||||||
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
|
;;
|
||||||
solaris_amd64)
|
solaris_amd64)
|
||||||
mksyscall="go run mksyscall_solaris.go"
|
mksyscall="go run mksyscall_solaris.go"
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
|
@ -214,11 +232,6 @@ esac
|
||||||
if [ "$GOOSARCH" == "aix_ppc64" ]; then
|
if [ "$GOOSARCH" == "aix_ppc64" ]; then
|
||||||
# aix/ppc64 script generates files instead of writing to stdin.
|
# aix/ppc64 script generates files instead of writing to stdin.
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
||||||
elif [ "$GOOS" == "darwin" ]; then
|
|
||||||
# 1.12 and later, syscalls via libSystem
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
|
||||||
# 1.13 and later, syscalls via libSystem (including syscallPtr)
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
|
|
||||||
elif [ "$GOOS" == "illumos" ]; then
|
elif [ "$GOOS" == "illumos" ]; then
|
||||||
# illumos code generation requires a --illumos switch
|
# illumos code generation requires a --illumos switch
|
||||||
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
|
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
|
||||||
|
|
|
@ -642,7 +642,7 @@ errors=$(
|
||||||
signals=$(
|
signals=$(
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
|
||||||
sort
|
sort
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -652,7 +652,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
sort >_error.grep
|
sort >_error.grep
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
|
||||||
sort >_signal.grep
|
sort >_signal.grep
|
||||||
|
|
||||||
echo '// mkerrors.sh' "$@"
|
echo '// mkerrors.sh' "$@"
|
||||||
|
|
|
@ -52,6 +52,20 @@ func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
|
||||||
return msgs, nil
|
return msgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseOneSocketControlMessage parses a single socket control message from b, returning the message header,
|
||||||
|
// message data (a slice of b), and the remainder of b after that single message.
|
||||||
|
// When there are no remaining messages, len(remainder) == 0.
|
||||||
|
func ParseOneSocketControlMessage(b []byte) (hdr Cmsghdr, data []byte, remainder []byte, err error) {
|
||||||
|
h, dbuf, err := socketControlMessageHeaderAndData(b)
|
||||||
|
if err != nil {
|
||||||
|
return Cmsghdr{}, nil, nil, err
|
||||||
|
}
|
||||||
|
if i := cmsgAlignOf(int(h.Len)); i < len(b) {
|
||||||
|
remainder = b[i:]
|
||||||
|
}
|
||||||
|
return *h, dbuf, remainder, nil
|
||||||
|
}
|
||||||
|
|
||||||
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
|
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
|
||||||
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {
|
if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// Copyright 2009 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 aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
|
||||||
if val < 0 {
|
|
||||||
return "-" + uitoa(uint(-val))
|
|
||||||
}
|
|
||||||
return uitoa(uint(val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func uitoa(val uint) string {
|
|
||||||
var buf [32]byte // big enough for int64
|
|
||||||
i := len(buf) - 1
|
|
||||||
for val >= 10 {
|
|
||||||
buf[i] = byte(val%10 + '0')
|
|
||||||
i--
|
|
||||||
val /= 10
|
|
||||||
}
|
|
||||||
buf[i] = byte(val + '0')
|
|
||||||
return string(buf[i:])
|
|
||||||
}
|
|
|
@ -29,8 +29,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
||||||
|
@ -82,13 +80,7 @@ func BytePtrToString(p *byte) string {
|
||||||
ptr = unsafe.Pointer(uintptr(ptr) + 1)
|
ptr = unsafe.Pointer(uintptr(ptr) + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var s []byte
|
return string(unsafe.Slice(p, n))
|
||||||
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
|
||||||
h.Data = unsafe.Pointer(p)
|
|
||||||
h.Len = n
|
|
||||||
h.Cap = n
|
|
||||||
|
|
||||||
return string(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// Copyright 2019 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 darwin && go1.12 && !go1.13
|
|
||||||
// +build darwin,go1.12,!go1.13
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const _SYS_GETDIRENTRIES64 = 344
|
|
||||||
|
|
||||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
|
||||||
// To implement this using libSystem we'd need syscall_syscallPtr for
|
|
||||||
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
|
|
||||||
// back to raw syscalls for this func on Go 1.12.
|
|
||||||
var p unsafe.Pointer
|
|
||||||
if len(buf) > 0 {
|
|
||||||
p = unsafe.Pointer(&buf[0])
|
|
||||||
} else {
|
|
||||||
p = unsafe.Pointer(&_zero)
|
|
||||||
}
|
|
||||||
r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
|
||||||
n = int(r0)
|
|
||||||
if e1 != 0 {
|
|
||||||
return n, errnoErr(e1)
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
// Copyright 2019 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 darwin && go1.13
|
|
||||||
// +build darwin,go1.13
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys closedir(dir uintptr) (err error)
|
|
||||||
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
|
|
||||||
|
|
||||||
func fdopendir(fd int) (dir uintptr, err error) {
|
|
||||||
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
|
|
||||||
dir = uintptr(r0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var libc_fdopendir_trampoline_addr uintptr
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
|
|
||||||
|
|
||||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
|
||||||
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
|
|
||||||
// We store the number of entries to skip in the seek
|
|
||||||
// offset of fd. See issue #31368.
|
|
||||||
// It's not the full required semantics, but should handle the case
|
|
||||||
// of calling Getdirentries or ReadDirent repeatedly.
|
|
||||||
// It won't handle assigning the results of lseek to *basep, or handle
|
|
||||||
// the directory being edited underfoot.
|
|
||||||
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to duplicate the incoming file descriptor
|
|
||||||
// because the caller expects to retain control of it, but
|
|
||||||
// fdopendir expects to take control of its argument.
|
|
||||||
// Just Dup'ing the file descriptor is not enough, as the
|
|
||||||
// result shares underlying state. Use Openat to make a really
|
|
||||||
// new file descriptor referring to the same directory.
|
|
||||||
fd2, err := Openat(fd, ".", O_RDONLY, 0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
d, err := fdopendir(fd2)
|
|
||||||
if err != nil {
|
|
||||||
Close(fd2)
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer closedir(d)
|
|
||||||
|
|
||||||
var cnt int64
|
|
||||||
for {
|
|
||||||
var entry Dirent
|
|
||||||
var entryp *Dirent
|
|
||||||
e := readdir_r(d, &entry, &entryp)
|
|
||||||
if e != 0 {
|
|
||||||
return n, errnoErr(e)
|
|
||||||
}
|
|
||||||
if entryp == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if skip > 0 {
|
|
||||||
skip--
|
|
||||||
cnt++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
reclen := int(entry.Reclen)
|
|
||||||
if reclen > len(buf) {
|
|
||||||
// Not enough room. Return for now.
|
|
||||||
// The counter will let us know where we should start up again.
|
|
||||||
// Note: this strategy for suspending in the middle and
|
|
||||||
// restarting is O(n^2) in the length of the directory. Oh well.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy entry into return buffer.
|
|
||||||
var s []byte
|
|
||||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
|
||||||
hdr.Data = unsafe.Pointer(&entry)
|
|
||||||
hdr.Cap = reclen
|
|
||||||
hdr.Len = reclen
|
|
||||||
copy(buf, s)
|
|
||||||
|
|
||||||
buf = buf[reclen:]
|
|
||||||
n += reclen
|
|
||||||
cnt++
|
|
||||||
}
|
|
||||||
// Set the seek offset of the input fd to record
|
|
||||||
// how many files we've already returned.
|
|
||||||
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
|
@ -19,6 +19,96 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//sys closedir(dir uintptr) (err error)
|
||||||
|
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
|
||||||
|
|
||||||
|
func fdopendir(fd int) (dir uintptr, err error) {
|
||||||
|
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
|
||||||
|
dir = uintptr(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_fdopendir_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||||
|
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
|
||||||
|
// We store the number of entries to skip in the seek
|
||||||
|
// offset of fd. See issue #31368.
|
||||||
|
// It's not the full required semantics, but should handle the case
|
||||||
|
// of calling Getdirentries or ReadDirent repeatedly.
|
||||||
|
// It won't handle assigning the results of lseek to *basep, or handle
|
||||||
|
// the directory being edited underfoot.
|
||||||
|
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to duplicate the incoming file descriptor
|
||||||
|
// because the caller expects to retain control of it, but
|
||||||
|
// fdopendir expects to take control of its argument.
|
||||||
|
// Just Dup'ing the file descriptor is not enough, as the
|
||||||
|
// result shares underlying state. Use Openat to make a really
|
||||||
|
// new file descriptor referring to the same directory.
|
||||||
|
fd2, err := Openat(fd, ".", O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
d, err := fdopendir(fd2)
|
||||||
|
if err != nil {
|
||||||
|
Close(fd2)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer closedir(d)
|
||||||
|
|
||||||
|
var cnt int64
|
||||||
|
for {
|
||||||
|
var entry Dirent
|
||||||
|
var entryp *Dirent
|
||||||
|
e := readdir_r(d, &entry, &entryp)
|
||||||
|
if e != 0 {
|
||||||
|
return n, errnoErr(e)
|
||||||
|
}
|
||||||
|
if entryp == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if skip > 0 {
|
||||||
|
skip--
|
||||||
|
cnt++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
reclen := int(entry.Reclen)
|
||||||
|
if reclen > len(buf) {
|
||||||
|
// Not enough room. Return for now.
|
||||||
|
// The counter will let us know where we should start up again.
|
||||||
|
// Note: this strategy for suspending in the middle and
|
||||||
|
// restarting is O(n^2) in the length of the directory. Oh well.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy entry into return buffer.
|
||||||
|
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
|
||||||
|
copy(buf, s)
|
||||||
|
|
||||||
|
buf = buf[reclen:]
|
||||||
|
n += reclen
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
// Set the seek offset of the input fd to record
|
||||||
|
// how many files we've already returned.
|
||||||
|
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
|
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
|
||||||
type SockaddrDatalink struct {
|
type SockaddrDatalink struct {
|
||||||
Len uint8
|
Len uint8
|
||||||
|
|
|
@ -61,7 +61,7 @@ func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,107 +77,3 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
|
|
||||||
|
|
||||||
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
|
|
||||||
var clp, datap *strbuf
|
|
||||||
if len(cl) > 0 {
|
|
||||||
clp = &strbuf{
|
|
||||||
Len: int32(len(cl)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
|
||||||
datap = &strbuf{
|
|
||||||
Len: int32(len(data)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return putmsg(fd, clp, datap, flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
|
|
||||||
|
|
||||||
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
|
|
||||||
var clp, datap *strbuf
|
|
||||||
if len(cl) > 0 {
|
|
||||||
clp = &strbuf{
|
|
||||||
Maxlen: int32(len(cl)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
|
||||||
datap = &strbuf{
|
|
||||||
Maxlen: int32(len(data)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = getmsg(fd, clp, datap, &flags); err != nil {
|
|
||||||
return nil, nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cl) > 0 {
|
|
||||||
retCl = cl[:clp.Len]
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
|
||||||
retData = data[:datap.Len]
|
|
||||||
}
|
|
||||||
return retCl, retData, flags, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
|
|
||||||
return ioctlRet(fd, req, uintptr(arg))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlSetString(fd int, req uint, val string) error {
|
|
||||||
bs := make([]byte, len(val)+1)
|
|
||||||
copy(bs[:len(bs)-1], val)
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
|
|
||||||
runtime.KeepAlive(&bs[0])
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lifreq Helpers
|
|
||||||
|
|
||||||
func (l *Lifreq) SetName(name string) error {
|
|
||||||
if len(name) >= len(l.Name) {
|
|
||||||
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
|
|
||||||
}
|
|
||||||
for i := range name {
|
|
||||||
l.Name[i] = int8(name[i])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) SetLifruInt(d int) {
|
|
||||||
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) GetLifruInt() int {
|
|
||||||
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) SetLifruUint(d uint) {
|
|
||||||
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) GetLifruUint() uint {
|
|
||||||
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
|
||||||
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strioctl Helpers
|
|
||||||
|
|
||||||
func (s *Strioctl) SetInt(i int) {
|
|
||||||
s.Len = int32(unsafe.Sizeof(i))
|
|
||||||
s.Dp = (*int8)(unsafe.Pointer(&i))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
|
|
||||||
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -233,7 +234,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error {
|
||||||
func Futimes(fd int, tv []Timeval) (err error) {
|
func Futimes(fd int, tv []Timeval) (err error) {
|
||||||
// Believe it or not, this is the best we can do on Linux
|
// Believe it or not, this is the best we can do on Linux
|
||||||
// (and is what glibc does).
|
// (and is what glibc does).
|
||||||
return Utimes("/proc/self/fd/"+itoa(fd), tv)
|
return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImplementsGetwd = true
|
const ImplementsGetwd = true
|
||||||
|
@ -1553,6 +1554,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
|
||||||
var iova [1]Iovec
|
var iova [1]Iovec
|
||||||
iova[0].Base = &dummy
|
iova[0].Base = &dummy
|
||||||
iova[0].SetLen(1)
|
iova[0].SetLen(1)
|
||||||
|
iov = iova[:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg.Control = &oob[0]
|
msg.Control = &oob[0]
|
||||||
|
@ -1891,17 +1893,28 @@ func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uint
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue 1435.
|
|
||||||
// On linux Setuid and Setgid only affects the current thread, not the process.
|
|
||||||
// This does not match what most callers expect so we must return an error
|
|
||||||
// here rather than letting the caller think that the call succeeded.
|
|
||||||
|
|
||||||
func Setuid(uid int) (err error) {
|
func Setuid(uid int) (err error) {
|
||||||
return EOPNOTSUPP
|
return syscall.Setuid(uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Setgid(uid int) (err error) {
|
func Setgid(gid int) (err error) {
|
||||||
return EOPNOTSUPP
|
return syscall.Setgid(gid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setreuid(ruid, euid int) (err error) {
|
||||||
|
return syscall.Setreuid(ruid, euid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setregid(rgid, egid int) (err error) {
|
||||||
|
return syscall.Setregid(rgid, egid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setresuid(ruid, euid, suid int) (err error) {
|
||||||
|
return syscall.Setresuid(ruid, euid, suid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setresgid(rgid, egid, sgid int) (err error) {
|
||||||
|
return syscall.Setresgid(rgid, egid, sgid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
|
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
|
||||||
|
@ -2240,7 +2253,7 @@ func (fh *FileHandle) Bytes() []byte {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n]
|
return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
|
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
|
||||||
|
@ -2356,6 +2369,16 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
|
||||||
return prev, nil
|
return prev, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sysnb rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK
|
||||||
|
|
||||||
|
func PthreadSigmask(how int, set, oldset *Sigset_t) error {
|
||||||
|
if oldset != nil {
|
||||||
|
// Explicitly clear in case Sigset_t is larger than _C__NSIG.
|
||||||
|
*oldset = Sigset_t{}
|
||||||
|
}
|
||||||
|
return rtSigprocmask(how, set, oldset, _C__NSIG/8)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unimplemented
|
* Unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -2414,7 +2437,6 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
|
||||||
// RestartSyscall
|
// RestartSyscall
|
||||||
// RtSigaction
|
// RtSigaction
|
||||||
// RtSigpending
|
// RtSigpending
|
||||||
// RtSigprocmask
|
|
||||||
// RtSigqueueinfo
|
// RtSigqueueinfo
|
||||||
// RtSigreturn
|
// RtSigreturn
|
||||||
// RtSigsuspend
|
// RtSigsuspend
|
||||||
|
|
|
@ -41,10 +41,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||||
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
||||||
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
|
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
|
|
@ -46,11 +46,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
|
|
@ -62,10 +62,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||||
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
||||||
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
|
|
@ -39,11 +39,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||||
|
|
|
@ -32,10 +32,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
|
|
@ -34,10 +34,6 @@ import (
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
|
|
@ -34,11 +34,7 @@ package unix
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error)
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
|
|
|
@ -38,11 +38,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,7 @@ import (
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error)
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||||
|
|
|
@ -31,11 +31,7 @@ package unix
|
||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error)
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2022 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 openbsd && !mips64
|
||||||
|
// +build openbsd,!mips64
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import _ "unsafe"
|
||||||
|
|
||||||
|
// Implemented in the runtime package (runtime/sys_openbsd3.go)
|
||||||
|
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:linkname syscall_syscall syscall.syscall
|
||||||
|
//go:linkname syscall_syscall6 syscall.syscall6
|
||||||
|
//go:linkname syscall_syscall10 syscall.syscall10
|
||||||
|
//go:linkname syscall_rawSyscall syscall.rawSyscall
|
||||||
|
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
|
||||||
|
|
||||||
|
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
|
||||||
|
return syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2019 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 ppc64 && openbsd
|
||||||
|
// +build ppc64,openbsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func setTimespec(sec, nsec int64) Timespec {
|
||||||
|
return Timespec{Sec: sec, Nsec: nsec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTimeval(sec, usec int64) Timeval {
|
||||||
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||||
|
msghdr.Iovlen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of openbsd/ppc64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2019 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 riscv64 && openbsd
|
||||||
|
// +build riscv64,openbsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func setTimespec(sec, nsec int64) Timespec {
|
||||||
|
return Timespec{Sec: sec, Nsec: nsec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTimeval(sec, usec int64) Timeval {
|
||||||
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||||
|
msghdr.Iovlen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of openbsd/riscv64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
|
@ -750,8 +750,8 @@ type EventPort struct {
|
||||||
// we should handle things gracefully. To do so, we need to keep an extra
|
// we should handle things gracefully. To do so, we need to keep an extra
|
||||||
// reference to the cookie around until the event is processed
|
// reference to the cookie around until the event is processed
|
||||||
// thus the otherwise seemingly extraneous "cookies" map
|
// thus the otherwise seemingly extraneous "cookies" map
|
||||||
// The key of this map is a pointer to the corresponding &fCookie.cookie
|
// The key of this map is a pointer to the corresponding fCookie
|
||||||
cookies map[*interface{}]*fileObjCookie
|
cookies map[*fileObjCookie]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PortEvent is an abstraction of the port_event C struct.
|
// PortEvent is an abstraction of the port_event C struct.
|
||||||
|
@ -778,7 +778,7 @@ func NewEventPort() (*EventPort, error) {
|
||||||
port: port,
|
port: port,
|
||||||
fds: make(map[uintptr]*fileObjCookie),
|
fds: make(map[uintptr]*fileObjCookie),
|
||||||
paths: make(map[string]*fileObjCookie),
|
paths: make(map[string]*fileObjCookie),
|
||||||
cookies: make(map[*interface{}]*fileObjCookie),
|
cookies: make(map[*fileObjCookie]struct{}),
|
||||||
}
|
}
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
@ -799,6 +799,7 @@ func (e *EventPort) Close() error {
|
||||||
}
|
}
|
||||||
e.fds = nil
|
e.fds = nil
|
||||||
e.paths = nil
|
e.paths = nil
|
||||||
|
e.cookies = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,17 +827,16 @@ func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, coo
|
||||||
if _, found := e.paths[path]; found {
|
if _, found := e.paths[path]; found {
|
||||||
return fmt.Errorf("%v is already associated with this Event Port", path)
|
return fmt.Errorf("%v is already associated with this Event Port", path)
|
||||||
}
|
}
|
||||||
fobj, err := createFileObj(path, stat)
|
fCookie, err := createFileObjCookie(path, stat, cookie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fCookie := &fileObjCookie{fobj, cookie}
|
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
|
||||||
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.paths[path] = fCookie
|
e.paths[path] = fCookie
|
||||||
e.cookies[&fCookie.cookie] = fCookie
|
e.cookies[fCookie] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,7 +858,7 @@ func (e *EventPort) DissociatePath(path string) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// dissociate was successful, safe to delete the cookie
|
// dissociate was successful, safe to delete the cookie
|
||||||
fCookie := e.paths[path]
|
fCookie := e.paths[path]
|
||||||
delete(e.cookies, &fCookie.cookie)
|
delete(e.cookies, fCookie)
|
||||||
}
|
}
|
||||||
delete(e.paths, path)
|
delete(e.paths, path)
|
||||||
return err
|
return err
|
||||||
|
@ -871,13 +871,16 @@ func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) erro
|
||||||
if _, found := e.fds[fd]; found {
|
if _, found := e.fds[fd]; found {
|
||||||
return fmt.Errorf("%v is already associated with this Event Port", fd)
|
return fmt.Errorf("%v is already associated with this Event Port", fd)
|
||||||
}
|
}
|
||||||
fCookie := &fileObjCookie{nil, cookie}
|
fCookie, err := createFileObjCookie("", nil, cookie)
|
||||||
_, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.fds[fd] = fCookie
|
e.fds[fd] = fCookie
|
||||||
e.cookies[&fCookie.cookie] = fCookie
|
e.cookies[fCookie] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,27 +899,31 @@ func (e *EventPort) DissociateFd(fd uintptr) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// dissociate was successful, safe to delete the cookie
|
// dissociate was successful, safe to delete the cookie
|
||||||
fCookie := e.fds[fd]
|
fCookie := e.fds[fd]
|
||||||
delete(e.cookies, &fCookie.cookie)
|
delete(e.cookies, fCookie)
|
||||||
}
|
}
|
||||||
delete(e.fds, fd)
|
delete(e.fds, fd)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFileObj(name string, stat os.FileInfo) (*fileObj, error) {
|
func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
|
||||||
fobj := new(fileObj)
|
fCookie := new(fileObjCookie)
|
||||||
bs, err := ByteSliceFromString(name)
|
fCookie.cookie = cookie
|
||||||
if err != nil {
|
if name != "" && stat != nil {
|
||||||
return nil, err
|
fCookie.fobj = new(fileObj)
|
||||||
|
bs, err := ByteSliceFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
|
||||||
|
s := stat.Sys().(*syscall.Stat_t)
|
||||||
|
fCookie.fobj.Atim.Sec = s.Atim.Sec
|
||||||
|
fCookie.fobj.Atim.Nsec = s.Atim.Nsec
|
||||||
|
fCookie.fobj.Mtim.Sec = s.Mtim.Sec
|
||||||
|
fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
|
||||||
|
fCookie.fobj.Ctim.Sec = s.Ctim.Sec
|
||||||
|
fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
|
||||||
}
|
}
|
||||||
fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
|
return fCookie, nil
|
||||||
s := stat.Sys().(*syscall.Stat_t)
|
|
||||||
fobj.Atim.Sec = s.Atim.Sec
|
|
||||||
fobj.Atim.Nsec = s.Atim.Nsec
|
|
||||||
fobj.Mtim.Sec = s.Mtim.Sec
|
|
||||||
fobj.Mtim.Nsec = s.Mtim.Nsec
|
|
||||||
fobj.Ctim.Sec = s.Ctim.Sec
|
|
||||||
fobj.Ctim.Nsec = s.Ctim.Nsec
|
|
||||||
return fobj, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOne wraps port_get(3c) and returns a single PortEvent.
|
// GetOne wraps port_get(3c) and returns a single PortEvent.
|
||||||
|
@ -929,44 +936,50 @@ func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
|
||||||
p := new(PortEvent)
|
p := new(PortEvent)
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
e.peIntToExt(pe, p)
|
err = e.peIntToExt(pe, p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
|
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
|
||||||
// NOTE: Always call this function while holding the e.mu mutex
|
// NOTE: Always call this function while holding the e.mu mutex
|
||||||
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) {
|
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
|
||||||
|
if e.cookies == nil {
|
||||||
|
return fmt.Errorf("this EventPort is already closed")
|
||||||
|
}
|
||||||
peExt.Events = peInt.Events
|
peExt.Events = peInt.Events
|
||||||
peExt.Source = peInt.Source
|
peExt.Source = peInt.Source
|
||||||
cookie := (*interface{})(unsafe.Pointer(peInt.User))
|
fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
|
||||||
peExt.Cookie = *cookie
|
_, found := e.cookies[fCookie]
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
|
||||||
|
}
|
||||||
|
peExt.Cookie = fCookie.cookie
|
||||||
|
delete(e.cookies, fCookie)
|
||||||
|
|
||||||
switch peInt.Source {
|
switch peInt.Source {
|
||||||
case PORT_SOURCE_FD:
|
case PORT_SOURCE_FD:
|
||||||
delete(e.cookies, cookie)
|
|
||||||
peExt.Fd = uintptr(peInt.Object)
|
peExt.Fd = uintptr(peInt.Object)
|
||||||
// Only remove the fds entry if it exists and this cookie matches
|
// Only remove the fds entry if it exists and this cookie matches
|
||||||
if fobj, ok := e.fds[peExt.Fd]; ok {
|
if fobj, ok := e.fds[peExt.Fd]; ok {
|
||||||
if &fobj.cookie == cookie {
|
if fobj == fCookie {
|
||||||
delete(e.fds, peExt.Fd)
|
delete(e.fds, peExt.Fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case PORT_SOURCE_FILE:
|
case PORT_SOURCE_FILE:
|
||||||
if fCookie, ok := e.cookies[cookie]; ok && uintptr(unsafe.Pointer(fCookie.fobj)) == uintptr(peInt.Object) {
|
peExt.fobj = fCookie.fobj
|
||||||
// Use our stashed reference rather than using unsafe on what we got back
|
|
||||||
// the unsafe version would be (*fileObj)(unsafe.Pointer(uintptr(peInt.Object)))
|
|
||||||
peExt.fobj = fCookie.fobj
|
|
||||||
} else {
|
|
||||||
panic("mismanaged memory")
|
|
||||||
}
|
|
||||||
delete(e.cookies, cookie)
|
|
||||||
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
|
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
|
||||||
// Only remove the paths entry if it exists and this cookie matches
|
// Only remove the paths entry if it exists and this cookie matches
|
||||||
if fobj, ok := e.paths[peExt.Path]; ok {
|
if fobj, ok := e.paths[peExt.Path]; ok {
|
||||||
if &fobj.cookie == cookie {
|
if fobj == fCookie {
|
||||||
delete(e.paths, peExt.Path)
|
delete(e.paths, peExt.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pending wraps port_getn(3c) and returns how many events are pending.
|
// Pending wraps port_getn(3c) and returns how many events are pending.
|
||||||
|
@ -990,7 +1003,7 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
|
||||||
got := uint32(min)
|
got := uint32(min)
|
||||||
max := uint32(len(s))
|
max := uint32(len(s))
|
||||||
var err error
|
var err error
|
||||||
ps := make([]portEvent, max, max)
|
ps := make([]portEvent, max)
|
||||||
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
|
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
|
||||||
// got will be trustworthy with ETIME, but not any other error.
|
// got will be trustworthy with ETIME, but not any other error.
|
||||||
if err != nil && err != ETIME {
|
if err != nil && err != ETIME {
|
||||||
|
@ -998,8 +1011,122 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
|
||||||
}
|
}
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
valid := 0
|
||||||
for i := 0; i < int(got); i++ {
|
for i := 0; i < int(got); i++ {
|
||||||
e.peIntToExt(&ps[i], &s[i])
|
err2 := e.peIntToExt(&ps[i], &s[i])
|
||||||
|
if err2 != nil {
|
||||||
|
if valid == 0 && err == nil {
|
||||||
|
// If err2 is the only error and there are no valid events
|
||||||
|
// to return, return it to the caller.
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
valid = i + 1
|
||||||
}
|
}
|
||||||
return int(got), err
|
return valid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
|
||||||
|
|
||||||
|
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
|
||||||
|
var clp, datap *strbuf
|
||||||
|
if len(cl) > 0 {
|
||||||
|
clp = &strbuf{
|
||||||
|
Len: int32(len(cl)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
datap = &strbuf{
|
||||||
|
Len: int32(len(data)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return putmsg(fd, clp, datap, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
|
||||||
|
|
||||||
|
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
|
||||||
|
var clp, datap *strbuf
|
||||||
|
if len(cl) > 0 {
|
||||||
|
clp = &strbuf{
|
||||||
|
Maxlen: int32(len(cl)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
datap = &strbuf{
|
||||||
|
Maxlen: int32(len(data)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = getmsg(fd, clp, datap, &flags); err != nil {
|
||||||
|
return nil, nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cl) > 0 {
|
||||||
|
retCl = cl[:clp.Len]
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
retData = data[:datap.Len]
|
||||||
|
}
|
||||||
|
return retCl, retData, flags, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
|
||||||
|
return ioctlRet(fd, req, uintptr(arg))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlSetString(fd int, req uint, val string) error {
|
||||||
|
bs := make([]byte, len(val)+1)
|
||||||
|
copy(bs[:len(bs)-1], val)
|
||||||
|
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
|
||||||
|
runtime.KeepAlive(&bs[0])
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lifreq Helpers
|
||||||
|
|
||||||
|
func (l *Lifreq) SetName(name string) error {
|
||||||
|
if len(name) >= len(l.Name) {
|
||||||
|
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
|
||||||
|
}
|
||||||
|
for i := range name {
|
||||||
|
l.Name[i] = int8(name[i])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) SetLifruInt(d int) {
|
||||||
|
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) GetLifruInt() int {
|
||||||
|
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) SetLifruUint(d uint) {
|
||||||
|
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) GetLifruUint() uint {
|
||||||
|
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
||||||
|
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strioctl Helpers
|
||||||
|
|
||||||
|
func (s *Strioctl) SetInt(i int) {
|
||||||
|
s.Len = int32(unsafe.Sizeof(i))
|
||||||
|
s.Dp = (*int8)(unsafe.Pointer(&i))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
|
||||||
|
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -117,11 +115,7 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use unsafe to convert addr into a []byte.
|
// Use unsafe to convert addr into a []byte.
|
||||||
var b []byte
|
b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
|
||||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
|
|
||||||
hdr.Data = unsafe.Pointer(addr)
|
|
||||||
hdr.Cap = length
|
|
||||||
hdr.Len = length
|
|
||||||
|
|
||||||
// Register mapping in m and return it.
|
// Register mapping in m and return it.
|
||||||
p := &b[cap(b)-1]
|
p := &b[cap(b)-1]
|
||||||
|
@ -429,11 +423,15 @@ func Send(s int, buf []byte, flags int) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
||||||
ptr, n, err := to.sockaddr()
|
var ptr unsafe.Pointer
|
||||||
if err != nil {
|
var salen _Socklen
|
||||||
return err
|
if to != nil {
|
||||||
|
ptr, salen, err = to.sockaddr()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sendto(fd, p, flags, ptr, n)
|
return sendto(fd, p, flags, ptr, salen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetsockoptByte(fd, level, opt int, value byte) (err error) {
|
func SetsockoptByte(fd, level, opt int, value byte) (err error) {
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && gc && !ppc64le && !ppc64
|
//go:build (darwin || dragonfly || freebsd || (linux && !ppc64 && !ppc64le) || netbsd || openbsd || solaris) && gc
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
// +build darwin dragonfly freebsd linux,!ppc64,!ppc64le netbsd openbsd solaris
|
||||||
// +build gc
|
// +build gc
|
||||||
// +build !ppc64le
|
|
||||||
// +build !ppc64
|
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,10 @@ package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -55,7 +57,13 @@ func (d *Dirent) NameString() string {
|
||||||
if d == nil {
|
if d == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return string(d.Name[:d.Namlen])
|
s := string(d.Name[:])
|
||||||
|
idx := strings.IndexByte(s, 0)
|
||||||
|
if idx == -1 {
|
||||||
|
return s
|
||||||
|
} else {
|
||||||
|
return s[:idx]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
@ -1230,6 +1238,14 @@ func Readdir(dir uintptr) (*Dirent, error) {
|
||||||
return &ent, err
|
return &ent, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
|
||||||
|
r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
|
||||||
|
if int64(r0) == -1 {
|
||||||
|
err = errnoErr(Errno(e1))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func Closedir(dir uintptr) error {
|
func Closedir(dir uintptr) error {
|
||||||
_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
|
_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
|
||||||
if e != 0 {
|
if e != 0 {
|
||||||
|
@ -1821,3 +1837,158 @@ func Unmount(name string, mtm int) (err error) {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fdToPath(dirfd int) (path string, err error) {
|
||||||
|
var buffer [1024]byte
|
||||||
|
// w_ctrl()
|
||||||
|
ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
|
||||||
|
[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
|
||||||
|
if ret == 0 {
|
||||||
|
zb := bytes.IndexByte(buffer[:], 0)
|
||||||
|
if zb == -1 {
|
||||||
|
zb = len(buffer)
|
||||||
|
}
|
||||||
|
// __e2a_l()
|
||||||
|
runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
|
||||||
|
[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
|
||||||
|
return string(buffer[:zb]), nil
|
||||||
|
}
|
||||||
|
// __errno()
|
||||||
|
errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
|
||||||
|
[]uintptr{}))))
|
||||||
|
// __errno2()
|
||||||
|
errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
|
||||||
|
[]uintptr{}))
|
||||||
|
// strerror_r()
|
||||||
|
ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
|
||||||
|
[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
|
||||||
|
if ret == 0 {
|
||||||
|
zb := bytes.IndexByte(buffer[:], 0)
|
||||||
|
if zb == -1 {
|
||||||
|
zb = len(buffer)
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
|
||||||
|
var d Dirent
|
||||||
|
|
||||||
|
d.Ino = uint64(dirent.Ino)
|
||||||
|
offset, err := Telldir(dir)
|
||||||
|
if err != nil {
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Off = int64(offset)
|
||||||
|
s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
|
||||||
|
copy(d.Name[:], s)
|
||||||
|
|
||||||
|
d.Reclen = uint16(24 + len(d.NameString()))
|
||||||
|
var st Stat_t
|
||||||
|
path = path + "/" + s
|
||||||
|
err = Lstat(path, &st)
|
||||||
|
if err != nil {
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Type = uint8(st.Mode >> 24)
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||||
|
// Simulation of Getdirentries port from the Darwin implementation.
|
||||||
|
// COMMENTS FROM DARWIN:
|
||||||
|
// It's not the full required semantics, but should handle the case
|
||||||
|
// of calling Getdirentries or ReadDirent repeatedly.
|
||||||
|
// It won't handle assigning the results of lseek to *basep, or handle
|
||||||
|
// the directory being edited underfoot.
|
||||||
|
|
||||||
|
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get path from fd to avoid unavailable call (fdopendir)
|
||||||
|
path, err := fdToPath(fd)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
d, err := Opendir(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer Closedir(d)
|
||||||
|
|
||||||
|
var cnt int64
|
||||||
|
for {
|
||||||
|
var entryLE direntLE
|
||||||
|
var entrypLE *direntLE
|
||||||
|
e := readdir_r(d, &entryLE, &entrypLE)
|
||||||
|
if e != nil {
|
||||||
|
return n, e
|
||||||
|
}
|
||||||
|
if entrypLE == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if skip > 0 {
|
||||||
|
skip--
|
||||||
|
cnt++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dirent on zos has a different structure
|
||||||
|
entry, e := direntLeToDirentUnix(&entryLE, d, path)
|
||||||
|
if e != nil {
|
||||||
|
return n, e
|
||||||
|
}
|
||||||
|
|
||||||
|
reclen := int(entry.Reclen)
|
||||||
|
if reclen > len(buf) {
|
||||||
|
// Not enough room. Return for now.
|
||||||
|
// The counter will let us know where we should start up again.
|
||||||
|
// Note: this strategy for suspending in the middle and
|
||||||
|
// restarting is O(n^2) in the length of the directory. Oh well.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy entry into return buffer.
|
||||||
|
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
|
||||||
|
copy(buf, s)
|
||||||
|
|
||||||
|
buf = buf[reclen:]
|
||||||
|
n += reclen
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
// Set the seek offset of the input fd to record
|
||||||
|
// how many files we've already returned.
|
||||||
|
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDirent(fd int, buf []byte) (n int, err error) {
|
||||||
|
var base = (*uintptr)(unsafe.Pointer(new(uint64)))
|
||||||
|
return Getdirentries(fd, buf, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntIno(buf []byte) (uint64, bool) {
|
||||||
|
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntReclen(buf []byte) (uint64, bool) {
|
||||||
|
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntNamlen(buf []byte) (uint64, bool) {
|
||||||
|
reclen, ok := direntReclen(buf)
|
||||||
|
if !ok {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,7 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import "unsafe"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SysvShmAttach attaches the Sysv shared memory segment associated with the
|
// SysvShmAttach attaches the Sysv shared memory segment associated with the
|
||||||
// shared memory identifier id.
|
// shared memory identifier id.
|
||||||
|
@ -34,12 +30,7 @@ func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use unsafe to convert addr into a []byte.
|
// Use unsafe to convert addr into a []byte.
|
||||||
// TODO: convert to unsafe.Slice once we can assume Go 1.17
|
b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz))
|
||||||
var b []byte
|
|
||||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
|
|
||||||
hdr.Data = unsafe.Pointer(addr)
|
|
||||||
hdr.Cap = int(info.Segsz)
|
|
||||||
hdr.Len = int(info.Segsz)
|
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,13 +160,12 @@ func Lremovexattr(link string, attr string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Listxattr(file string, dest []byte) (sz int, err error) {
|
func Listxattr(file string, dest []byte) (sz int, err error) {
|
||||||
d := initxattrdest(dest, 0)
|
|
||||||
destsiz := len(dest)
|
destsiz := len(dest)
|
||||||
|
|
||||||
// FreeBSD won't allow you to list xattrs from multiple namespaces
|
// FreeBSD won't allow you to list xattrs from multiple namespaces
|
||||||
s := 0
|
s, pos := 0, 0
|
||||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
|
stmp, e := ListxattrNS(file, nsid, dest[pos:])
|
||||||
|
|
||||||
/* Errors accessing system attrs are ignored so that
|
/* Errors accessing system attrs are ignored so that
|
||||||
* we can implement the Linux-like behavior of omitting errors that
|
* we can implement the Linux-like behavior of omitting errors that
|
||||||
|
@ -175,66 +174,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
|
||||||
* Linux will still error if we ask for user attributes on a file that
|
* Linux will still error if we ask for user attributes on a file that
|
||||||
* we don't have read permissions on, so don't ignore those errors
|
* we don't have read permissions on, so don't ignore those errors
|
||||||
*/
|
*/
|
||||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
if e != nil {
|
||||||
continue
|
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
} else if e != nil {
|
continue
|
||||||
|
}
|
||||||
return s, e
|
return s, e
|
||||||
}
|
}
|
||||||
|
|
||||||
s += stmp
|
s += stmp
|
||||||
destsiz -= s
|
pos = s
|
||||||
if destsiz < 0 {
|
if pos > destsiz {
|
||||||
destsiz = 0
|
pos = destsiz
|
||||||
}
|
}
|
||||||
d = initxattrdest(dest, s)
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
||||||
d := initxattrdest(dest, 0)
|
|
||||||
destsiz := len(dest)
|
destsiz := len(dest)
|
||||||
|
|
||||||
s := 0
|
s, pos := 0, 0
|
||||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
|
stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
|
||||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
|
||||||
continue
|
if e != nil {
|
||||||
} else if e != nil {
|
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return s, e
|
return s, e
|
||||||
}
|
}
|
||||||
|
|
||||||
s += stmp
|
s += stmp
|
||||||
destsiz -= s
|
pos = s
|
||||||
if destsiz < 0 {
|
if pos > destsiz {
|
||||||
destsiz = 0
|
pos = destsiz
|
||||||
}
|
}
|
||||||
d = initxattrdest(dest, s)
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
||||||
d := initxattrdest(dest, 0)
|
|
||||||
destsiz := len(dest)
|
destsiz := len(dest)
|
||||||
|
|
||||||
s := 0
|
s, pos := 0, 0
|
||||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
|
stmp, e := LlistxattrNS(link, nsid, dest[pos:])
|
||||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
|
||||||
continue
|
if e != nil {
|
||||||
} else if e != nil {
|
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return s, e
|
return s, e
|
||||||
}
|
}
|
||||||
|
|
||||||
s += stmp
|
s += stmp
|
||||||
destsiz -= s
|
pos = s
|
||||||
if destsiz < 0 {
|
if pos > destsiz {
|
||||||
destsiz = 0
|
pos = destsiz
|
||||||
}
|
}
|
||||||
d = initxattrdest(dest, s)
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,40 +0,0 @@
|
||||||
// go run mksyscall.go -tags darwin,amd64,go1.13 syscall_darwin.1_13.go
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:build darwin && amd64 && go1.13
|
|
||||||
// +build darwin,amd64,go1.13
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ syscall.Errno
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func closedir(dir uintptr) (err error) {
|
|
||||||
_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var libc_closedir_trampoline_addr uintptr
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
|
|
||||||
r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
|
|
||||||
res = Errno(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var libc_readdir_r_trampoline_addr uintptr
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
|
|
|
@ -1,25 +0,0 @@
|
||||||
// go run mkasm.go darwin amd64
|
|
||||||
// Code generated by the command above; DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:build go1.13
|
|
||||||
// +build go1.13
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
|
|
||||||
JMP libc_fdopendir(SB)
|
|
||||||
|
|
||||||
GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8
|
|
||||||
DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
|
|
||||||
|
|
||||||
TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
|
|
||||||
JMP libc_closedir(SB)
|
|
||||||
|
|
||||||
GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8
|
|
||||||
DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
|
|
||||||
|
|
||||||
TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
|
|
||||||
JMP libc_readdir_r(SB)
|
|
||||||
|
|
||||||
GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8
|
|
||||||
DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
|
|
|
@ -1,8 +1,8 @@
|
||||||
// go run mksyscall.go -tags darwin,amd64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
|
// go run mksyscall.go -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build darwin && amd64 && go1.12
|
//go:build darwin && amd64
|
||||||
// +build darwin,amd64,go1.12
|
// +build darwin,amd64
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -463,6 +463,32 @@ var libc_munlockall_trampoline_addr uintptr
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func closedir(dir uintptr) (err error) {
|
||||||
|
_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_closedir_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
|
||||||
|
r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
|
||||||
|
res = Errno(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_readdir_r_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func pipe(p *[2]int32) (err error) {
|
func pipe(p *[2]int32) (err error) {
|
||||||
_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
|
_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
// go run mkasm.go darwin amd64
|
// go run mkasm.go darwin amd64
|
||||||
// Code generated by the command above; DO NOT EDIT.
|
// Code generated by the command above; DO NOT EDIT.
|
||||||
|
|
||||||
//go:build go1.12
|
|
||||||
// +build go1.12
|
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_fdopendir(SB)
|
||||||
|
|
||||||
|
GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
|
||||||
|
|
||||||
TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
|
TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
JMP libc_getgroups(SB)
|
JMP libc_getgroups(SB)
|
||||||
|
|
||||||
|
@ -174,6 +177,18 @@ TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8
|
GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8
|
||||||
DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
|
DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_closedir(SB)
|
||||||
|
|
||||||
|
GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_readdir_r(SB)
|
||||||
|
|
||||||
|
GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
|
||||||
|
|
||||||
TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
|
TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
JMP libc_pipe(SB)
|
JMP libc_pipe(SB)
|
||||||
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
// go run mksyscall.go -tags darwin,arm64,go1.13 syscall_darwin.1_13.go
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:build darwin && arm64 && go1.13
|
|
||||||
// +build darwin,arm64,go1.13
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ syscall.Errno
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func closedir(dir uintptr) (err error) {
|
|
||||||
_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var libc_closedir_trampoline_addr uintptr
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
|
|
||||||
r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
|
|
||||||
res = Errno(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var libc_readdir_r_trampoline_addr uintptr
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
|
|
|
@ -1,25 +0,0 @@
|
||||||
// go run mkasm.go darwin arm64
|
|
||||||
// Code generated by the command above; DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:build go1.13
|
|
||||||
// +build go1.13
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
|
|
||||||
JMP libc_fdopendir(SB)
|
|
||||||
|
|
||||||
GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8
|
|
||||||
DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
|
|
||||||
|
|
||||||
TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
|
|
||||||
JMP libc_closedir(SB)
|
|
||||||
|
|
||||||
GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8
|
|
||||||
DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
|
|
||||||
|
|
||||||
TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
|
|
||||||
JMP libc_readdir_r(SB)
|
|
||||||
|
|
||||||
GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8
|
|
||||||
DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
|
|
|
@ -1,8 +1,8 @@
|
||||||
// go run mksyscall.go -tags darwin,arm64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
|
// go run mksyscall.go -tags darwin,arm64 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build darwin && arm64 && go1.12
|
//go:build darwin && arm64
|
||||||
// +build darwin,arm64,go1.12
|
// +build darwin,arm64
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -463,6 +463,32 @@ var libc_munlockall_trampoline_addr uintptr
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func closedir(dir uintptr) (err error) {
|
||||||
|
_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_closedir_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
|
||||||
|
r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
|
||||||
|
res = Errno(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_readdir_r_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func pipe(p *[2]int32) (err error) {
|
func pipe(p *[2]int32) (err error) {
|
||||||
_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
|
_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
// go run mkasm.go darwin arm64
|
// go run mkasm.go darwin arm64
|
||||||
// Code generated by the command above; DO NOT EDIT.
|
// Code generated by the command above; DO NOT EDIT.
|
||||||
|
|
||||||
//go:build go1.12
|
|
||||||
// +build go1.12
|
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_fdopendir(SB)
|
||||||
|
|
||||||
|
GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
|
||||||
|
|
||||||
TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
|
TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
JMP libc_getgroups(SB)
|
JMP libc_getgroups(SB)
|
||||||
|
|
||||||
|
@ -174,6 +177,18 @@ TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8
|
GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8
|
||||||
DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
|
DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_closedir(SB)
|
||||||
|
|
||||||
|
GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_readdir_r(SB)
|
||||||
|
|
||||||
|
GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
|
||||||
|
|
||||||
TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
|
TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
JMP libc_pipe(SB)
|
JMP libc_pipe(SB)
|
||||||
|
|
||||||
|
|
|
@ -15,25 +15,19 @@ import (
|
||||||
//go:cgo_import_dynamic libc_writev writev "libc.so"
|
//go:cgo_import_dynamic libc_writev writev "libc.so"
|
||||||
//go:cgo_import_dynamic libc_pwritev pwritev "libc.so"
|
//go:cgo_import_dynamic libc_pwritev pwritev "libc.so"
|
||||||
//go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so"
|
//go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so"
|
||||||
//go:cgo_import_dynamic libc_putmsg putmsg "libc.so"
|
|
||||||
//go:cgo_import_dynamic libc_getmsg getmsg "libc.so"
|
|
||||||
|
|
||||||
//go:linkname procreadv libc_readv
|
//go:linkname procreadv libc_readv
|
||||||
//go:linkname procpreadv libc_preadv
|
//go:linkname procpreadv libc_preadv
|
||||||
//go:linkname procwritev libc_writev
|
//go:linkname procwritev libc_writev
|
||||||
//go:linkname procpwritev libc_pwritev
|
//go:linkname procpwritev libc_pwritev
|
||||||
//go:linkname procaccept4 libc_accept4
|
//go:linkname procaccept4 libc_accept4
|
||||||
//go:linkname procputmsg libc_putmsg
|
|
||||||
//go:linkname procgetmsg libc_getmsg
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
procreadv,
|
procreadv,
|
||||||
procpreadv,
|
procpreadv,
|
||||||
procwritev,
|
procwritev,
|
||||||
procpwritev,
|
procpwritev,
|
||||||
procaccept4,
|
procaccept4 syscallFunc
|
||||||
procputmsg,
|
|
||||||
procgetmsg syscallFunc
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
@ -106,23 +100,3 @@ func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) {
|
|
||||||
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = e1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) {
|
|
||||||
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = e1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -2151,3 +2151,13 @@ func setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) {
|
||||||
|
_, _, e1 := RawSyscall6(SYS_RT_SIGPROCMASK, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oldset)), uintptr(sigsetsize), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -287,46 +287,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
|
func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
|
||||||
r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
|
r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
|
||||||
n = int(r0)
|
n = int(r0)
|
||||||
|
|
|
@ -334,36 +334,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
|
_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
@ -374,16 +344,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Shutdown(fd int, how int) (err error) {
|
func Shutdown(fd int, how int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -412,46 +412,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Shutdown(fd int, how int) (err error) {
|
func Shutdown(fd int, how int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -289,36 +289,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func setrlimit(resource int, rlim *Rlimit) (err error) {
|
func setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
|
_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
@ -329,16 +299,6 @@ func setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Shutdown(fd int, how int) (err error) {
|
func Shutdown(fd int, how int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -223,46 +223,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Shutdown(fd int, how int) (err error) {
|
func Shutdown(fd int, how int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -248,46 +248,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Shutdown(fd int, how int) (err error) {
|
func Shutdown(fd int, how int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
|
@ -278,36 +278,6 @@ func setfsuid(uid int) (prev int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setregid(rgid int, egid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresgid(rgid int, egid int, sgid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setresuid(ruid int, euid int, suid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
|
_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
@ -318,16 +288,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Setreuid(ruid int, euid int) (err error) {
|
|
||||||
_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Shutdown(fd int, how int) (err error) {
|
func Shutdown(fd int, how int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue