82
82
#![ doc( html_root_url = "https://docs.rs/jobserver/0.1" ) ]
83
83
84
84
use std:: env;
85
+ use std:: ffi:: OsString ;
85
86
use std:: io;
86
87
use std:: process:: Command ;
87
88
use std:: sync:: { Arc , Condvar , Mutex , MutexGuard } ;
88
89
90
+ mod error;
89
91
#[ cfg( unix) ]
90
92
#[ path = "unix.rs" ]
91
93
mod imp;
@@ -151,40 +153,30 @@ struct HelperInner {
151
153
consumer_done : bool ,
152
154
}
153
155
154
- /// Error type for `from_env` function.
156
+ use error:: FromEnvErrorInner ;
157
+ pub use error:: { FromEnvError , FromEnvErrorKind } ;
158
+
159
+ /// Return type for `from_env_ext` function.
155
160
#[ derive( Debug ) ]
156
- pub enum ErrFromEnv {
157
- /// There isn't env var, that describes jobserver to inherit.
158
- IsNotConfigured ,
159
- /// Cannot connect following this process's environment.
160
- PlatformSpecific {
161
- /// Error.
162
- err : io:: Error ,
163
- /// Name of gotten env var.
164
- env : & ' static str ,
165
- /// Value of gotten env var.
166
- var : String ,
167
- } ,
161
+ pub struct FromEnv {
162
+ /// Result of trying to get jobserver client from env.
163
+ pub client : Result < Client , FromEnvError > ,
164
+ /// Name and value of the environment variable.
165
+ /// `None` if no relevant environment variable is found.
166
+ pub var : Option < ( & ' static str , OsString ) > ,
168
167
}
169
168
170
- impl std:: fmt:: Display for ErrFromEnv {
171
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
172
- match self {
173
- ErrFromEnv :: IsNotConfigured => {
174
- write ! ( f, "couldn't find relevant environment variable" )
175
- }
176
- ErrFromEnv :: PlatformSpecific { err, env, var } => {
177
- write ! ( f, "{err} ({env}={var}" )
178
- }
169
+ impl FromEnv {
170
+ fn new_ok ( client : Client , var_name : & ' static str , var_value : OsString ) -> FromEnv {
171
+ FromEnv {
172
+ client : Ok ( client) ,
173
+ var : Some ( ( var_name, var_value) ) ,
179
174
}
180
175
}
181
- }
182
-
183
- impl std:: error:: Error for ErrFromEnv {
184
- fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
185
- match self {
186
- ErrFromEnv :: IsNotConfigured => None ,
187
- ErrFromEnv :: PlatformSpecific { err, .. } => Some ( err) ,
176
+ fn new_err ( kind : FromEnvErrorInner , var_name : & ' static str , var_value : OsString ) -> FromEnv {
177
+ FromEnv {
178
+ client : Err ( FromEnvError { inner : kind } ) ,
179
+ var : Some ( ( var_name, var_value) ) ,
188
180
}
189
181
}
190
182
}
@@ -234,10 +226,10 @@ impl Client {
234
226
///
235
227
/// # Return value
236
228
///
229
+ /// `FromEnv` contains result and relevant environment variable.
237
230
/// If a jobserver was found in the environment and it looks correct then
238
- /// `Ok` of the connected client will be returned. If no relevant env var
239
- /// was found then `Err(IsNotConfigured)` will be returned. In other cases
240
- /// `Err(PlatformSpecific)` will be returned.
231
+ /// result with the connected client will be returned. In other cases
232
+ /// result will contain `Err(FromEnvErr)`.
241
233
///
242
234
/// Note that on Unix the `Client` returned **takes ownership of the file
243
235
/// descriptors specified in the environment**. Jobservers on Unix are
@@ -250,8 +242,8 @@ impl Client {
250
242
/// with `CLOEXEC` so they're not automatically inherited by spawned
251
243
/// children.
252
244
///
253
- /// On unix if `unix_check_is_pipe ` enabled this function will check if
254
- /// provided files are actually pipes.
245
+ /// On unix if `check_pipe ` enabled this function will check if provided
246
+ /// files are actually pipes.
255
247
///
256
248
/// # Safety
257
249
///
@@ -269,27 +261,42 @@ impl Client {
269
261
///
270
262
/// Note, though, that on Windows it should be safe to call this function
271
263
/// any number of times.
272
- pub unsafe fn from_env_ext ( check_pipe : bool ) -> Result < Client , ErrFromEnv > {
273
- let ( env, var ) = [ "CARGO_MAKEFLAGS" , "MAKEFLAGS" , "MFLAGS" ]
264
+ pub unsafe fn from_env_ext ( check_pipe : bool ) -> FromEnv {
265
+ let ( env, var_os ) = match [ "CARGO_MAKEFLAGS" , "MAKEFLAGS" , "MFLAGS" ]
274
266
. iter ( )
275
- . map ( |& env| env:: var ( env) . map ( |var| ( env, var) ) )
276
- . find_map ( |p| p. ok ( ) )
277
- . ok_or ( ErrFromEnv :: IsNotConfigured ) ?;
267
+ . map ( |& env| env:: var_os ( env) . map ( |var| ( env, var) ) )
268
+ . find_map ( |p| p)
269
+ {
270
+ Some ( ( env, var_os) ) => ( env, var_os) ,
271
+ None => return FromEnv :: new_err ( FromEnvErrorInner :: NoEnvVar , "" , Default :: default ( ) ) ,
272
+ } ;
273
+
274
+ let var = match var_os. to_str ( ) {
275
+ Some ( var) => var,
276
+ None => {
277
+ let err = FromEnvErrorInner :: CannotParse ( "not valid UTF-8" . to_string ( ) ) ;
278
+ return FromEnv :: new_err ( err, env, var_os) ;
279
+ }
280
+ } ;
278
281
279
- let ( arg, pos) = [ "--jobserver-fds=" , "--jobserver-auth=" ]
282
+ let ( arg, pos) = match [ "--jobserver-fds=" , "--jobserver-auth=" ]
280
283
. iter ( )
281
284
. map ( |& arg| var. find ( arg) . map ( |pos| ( arg, pos) ) )
282
285
. find_map ( |pos| pos)
283
- . ok_or ( ErrFromEnv :: IsNotConfigured ) ?;
286
+ {
287
+ Some ( ( arg, pos) ) => ( arg, pos) ,
288
+ None => {
289
+ let err = FromEnvErrorInner :: CannotParse (
290
+ "expected `--jobserver-fds=` or `--jobserver-auth=`" . to_string ( ) ,
291
+ ) ;
292
+ return FromEnv :: new_err ( err, env, var_os) ;
293
+ }
294
+ } ;
284
295
285
296
let s = var[ pos + arg. len ( ) ..] . split ( ' ' ) . next ( ) . unwrap ( ) ;
286
- #[ cfg( unix) ]
287
- let imp_client = imp:: Client :: open ( s, check_pipe) ;
288
- #[ cfg( not( unix) ) ]
289
- let imp_client = imp:: Client :: open ( s) ;
290
- match imp_client {
291
- Ok ( c) => Ok ( Client { inner : Arc :: new ( c) } ) ,
292
- Err ( err) => Err ( ErrFromEnv :: PlatformSpecific { err, env, var } ) ,
297
+ match imp:: Client :: open ( s, check_pipe) {
298
+ Ok ( c) => FromEnv :: new_ok ( Client { inner : Arc :: new ( c) } , env, var_os) ,
299
+ Err ( err) => FromEnv :: new_err ( err, env, var_os) ,
293
300
}
294
301
}
295
302
@@ -298,7 +305,7 @@ impl Client {
298
305
///
299
306
/// Wraps `from_env_ext` and discards error details.
300
307
pub unsafe fn from_env ( ) -> Option < Client > {
301
- Self :: from_env_ext ( false ) . ok ( )
308
+ Self :: from_env_ext ( false ) . client . ok ( )
302
309
}
303
310
304
311
/// Acquires a token from this jobserver client.
0 commit comments