Rev 24 | Rev 26 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 24 | Rev 25 | ||
---|---|---|---|
Line 318... | Line 318... | ||
318 | char *token; |
318 | char *token; |
319 | 319 | ||
320 | // resolve possible environment variables in pathname |
320 | // resolve possible environment variables in pathname |
321 | pathname_without_envvars = resolve_envvars (pathname); |
321 | pathname_without_envvars = resolve_envvars (pathname); |
322 | 322 | ||
- | 323 | // NOTE: the QNX documentation states: |
|
- | 324 | // "- If path starts with a slash (/) on a Linux development host, or a disk volume label (i.e., drive letter and a colon) followed by a backslash (\) on a Windows host, the path is absolute and mkifs looks for the file at that exact host location. [...] |
|
- | 325 | // - If path contains a slash or backslash character that's not at the start, the path is relative and mkifs tries to resolve it relative to the current working directory (CWD). |
|
- | 326 | // - If path does not contain a directory separator or the file could not be found relative to the CWD, mkifs tries to resolve it relative to all directories given in the search attribute, in succession." |
|
- | 327 | ||
323 | // is it an absolute pathname (POSIX and Windows variants) |
328 | // is it an absolute pathname (POSIX and Windows variants) ? |
324 | if (IS_DIRSEP ( |
329 | if (IS_DIRSEP (pathname_without_envvars[0]) |
325 | #ifdef _WIN32 |
330 | #ifdef _WIN32 |
326 | || (isalpha ( |
331 | || (isalpha (pathname_without_envvars[0]) && (pathname_without_envvars[1] == ':') && IS_DIRSEP (pathname_without_envvars[2])) |
327 | || (strchr (pathname, '\\') != NULL) |
- | |
328 | #endif // _WIN32 |
332 | #endif // _WIN32 |
329 | || (strchr (pathname, '/') != NULL) |
- | |
330 | ) |
333 | ) |
331 | return (pathname_without_envvars); // in this case, it MUST exist at its designated location |
334 | return (pathname_without_envvars); // in this case, it MUST exist at its designated location |
332 | else // what we've been given is just a basename, so search it among the search paths we have |
- | |
333 | { |
- | |
334 | // QNX docs: |
- | |
335 | // When searching for host files to be included in the image, search the default paths used for storing binaries within the specified directory before searching the default paths within $QNX_TARGET. |
- | |
336 | // You can define multiple -r options; each adds a set of paths to search for files. |
- | |
337 | // The -r options are evaluated from left to right meaning the paths prefixed with the first (leftmost) rootdir are searched first, then those prefixed with the second rootdir, and so on. |
- | |
338 | // Normally, mkifs searches any paths defined in $MKIFS_PATH when it was called and then the default paths within $QNX_TARGET. |
- | |
339 | // The default paths are based on the CPU architecture specified by $PROCESSOR and $PROCESSOR_BASE. |
- | |
340 | // If you specify -r options, mkifs searches the default paths prefixed with each dir variable before searching those within $QNX_TARGET. |
- | |
341 | // These paths are: |
- | |
342 | // dir/${PROCESSOR}/sbin |
- | |
343 | // dir/${PROCESSOR}/usr/sbin |
- | |
344 | // dir/${PROCESSOR}/boot/sys |
- | |
345 | // dir/${PROCESSOR_BASE}/boot/sys |
- | |
346 | // dir/${PROCESSOR}/bin |
- | |
347 | // dir/${PROCESSOR}/usr/bin |
- | |
348 | // dir/${PROCESSOR}/lib |
- | |
349 | // dir/${PROCESSOR}/lib/dll |
- | |
350 | // dir/${PROCESSOR}/usr/lib |
- | |
351 | // NOTE: The structure of the directory paths under dir must be identical to that of the default paths under $QNX_TARGET, but the root dir itself may be any path you choose. |
- | |
352 | // For example, if you wanted to include /scratch/aarch64le/sbin/devb-sata, you would specify a -r option like this: |
- | |
353 | // -r /scratch |
- | |
354 | // Note that you don't include $PROCESSOR or $PROCESSOR_BASE in dir. |
- | |
355 | 335 | ||
356 |
|
336 | // else is it a relative pathname ? |
357 |
|
337 | else if (((strchr (pathname_without_envvars, '/') != NULL) |
- | 338 | #ifdef _WIN32 |
|
358 |
|
339 | || (strchr (pathname_without_envvars, '\\') != NULL) |
- | 340 | #endif // _WIN32 |
|
- | 341 | ) && (stat (pathname_without_envvars, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
|
- | 342 | return (pathname_without_envvars); // in this case, see if it exists relatively to the current working directory, and if it does, return it |
|
359 | 343 | ||
360 |
|
344 | // what we've been given is just a basename, so search it among the search paths we have |
361 | if (resolved_pathname == NULL) |
- | |
362 | { |
- | |
363 | resolved_pathname = malloc (MAXPATHLEN); |
- | |
364 | ASSERT_WITH_ERRNO (resolved_pathname); |
- | |
365 | } |
- | |
366 | 345 | ||
- | 346 | // QNX docs: |
|
367 |
|
347 | // When searching for host files to be included in the image, search the default paths used for storing binaries within the specified directory before searching the default paths within $QNX_TARGET. |
368 |
|
348 | // You can define multiple -r options; each adds a set of paths to search for files. |
- | 349 | // The -r options are evaluated from left to right meaning the paths prefixed with the first (leftmost) rootdir are searched first, then those prefixed with the second rootdir, and so on. |
|
369 |
|
350 | // Normally, mkifs searches any paths defined in $MKIFS_PATH when it was called and then the default paths within $QNX_TARGET. |
- | 351 | // The default paths are based on the CPU architecture specified by $PROCESSOR and $PROCESSOR_BASE. |
|
- | 352 | // If you specify -r options, mkifs searches the default paths prefixed with each dir variable before searching those within $QNX_TARGET. |
|
- | 353 | // These paths are: |
|
- | 354 | // dir/${PROCESSOR}/sbin |
|
- | 355 | // dir/${PROCESSOR}/usr/sbin |
|
- | 356 | // dir/${PROCESSOR}/boot/sys |
|
- | 357 | // dir/${PROCESSOR_BASE}/boot/sys |
|
- | 358 | // dir/${PROCESSOR}/bin |
|
- | 359 | // dir/${PROCESSOR}/usr/bin |
|
- | 360 | // dir/${PROCESSOR}/lib |
|
- | 361 | // dir/${PROCESSOR}/lib/dll |
|
- | 362 | // dir/${PROCESSOR}/usr/lib |
|
- | 363 | // NOTE: The structure of the directory paths under dir must be identical to that of the default paths under $QNX_TARGET, but the root dir itself may be any path you choose. |
|
- | 364 | // For example, if you wanted to include /scratch/aarch64le/sbin/devb-sata, you would specify a -r option like this: |
|
- | 365 | // -r /scratch |
|
- | 366 | // Note that you don't include $PROCESSOR or $PROCESSOR_BASE in dir. |
|
370 | 367 | ||
371 |
|
368 | // - search all paths in explicit path/[default paths] (if explicit path supplied) |
372 |
|
369 | // - search all paths in (-r flags if have some|MKIFS_PATH)/[default paths] (if no explicit path supplied) |
373 | { |
- | |
374 |
|
370 | // - search all paths in $QNX_TARGET/[default paths] |
375 | resolved_search_path = resolve_envvars (search_paths_or_NULL_for_MKIFS_PATH_envvar); |
- | |
376 | 371 | ||
- | 372 | // initial allocation (per thread) |
|
- | 373 | if (resolved_pathname == NULL) |
|
- | 374 | { |
|
- | 375 | resolved_pathname = malloc (MAXPATHLEN); |
|
- | 376 | ASSERT_WITH_ERRNO (resolved_pathname); |
|
- | 377 | } |
|
- | 378 | ||
- | 379 | // if no file-specific explicit search path was supplied, use the path list supplied by the -r command-line arguments, else fallback to MKIFS_PATH if we don't have any |
|
- | 380 | if (search_paths_or_NULL_for_MKIFS_PATH_envvar == NULL) |
|
- | 381 | search_paths_or_NULL_for_MKIFS_PATH_envvar = (SEARCH_PATH != NULL ? SEARCH_PATH : getenv ("MKIFS_PATH")); |
|
- | 382 | ||
- | 383 | // construct a potential final path using each element of the search path |
|
- | 384 | if (search_paths_or_NULL_for_MKIFS_PATH_envvar != NULL) |
|
- | 385 | { |
|
- | 386 | // the first step is to resolve all environment variables in the search path |
|
- | 387 | resolved_search_path = resolve_envvars (search_paths_or_NULL_for_MKIFS_PATH_envvar); |
|
- | 388 | ||
377 |
|
389 | // now split this search path string into multiple tokens and process them one after the other |
378 |
|
390 | token = (*resolved_search_path != 0 ? resolved_search_path : NULL); |
379 |
|
391 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
380 |
|
392 | while (token != NULL) |
- | 393 | { |
|
- | 394 | // look under this search path at each of the known subpaths |
|
- | 395 | for (defaultpath_index = 0; defaultpath_index < sizeof (default_paths) / sizeof (default_paths[0]); defaultpath_index++) |
|
381 | { |
396 | { |
382 |
|
397 | sprintf_s (resolved_pathname, MAXPATHLEN, "%.*s/%s/%s/%s", (int) (nextsep - token), token, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname_without_envvars); |
383 |
|
398 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
384 | { |
399 | { |
385 | sprintf_s (resolved_pathname, MAXPATHLEN, "%.*s/%s/%s/%s", (int) (nextsep - token), token, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname_without_envvars); |
- | |
386 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
- | |
387 | { |
- | |
388 |
|
400 | free (pathname_without_envvars); |
389 |
|
401 | return (resolved_pathname); // if a file can indeed be found at this location, stop searching |
390 | } |
- | |
391 | } |
402 | } |
392 | - | ||
393 | token = (*nextsep != 0 ? nextsep + 1 : NULL); |
- | |
394 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
- | |
395 | } |
403 | } |
- | 404 | ||
- | 405 | token = (*nextsep != 0 ? nextsep + 1 : NULL); |
|
- | 406 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
|
396 | } |
407 | } |
- | 408 | } |
|
397 | 409 | ||
398 |
|
410 | // file not found in search paths: look under QNX_TARGET at each of the known subpaths |
399 |
|
411 | for (defaultpath_index = 0; defaultpath_index < sizeof (default_paths) / sizeof (default_paths[0]); defaultpath_index++) |
- | 412 | { |
|
- | 413 | sprintf_s (resolved_pathname, MAXPATHLEN, "%s/%s/%s/%s", QNX_TARGET, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname_without_envvars); |
|
- | 414 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
|
400 | { |
415 | { |
401 | sprintf_s (resolved_pathname, MAXPATHLEN, "%s/%s/%s/%s", QNX_TARGET, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname_without_envvars); |
- | |
402 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
- | |
403 | { |
- | |
404 |
|
416 | free (pathname_without_envvars); |
405 |
|
417 | return (resolved_pathname); // if a file can indeed be found at this location, stop searching |
406 | } |
- | |
407 | } |
418 | } |
408 | } |
419 | } |
409 | 420 | ||
410 | free (pathname_without_envvars); |
421 | free (pathname_without_envvars); |
411 | errno = ENOENT; // we exhausted all possibilities |
422 | errno = ENOENT; // we exhausted all possibilities |
Line 1418... | Line 1429... | ||
1418 | return; // if we're allowed to continue when a file to add doesn't exist, do so, else die with an error message |
1429 | return; // if we're allowed to continue when a file to add doesn't exist, do so, else die with an error message |
1419 | } |
1430 | } |
1420 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d not found on build host: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
1431 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d not found on build host: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
1421 | } |
1432 | } |
1422 | if (!Buffer_ReadFromFile (&entry_parms->data, resolved_pathname)) |
1433 | if (!Buffer_ReadFromFile (&entry_parms->data, resolved_pathname)) |
1423 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d can't be read: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
1434 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d can't be read from \"%s\": %s", buildhost_pathname, buildfile_pathname, lineno, resolved_pathname, strerror (errno)); |
1424 | stat (resolved_pathname, &stat_buf); // can't fail, since we could read it |
1435 | stat (resolved_pathname, &stat_buf); // can't fail, since we could read it |
1425 | if (entry_parms->mtime == UINT32_MAX) |
1436 | if (entry_parms->mtime == UINT32_MAX) |
1426 | entry_parms->mtime = (uint32_t) stat_buf.st_mtime; |
1437 | entry_parms->mtime = (uint32_t) stat_buf.st_mtime; |
1427 | LOG_INFO ("file: ino 0x%x uid %d gid %d mode 0%o path \"%s\" buildhost_file \"%s\" (len %zd)", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, buildhost_pathname, entry_parms->data.size); |
1438 | LOG_INFO ("file: ino 0x%x uid %d gid %d mode 0%o path \"%s\" buildhost_file \"%s\" (len %zd)", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, buildhost_pathname, entry_parms->data.size); |
1428 | } |
1439 | } |