7
7
package unix_test
8
8
9
9
import (
10
+ "bytes"
10
11
"errors"
11
12
"flag"
12
13
"fmt"
@@ -202,7 +203,7 @@ func TestSignalNum(t *testing.T) {
202
203
203
204
func TestFcntlInt (t * testing.T ) {
204
205
t .Parallel ()
205
- file , err := os .Create (filepath .Join (t .TempDir (), "TestFnctlInt" ))
206
+ file , err := os .Create (filepath .Join (t .TempDir (), t . Name () ))
206
207
if err != nil {
207
208
t .Fatal (err )
208
209
}
@@ -217,10 +218,27 @@ func TestFcntlInt(t *testing.T) {
217
218
}
218
219
}
219
220
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
+
220
238
// TestFcntlFlock tests whether the file locking structure matches
221
239
// the calling convention of each kernel.
222
240
func TestFcntlFlock (t * testing.T ) {
223
- name := filepath .Join (os .TempDir (), "TestFcntlFlock" )
241
+ name := filepath .Join (t .TempDir (), "TestFcntlFlock" )
224
242
fd , err := unix .Open (name , unix .O_CREAT | unix .O_RDWR | unix .O_CLOEXEC , 0 )
225
243
if err != nil {
226
244
t .Fatalf ("Open failed: %v" , err )
@@ -236,6 +254,23 @@ func TestFcntlFlock(t *testing.T) {
236
254
}
237
255
}
238
256
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
+
239
274
// TestPassFD tests passing a file descriptor over a Unix socket.
240
275
//
241
276
// This test involved both a parent and child process. The parent
@@ -249,8 +284,6 @@ func TestPassFD(t *testing.T) {
249
284
return
250
285
}
251
286
252
- tempDir := t .TempDir ()
253
-
254
287
fds , err := unix .Socketpair (unix .AF_LOCAL , unix .SOCK_STREAM , 0 )
255
288
if err != nil {
256
289
t .Fatalf ("Socketpair: %v" , err )
@@ -262,7 +295,7 @@ func TestPassFD(t *testing.T) {
262
295
defer writeFile .Close ()
263
296
defer readFile .Close ()
264
297
265
- cmd := exec .Command (os .Args [0 ], "-test.run=^TestPassFD$" , "--" , tempDir )
298
+ cmd := exec .Command (os .Args [0 ], "-test.run=^TestPassFD$" , "--" , t . TempDir () )
266
299
cmd .Env = []string {"GO_WANT_HELPER_PROCESS=1" }
267
300
if lp := os .Getenv ("LD_LIBRARY_PATH" ); lp != "" {
268
301
cmd .Env = append (cmd .Env , "LD_LIBRARY_PATH=" + lp )
@@ -371,7 +404,7 @@ func passFDChild() {
371
404
}
372
405
}
373
406
374
- // TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
407
+ // TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage, ParseOneSocketControlMessage,
375
408
// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
376
409
func TestUnixRightsRoundtrip (t * testing.T ) {
377
410
testCases := [... ][][]int {
@@ -399,6 +432,23 @@ func TestUnixRightsRoundtrip(t *testing.T) {
399
432
if len (scms ) != len (testCase ) {
400
433
t .Fatalf ("expected %v SocketControlMessage; got scms = %#v" , len (testCase ), scms )
401
434
}
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
+
402
452
for i , scm := range scms {
403
453
gotFds , err := unix .ParseUnixRights (& scm )
404
454
if err != nil {
@@ -474,6 +524,12 @@ func TestRlimit(t *testing.T) {
474
524
if err != nil {
475
525
t .Fatalf ("Setrlimit: restore failed: %#v %v" , rlimit , err )
476
526
}
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
+ }
477
533
}
478
534
479
535
func TestSeekFailure (t * testing.T ) {
@@ -497,9 +553,9 @@ func TestSetsockoptString(t *testing.T) {
497
553
}
498
554
499
555
func 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 () ))
501
557
if err != nil {
502
- t .Fatalf ( "Tempfile failed: %v" , err )
558
+ t .Fatal ( err )
503
559
}
504
560
defer file .Close ()
505
561
f := int (file .Fd ())
@@ -654,25 +710,21 @@ func touch(t *testing.T, name string) {
654
710
}
655
711
656
712
// 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 ()
659
716
oldwd , err := os .Getwd ()
660
717
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 )
666
719
}
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 )
669
722
}
670
- return func () {
723
+ t . Cleanup ( func () {
671
724
if err := os .Chdir (oldwd ); err != nil {
672
- t .Fatalf ( "chtmpdir: %v" , err )
725
+ t .Fatal ( err )
673
726
}
674
- os .RemoveAll (d )
675
- }
727
+ })
676
728
}
677
729
678
730
func TestLegacyMountUnmount (t * testing.T ) {
@@ -2993,7 +3045,7 @@ func TestUnlinkat(t *testing.T) {
2993
3045
}
2994
3046
2995
3047
func TestRenameat (t * testing.T ) {
2996
- defer chtmpdir (t )( )
3048
+ chtmpdir (t )
2997
3049
2998
3050
from , to := "renamefrom" , "renameto"
2999
3051
@@ -3016,7 +3068,7 @@ func TestRenameat(t *testing.T) {
3016
3068
}
3017
3069
3018
3070
func TestRenameat2 (t * testing.T ) {
3019
- defer chtmpdir (t )( )
3071
+ chtmpdir (t )
3020
3072
3021
3073
from , to := "renamefrom" , "renameto"
3022
3074
@@ -3050,7 +3102,7 @@ func TestRenameat2(t *testing.T) {
3050
3102
}
3051
3103
3052
3104
func TestFchmodat (t * testing.T ) {
3053
- defer chtmpdir (t )( )
3105
+ chtmpdir (t )
3054
3106
3055
3107
touch (t , "file1" )
3056
3108
err := os .Symlink ("file1" , "symlink1" )
@@ -3148,7 +3200,7 @@ func compareStat_t(t *testing.T, otherStat string, st1, st2 *unix.Stat_t) {
3148
3200
}
3149
3201
3150
3202
func TestFstatat (t * testing.T ) {
3151
- defer chtmpdir (t )( )
3203
+ chtmpdir (t )
3152
3204
3153
3205
touch (t , "file1" )
3154
3206
@@ -3749,3 +3801,77 @@ func TestConsole2modify(t *testing.T) {
3749
3801
3750
3802
t .Logf ("Got %s %x\n " , unix .ZosEbcdicBytesToString (modstr [:], true ), cmsg_cmd )
3751
3803
}
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