1# SPDX-License-Identifier: GPL-2.0+ 2# 3# Copyright (c) 2016 Google, Inc 4# 5 6import os 7import shutil 8import tempfile 9 10import tout 11 12outdir = None 13indirs = None 14preserve_outdir = False 15 16def PrepareOutputDir(dirname, preserve=False): 17 """Select an output directory, ensuring it exists. 18 19 This either creates a temporary directory or checks that the one supplied 20 by the user is valid. For a temporary directory, it makes a note to 21 remove it later if required. 22 23 Args: 24 dirname: a string, name of the output directory to use to store 25 intermediate and output files. If is None - create a temporary 26 directory. 27 preserve: a Boolean. If outdir above is None and preserve is False, the 28 created temporary directory will be destroyed on exit. 29 30 Raises: 31 OSError: If it cannot create the output directory. 32 """ 33 global outdir, preserve_outdir 34 35 preserve_outdir = dirname or preserve 36 if dirname: 37 outdir = dirname 38 if not os.path.isdir(outdir): 39 try: 40 os.makedirs(outdir) 41 except OSError as err: 42 raise CmdError("Cannot make output directory '%s': '%s'" % 43 (outdir, err.strerror)) 44 tout.Debug("Using output directory '%s'" % outdir) 45 else: 46 outdir = tempfile.mkdtemp(prefix='binman.') 47 tout.Debug("Using temporary directory '%s'" % outdir) 48 49def _RemoveOutputDir(): 50 global outdir 51 52 shutil.rmtree(outdir) 53 tout.Debug("Deleted temporary directory '%s'" % outdir) 54 outdir = None 55 56def FinaliseOutputDir(): 57 global outdir, preserve_outdir 58 59 """Tidy up: delete output directory if temporary and not preserved.""" 60 if outdir and not preserve_outdir: 61 _RemoveOutputDir() 62 63def GetOutputFilename(fname): 64 """Return a filename within the output directory. 65 66 Args: 67 fname: Filename to use for new file 68 69 Returns: 70 The full path of the filename, within the output directory 71 """ 72 return os.path.join(outdir, fname) 73 74def _FinaliseForTest(): 75 """Remove the output directory (for use by tests)""" 76 global outdir 77 78 if outdir: 79 _RemoveOutputDir() 80 81def SetInputDirs(dirname): 82 """Add a list of input directories, where input files are kept. 83 84 Args: 85 dirname: a list of paths to input directories to use for obtaining 86 files needed by binman to place in the image. 87 """ 88 global indir 89 90 indir = dirname 91 tout.Debug("Using input directories %s" % indir) 92 93def GetInputFilename(fname): 94 """Return a filename for use as input. 95 96 Args: 97 fname: Filename to use for new file 98 99 Returns: 100 The full path of the filename, within the input directory 101 """ 102 if not indir: 103 return fname 104 for dirname in indir: 105 pathname = os.path.join(dirname, fname) 106 if os.path.exists(pathname): 107 return pathname 108 109 raise ValueError("Filename '%s' not found in input path (%s)" % 110 (fname, ','.join(indir))) 111 112def Align(pos, align): 113 if align: 114 mask = align - 1 115 pos = (pos + mask) & ~mask 116 return pos 117 118def NotPowerOfTwo(num): 119 return num and (num & (num - 1)) 120