2
2
//
3
3
// For the full copyright and license information, please view the LICENSE
4
4
// file that was distributed with this source code.
5
+ // spell-checker:ignore setvbuf
6
+ use std:: process:: Command ;
5
7
use uutests:: new_ucmd;
6
8
#[ cfg( not( target_os = "windows" ) ) ]
7
9
use uutests:: util:: TestScenario ;
@@ -34,6 +36,9 @@ fn test_no_such() {
34
36
#[ test]
35
37
fn test_stdbuf_unbuffered_stdout ( ) {
36
38
// This is a basic smoke test
39
+ // Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
40
+ // for simple, short-lived commands. It does not guarantee that buffering is actually modified or that
41
+ // libstdbuf is loaded and functioning correctly.
37
42
new_ucmd ! ( )
38
43
. args ( & [ "-o0" , "head" ] )
39
44
. pipe_in ( "The quick brown fox jumps over the lazy dog." )
@@ -44,6 +49,9 @@ fn test_stdbuf_unbuffered_stdout() {
44
49
#[ cfg( all( not( target_os = "windows" ) , not( target_os = "openbsd" ) ) ) ]
45
50
#[ test]
46
51
fn test_stdbuf_line_buffered_stdout ( ) {
52
+ // Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
53
+ // for simple, short-lived commands. It does not guarantee that buffering is actually modified or that
54
+ // libstdbuf is loaded and functioning correctly.
47
55
new_ucmd ! ( )
48
56
. args ( & [ "-oL" , "head" ] )
49
57
. pipe_in ( "The quick brown fox jumps over the lazy dog." )
@@ -105,3 +113,52 @@ fn test_stdbuf_invalid_mode_fails() {
105
113
}
106
114
}
107
115
}
116
+
117
+ #[ cfg( all( not( target_os = "windows" ) , not( target_os = "openbsd" ) ) ) ]
118
+ #[ test]
119
+ fn test_setvbuf_resolution ( ) {
120
+ // Run a simple program with LD_DEBUG=symbols to see which setvbuf is being used
121
+ // Written in a way that it can run with cross-rs and be used as regression test
122
+ // for https://github.com/uutils/coreutils/issues/6591
123
+
124
+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
125
+ let coreutils_bin = & scene. bin_path ;
126
+
127
+ // Test with our own echo (should have the correct architecture even when cross-compiled using cross-rs,
128
+ // in which case the "system" echo will be the host architecture)
129
+ let uutils_echo_cmd = format ! (
130
+ "LD_DEBUG=symbols {} stdbuf -oL {} echo test 2>&1" ,
131
+ coreutils_bin. display( ) ,
132
+ coreutils_bin. display( )
133
+ ) ;
134
+ let uutils_output = Command :: new ( "sh" )
135
+ . arg ( "-c" )
136
+ . arg ( & uutils_echo_cmd)
137
+ . output ( )
138
+ . expect ( "Failed to run uutils echo test" ) ;
139
+
140
+ let uutils_debug = String :: from_utf8_lossy ( & uutils_output. stdout ) ;
141
+
142
+ // Check if libstdbuf.so / libstdbuf.dylib is in the lookup path. The log should contain something like this:
143
+ // "symbol=setvbuf; lookup in file=/tmp/.tmp0mfmCg/libstdbuf.so [0]"
144
+ let libstdbuf_in_path = uutils_debug. contains ( "symbol=setvbuf" )
145
+ && uutils_debug. contains ( "lookup in file=" )
146
+ && uutils_debug. contains ( "libstdbuf" ) ;
147
+
148
+ // Check for lack of architecture mismatch error. The potential error message is:
149
+ // "ERROR: ld.so: object '/tmp/.tmpCLq8jl/libstdbuf.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored."
150
+ let no_arch_mismatch = !uutils_debug. contains ( "cannot be preloaded" ) ;
151
+
152
+ println ! ( "libstdbuf in lookup path: {}" , libstdbuf_in_path) ;
153
+ println ! ( "No architecture mismatch: {}" , no_arch_mismatch) ;
154
+ println ! ( "LD_DEBUG output: {}" , uutils_debug) ;
155
+
156
+ assert ! (
157
+ libstdbuf_in_path,
158
+ "libstdbuf should be in lookup path with uutils echo"
159
+ ) ;
160
+ assert ! (
161
+ no_arch_mismatch,
162
+ "uutils echo should not show architecture mismatch"
163
+ ) ;
164
+ }
0 commit comments