77package unix_test
88
99import (
10+ "bytes"
1011 "errors"
1112 "flag"
1213 "fmt"
@@ -202,7 +203,7 @@ func TestSignalNum(t *testing.T) {
202203
203204func TestFcntlInt (t * testing.T ) {
204205 t .Parallel ()
205- file , err := os .Create (filepath .Join (t .TempDir (), "TestFnctlInt" ))
206+ file , err := os .Create (filepath .Join (t .TempDir (), t . Name () ))
206207 if err != nil {
207208 t .Fatal (err )
208209 }
@@ -217,10 +218,27 @@ func TestFcntlInt(t *testing.T) {
217218 }
218219}
219220
221+ func TestFcntlInt2 (t * testing.T ) {
222+ t .Parallel ()
223+ file , err := os .Create (filepath .Join (t .TempDir (), t .Name ()))
224+ if err != nil {
225+ t .Fatal (err )
226+ }
227+ defer file .Close ()
228+ f := file .Fd ()
229+ flags , err := unix .Fcntl (f , unix .F_GETFD , 0 )
230+ if err != nil {
231+ t .Fatal (err )
232+ }
233+ if flags & unix .FD_CLOEXEC == 0 {
234+ t .Errorf ("flags %#x do not include FD_CLOEXEC" , flags )
235+ }
236+ }
237+
220238// TestFcntlFlock tests whether the file locking structure matches
221239// the calling convention of each kernel.
222240func TestFcntlFlock (t * testing.T ) {
223- name := filepath .Join (os .TempDir (), "TestFcntlFlock" )
241+ name := filepath .Join (t .TempDir (), "TestFcntlFlock" )
224242 fd , err := unix .Open (name , unix .O_CREAT | unix .O_RDWR | unix .O_CLOEXEC , 0 )
225243 if err != nil {
226244 t .Fatalf ("Open failed: %v" , err )
@@ -236,6 +254,23 @@ func TestFcntlFlock(t *testing.T) {
236254 }
237255}
238256
257+ func TestFcntlFlock2 (t * testing.T ) {
258+ name := filepath .Join (t .TempDir (), "TestFcntlFlock2" )
259+ fd , err := unix .Open (name , unix .O_CREAT | unix .O_RDWR | unix .O_CLOEXEC , 0 )
260+ if err != nil {
261+ t .Fatalf ("Open failed: %v" , err )
262+ }
263+ defer unix .Unlink (name )
264+ defer unix .Close (fd )
265+ flock := unix.Flock_t {
266+ Type : unix .F_RDLCK ,
267+ Start : 0 , Len : 0 , Whence : 1 ,
268+ }
269+ if v , err := unix .Fcntl (uintptr (fd ), unix .F_GETLK , & flock ); err != nil {
270+ t .Fatalf ("FcntlFlock failed: %d %v" , v , err )
271+ }
272+ }
273+
239274// TestPassFD tests passing a file descriptor over a Unix socket.
240275//
241276// This test involved both a parent and child process. The parent
@@ -249,8 +284,6 @@ func TestPassFD(t *testing.T) {
249284 return
250285 }
251286
252- tempDir := t .TempDir ()
253-
254287 fds , err := unix .Socketpair (unix .AF_LOCAL , unix .SOCK_STREAM , 0 )
255288 if err != nil {
256289 t .Fatalf ("Socketpair: %v" , err )
@@ -262,7 +295,7 @@ func TestPassFD(t *testing.T) {
262295 defer writeFile .Close ()
263296 defer readFile .Close ()
264297
265- cmd := exec .Command (os .Args [0 ], "-test.run=^TestPassFD$" , "--" , tempDir )
298+ cmd := exec .Command (os .Args [0 ], "-test.run=^TestPassFD$" , "--" , t . TempDir () )
266299 cmd .Env = []string {"GO_WANT_HELPER_PROCESS=1" }
267300 if lp := os .Getenv ("LD_LIBRARY_PATH" ); lp != "" {
268301 cmd .Env = append (cmd .Env , "LD_LIBRARY_PATH=" + lp )
@@ -371,7 +404,7 @@ func passFDChild() {
371404 }
372405}
373406
374- // TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
407+ // TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage, ParseOneSocketControlMessage,
375408// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
376409func TestUnixRightsRoundtrip (t * testing.T ) {
377410 testCases := [... ][][]int {
@@ -399,6 +432,23 @@ func TestUnixRightsRoundtrip(t *testing.T) {
399432 if len (scms ) != len (testCase ) {
400433 t .Fatalf ("expected %v SocketControlMessage; got scms = %#v" , len (testCase ), scms )
401434 }
435+
436+ var c int
437+ for len (b ) > 0 {
438+ hdr , data , remainder , err := unix .ParseOneSocketControlMessage (b )
439+ if err != nil {
440+ t .Fatalf ("ParseOneSocketControlMessage: %v" , err )
441+ }
442+ if scms [c ].Header != hdr || ! bytes .Equal (scms [c ].Data , data ) {
443+ t .Fatal ("expected SocketControlMessage header and data to match" )
444+ }
445+ b = remainder
446+ c ++
447+ }
448+ if c != len (scms ) {
449+ t .Fatalf ("expected %d SocketControlMessages; got %d" , len (scms ), c )
450+ }
451+
402452 for i , scm := range scms {
403453 gotFds , err := unix .ParseUnixRights (& scm )
404454 if err != nil {
@@ -474,6 +524,12 @@ func TestRlimit(t *testing.T) {
474524 if err != nil {
475525 t .Fatalf ("Setrlimit: restore failed: %#v %v" , rlimit , err )
476526 }
527+
528+ // make sure RLIM_INFINITY can be assigned to Rlimit members
529+ _ = unix.Rlimit {
530+ Cur : unix .RLIM_INFINITY ,
531+ Max : unix .RLIM_INFINITY ,
532+ }
477533}
478534
479535func TestSeekFailure (t * testing.T ) {
@@ -497,9 +553,9 @@ func TestSetsockoptString(t *testing.T) {
497553}
498554
499555func TestDup (t * testing.T ) {
500- file , err := os .Create (filepath .Join (t .TempDir (), "TestDup" ))
556+ file , err := os .Create (filepath .Join (t .TempDir (), t . Name () ))
501557 if err != nil {
502- t .Fatalf ( "Tempfile failed: %v" , err )
558+ t .Fatal ( err )
503559 }
504560 defer file .Close ()
505561 f := int (file .Fd ())
@@ -654,25 +710,21 @@ func touch(t *testing.T, name string) {
654710}
655711
656712// chtmpdir changes the working directory to a new temporary directory and
657- // provides a cleanup function. Used when PWD is read-only.
658- func chtmpdir (t * testing.T ) func () {
713+ // sets up a cleanup function. Used when PWD is read-only.
714+ func chtmpdir (t * testing.T ) {
715+ t .Helper ()
659716 oldwd , err := os .Getwd ()
660717 if err != nil {
661- t .Fatalf ("chtmpdir: %v" , err )
662- }
663- d , err := os .MkdirTemp ("" , "test" )
664- if err != nil {
665- t .Fatalf ("chtmpdir: %v" , err )
718+ t .Fatal (err )
666719 }
667- if err := os .Chdir (d ); err != nil {
668- t .Fatalf ( "chtmpdir: %v" , err )
720+ if err := os .Chdir (t . TempDir () ); err != nil {
721+ t .Fatal ( err )
669722 }
670- return func () {
723+ t . Cleanup ( func () {
671724 if err := os .Chdir (oldwd ); err != nil {
672- t .Fatalf ( "chtmpdir: %v" , err )
725+ t .Fatal ( err )
673726 }
674- os .RemoveAll (d )
675- }
727+ })
676728}
677729
678730func TestLegacyMountUnmount (t * testing.T ) {
@@ -2993,7 +3045,7 @@ func TestUnlinkat(t *testing.T) {
29933045}
29943046
29953047func TestRenameat (t * testing.T ) {
2996- defer chtmpdir (t )( )
3048+ chtmpdir (t )
29973049
29983050 from , to := "renamefrom" , "renameto"
29993051
@@ -3016,7 +3068,7 @@ func TestRenameat(t *testing.T) {
30163068}
30173069
30183070func TestRenameat2 (t * testing.T ) {
3019- defer chtmpdir (t )( )
3071+ chtmpdir (t )
30203072
30213073 from , to := "renamefrom" , "renameto"
30223074
@@ -3050,7 +3102,7 @@ func TestRenameat2(t *testing.T) {
30503102}
30513103
30523104func TestFchmodat (t * testing.T ) {
3053- defer chtmpdir (t )( )
3105+ chtmpdir (t )
30543106
30553107 touch (t , "file1" )
30563108 err := os .Symlink ("file1" , "symlink1" )
@@ -3148,7 +3200,7 @@ func compareStat_t(t *testing.T, otherStat string, st1, st2 *unix.Stat_t) {
31483200}
31493201
31503202func TestFstatat (t * testing.T ) {
3151- defer chtmpdir (t )( )
3203+ chtmpdir (t )
31523204
31533205 touch (t , "file1" )
31543206
@@ -3749,3 +3801,77 @@ func TestConsole2modify(t *testing.T) {
37493801
37503802 t .Logf ("Got %s %x\n " , unix .ZosEbcdicBytesToString (modstr [:], true ), cmsg_cmd )
37513803}
3804+ func TestTty (t * testing.T ) {
3805+ ptmxfd , err := unix .Posix_openpt (unix .O_RDWR )
3806+ if err != nil {
3807+ t .Fatalf ("Posix_openpt %+v\n " , err )
3808+ }
3809+ t .Logf ("ptmxfd %v\n " , ptmxfd )
3810+
3811+ // convert to EBCDIC
3812+ cvtreq := unix.F_cnvrt {Cvtcmd : unix .SETCVTON , Pccsid : 0 , Fccsid : 1047 }
3813+ if _ , err = unix .Fcntl (uintptr (ptmxfd ), unix .F_CONTROL_CVT , & cvtreq ); err != nil {
3814+ t .Fatalf ("fcntl F_CONTROL_CVT %+v\n " , err )
3815+ }
3816+ p := os .NewFile (uintptr (ptmxfd ), "/dev/ptmx" )
3817+ if p == nil {
3818+ t .Fatalf ("NewFile %d /dev/ptmx failed\n " , ptmxfd )
3819+ }
3820+
3821+ // In case of error after this point, make sure we close the ptmx fd.
3822+ defer func () {
3823+ if err != nil {
3824+ _ = p .Close () // Best effort.
3825+ }
3826+ }()
3827+ sname , err := unix .Ptsname (ptmxfd )
3828+ if err != nil {
3829+ t .Fatalf ("Ptsname %+v\n " , err )
3830+ }
3831+ t .Logf ("sname %v\n " , sname )
3832+
3833+ _ , err = unix .Grantpt (ptmxfd )
3834+ if err != nil {
3835+ t .Fatalf ("Grantpt %+v\n " , err )
3836+ }
3837+
3838+ if _ , err = unix .Unlockpt (ptmxfd ); err != nil {
3839+ t .Fatalf ("Unlockpt %+v\n " , err )
3840+ }
3841+
3842+ ptsfd , err := syscall .Open (sname , os .O_RDWR | syscall .O_NOCTTY , 0 )
3843+ if err != nil {
3844+ t .Fatalf ("Open %s %+v\n " , sname , err )
3845+ }
3846+ if _ , err = unix .Fcntl (uintptr (ptsfd ), unix .F_CONTROL_CVT , & cvtreq ); err != nil {
3847+
3848+ t .Fatalf ("fcntl F_CONTROL_CVT ptsfd %+v\n " , err )
3849+
3850+ }
3851+
3852+ tt := os .NewFile (uintptr (ptsfd ), sname )
3853+ if err != nil {
3854+ t .Fatalf ("NewFile %d %+v %+v\n " , ptsfd , sname , err )
3855+ }
3856+ text := []byte ("11111111" )
3857+
3858+ n , err := tt .Write (text )
3859+ if err != nil {
3860+ t .Fatalf ("ptsfd Write %+v\n " , err )
3861+ }
3862+ t .Logf ("bytes %d\n " , n )
3863+
3864+ var buffer [1024 ]byte
3865+
3866+ n , err = p .Read (buffer [:n ])
3867+ if err != nil {
3868+ t .Fatalf ("ptmx read %+v\n " , err )
3869+ }
3870+ t .Logf ("Buffer %+v\n " , buffer [:n ])
3871+
3872+ if ! bytes .Equal (text , buffer [:n ]) {
3873+ t .Fatalf ("Expected %+v, read %+v\n " , text , buffer [:n ])
3874+
3875+ }
3876+
3877+ }
0 commit comments