truncate and ftruncate Functions

本文深入探讨了文件截断(truncate)与空文件(通过O_TRUNC打开)的操作,解释了如何使用C语言中的`truncate`和`ftruncate`函数来修改文件大小,并在特定场景下使用这些技术来清理文件内容。

truncate, ftruncate - truncate a file to a specified length

Sometimes we would like to truncate a file by chopping off(砍去) data at the end of the file.
Emptying a file, which we can do with the O_TRUNC flag to open, is a special case of truncation.

函数原型如下:

#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
//Both Returns: 0 if OK, -1 on error

将会将文件截断到length字节。如果length大于先前的长度,则两长度之间的数据无法访问。如果先前长度小于length,则会将文件尺寸扩大到length,在old end 和 new end之间的数据在read时作为0.

We use ftruncate in the program shown in Figure 13.6 when we need to empty a file after obtaining a lock on the file.

=== SQLite Database Connection Info === Attached databases: #0: name='main', file='/dev/sda1' Database file: /dev/sda1 Main database readonly: no Last error code: 0 Last error message: not an error SQLite version: 3.17.0 Compiler: 2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c Compile options: COMPILER=gcc-9.1.0, ENABLE_FTS3, ENABLE_RTREE, HAS_CODEC, SYSTEM_MALLOC, THREADSAFE=1 Total number of functions: 127 Cache hit: 16, miss: 101 The value of flag is: 1 name = sqlite_sequence name = tAudioInfo name = tCarAtrribute_v2 name = tEventInfo name = tExtendInfo name = tFaceEventInfo name = tFaceFunction_v2 name = tFaceGallery name = tFaceIdObjr name = tLayVerInfo name = tMetadata name = tPeopleAtrribute_v2 name = tPictureInfo name = tSlogExtraInfo name = tSlogInfo name = tSmartAttrInfo_v1 name = tSmartd name = tSubEventInfo name = tTagInfo name = tZoneInfo name = timeInfo name = timeInfo_quota Operation done successfully ======================================== === SQLite Database Connection Info === Attached databases: #0: name='main', file='/dev/mmcblk0p1' Database file: /dev/mmcblk0p1 Main database readonly: no Last error code: 0 Last error message: not an error SQLite version: 3.17.0 Compiler: 2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c Compile options: COMPILER=gcc-9.1.0, ENABLE_FTS3, ENABLE_RTREE, HAS_CODEC, SYSTEM_MALLOC, THREADSAFE=1 Total number of functions: 127 Cache hit: 5, miss: 0 The value of flag is: 0 Operation done successfully ======================================== Target database is empty after backup! Backup likely failed or wrote to invalid path.还是有这个情况,怎么办,但是sda1可以写啊,为什么emmc就不行
09-30
// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2008 Semihalf * * (C) Copyright 2000-2004 * DENX Software Engineering * Wolfgang Denk, wd@denx.de * * Updated-by: Prafulla Wadaskar <prafulla@marvell.com> * FIT image specific code abstracted from mkimage.c * some functions added to address abstraction * * All rights reserved. */ #include "imagetool.h" #include "fit_common.h" #include "mkimage.h" #include <image.h> #include <string.h> #include <stdarg.h> #include <version.h> #include <u-boot/crc.h> static image_header_t header; static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, const char *tmpfile) { int tfd, destfd = 0; void *dest_blob = NULL; off_t destfd_size = 0; struct stat sbuf; void *ptr; int ret = 0; tfd = mmap_fdt(params->cmdname, tmpfile, size_inc, &ptr, &sbuf, true, false); if (tfd < 0) return -EIO; if (params->keydest) { struct stat dest_sbuf; destfd = mmap_fdt(params->cmdname, params->keydest, size_inc, &dest_blob, &dest_sbuf, false, false); if (destfd < 0) { ret = -EIO; goto err_keydest; } destfd_size = dest_sbuf.st_size; } /* for first image creation, add a timestamp at offset 0 i.e., root */ if (params->datafile || params->reset_timestamp) { time_t time = imagetool_get_source_date(params->cmdname, sbuf.st_mtime); ret = fit_set_timestamp(ptr, 0, time); } if (!ret) { ret = fit_cipher_data(params->keydir, dest_blob, ptr, params->comment, params->require_keys, params->engine_id, params->cmdname); } if (!ret) { ret = fit_add_verification_data(params->keydir, params->keyfile, dest_blob, ptr, params->comment, params->require_keys, params->engine_id, params->cmdname); } if (dest_blob) { munmap(dest_blob, destfd_size); close(destfd); } err_keydest: munmap(ptr, sbuf.st_size); close(tfd); return ret; } /** * fit_calc_size() - Calculate the approximate size of the FIT we will generate */ static int fit_calc_size(struct image_tool_params *params) { struct content_info *cont; int size, total_size; size = imagetool_get_filesize(params, params->datafile); if (size < 0) return -1; total_size = size; if (params->fit_ramdisk) { size = imagetool_get_filesize(params, params->fit_ramdisk); if (size < 0) return -1; total_size += size; } for (cont = params->content_head; cont; cont = cont->next) { size = imagetool_get_filesize(params, cont->fname); if (size < 0) return -1; /* Add space for properties and hash node */ total_size += size + 300; } /* Add plenty of space for headers, properties, nodes, etc. */ total_size += 4096; return total_size; } static int fdt_property_file(struct image_tool_params *params, void *fdt, const char *name, const char *fname) { struct stat sbuf; void *ptr; int ret; int fd; fd = open(fname, O_RDWR | O_BINARY); if (fd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", params->cmdname, fname, strerror(errno)); return -1; } if (fstat(fd, &sbuf) < 0) { fprintf(stderr, "%s: Can't stat %s: %s\n", params->cmdname, fname, strerror(errno)); goto err; } ret = fdt_property_placeholder(fdt, "data", sbuf.st_size, &ptr); if (ret) goto err; ret = read(fd, ptr, sbuf.st_size); if (ret != sbuf.st_size) { fprintf(stderr, "%s: Can't read %s: %s\n", params->cmdname, fname, strerror(errno)); goto err; } close(fd); return 0; err: close(fd); return -1; } static int fdt_property_strf(void *fdt, const char *name, const char *fmt, ...) { char str[100]; va_list ptr; va_start(ptr, fmt); vsnprintf(str, sizeof(str), fmt, ptr); va_end(ptr); return fdt_property_string(fdt, name, str); } static void get_basename(char *str, int size, const char *fname) { const char *p, *start, *end; int len; /* * Use the base name as the 'name' field. So for example: * * "arch/arm/dts/sun7i-a20-bananapro.dtb" * becomes "sun7i-a20-bananapro" */ p = strrchr(fname, '/'); start = p ? p + 1 : fname; p = strrchr(fname, '.'); end = p ? p : fname + strlen(fname); len = end - start; if (len >= size) len = size - 1; memcpy(str, start, len); str[len] = '\0'; } /** * add_crc_node() - Add a hash node to request a CRC checksum for an image * * @fdt: Device tree to add to (in sequential-write mode) */ static void add_crc_node(void *fdt) { fdt_begin_node(fdt, "hash-1"); fdt_property_string(fdt, FIT_ALGO_PROP, "crc32"); fdt_end_node(fdt); } /** * fit_write_images() - Write out a list of images to the FIT * * We always include the main image (params->datafile). If there are device * tree files, we include an fdt- node for each of those too. */ static int fit_write_images(struct image_tool_params *params, char *fdt) { struct content_info *cont; const char *typename; char str[100]; int upto; int ret; fdt_begin_node(fdt, "images"); /* First the main image */ typename = genimg_get_type_short_name(params->fit_image_type); snprintf(str, sizeof(str), "%s-1", typename); fdt_begin_node(fdt, str); fdt_property_string(fdt, FIT_DESC_PROP, params->imagename); fdt_property_string(fdt, FIT_TYPE_PROP, typename); fdt_property_string(fdt, FIT_ARCH_PROP, genimg_get_arch_short_name(params->arch)); fdt_property_string(fdt, FIT_OS_PROP, genimg_get_os_short_name(params->os)); fdt_property_string(fdt, FIT_COMP_PROP, genimg_get_comp_short_name(params->comp)); fdt_property_u32(fdt, FIT_LOAD_PROP, params->addr); fdt_property_u32(fdt, FIT_ENTRY_PROP, params->ep); /* * Put data last since it is large. SPL may only load the first part * of the DT, so this way it can access all the above fields. */ ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->datafile); if (ret) return ret; add_crc_node(fdt); fdt_end_node(fdt); /* Now the device tree files if available */ upto = 0; for (cont = params->content_head; cont; cont = cont->next) { if (cont->type != IH_TYPE_FLATDT) continue; typename = genimg_get_type_short_name(cont->type); snprintf(str, sizeof(str), "%s-%d", FIT_FDT_PROP, ++upto); fdt_begin_node(fdt, str); get_basename(str, sizeof(str), cont->fname); fdt_property_string(fdt, FIT_DESC_PROP, str); ret = fdt_property_file(params, fdt, FIT_DATA_PROP, cont->fname); if (ret) return ret; fdt_property_string(fdt, FIT_TYPE_PROP, typename); fdt_property_string(fdt, FIT_ARCH_PROP, genimg_get_arch_short_name(params->arch)); fdt_property_string(fdt, FIT_COMP_PROP, genimg_get_comp_short_name(IH_COMP_NONE)); add_crc_node(fdt); fdt_end_node(fdt); } /* And a ramdisk file if available */ if (params->fit_ramdisk) { fdt_begin_node(fdt, FIT_RAMDISK_PROP "-1"); fdt_property_string(fdt, FIT_TYPE_PROP, FIT_RAMDISK_PROP); fdt_property_string(fdt, FIT_OS_PROP, genimg_get_os_short_name(params->os)); fdt_property_string(fdt, FIT_ARCH_PROP, genimg_get_arch_short_name(params->arch)); ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->fit_ramdisk); if (ret) return ret; add_crc_node(fdt); fdt_end_node(fdt); } fdt_end_node(fdt); return 0; } /** * fit_write_configs() - Write out a list of configurations to the FIT * * If there are device tree files, we include a configuration for each, which * selects the main image (params->datafile) and its corresponding device * tree file. * * Otherwise we just create a configuration with the main image in it. */ static void fit_write_configs(struct image_tool_params *params, char *fdt) { struct content_info *cont; const char *typename; char str[100]; int upto; fdt_begin_node(fdt, "configurations"); fdt_property_string(fdt, FIT_DEFAULT_PROP, "conf-1"); upto = 0; for (cont = params->content_head; cont; cont = cont->next) { if (cont->type != IH_TYPE_FLATDT) continue; typename = genimg_get_type_short_name(cont->type); snprintf(str, sizeof(str), "conf-%d", ++upto); fdt_begin_node(fdt, str); get_basename(str, sizeof(str), cont->fname); fdt_property_string(fdt, FIT_DESC_PROP, str); typename = genimg_get_type_short_name(params->fit_image_type); snprintf(str, sizeof(str), "%s-1", typename); fdt_property_string(fdt, typename, str); fdt_property_string(fdt, FIT_LOADABLE_PROP, str); if (params->fit_ramdisk) fdt_property_string(fdt, FIT_RAMDISK_PROP, FIT_RAMDISK_PROP "-1"); snprintf(str, sizeof(str), FIT_FDT_PROP "-%d", upto); fdt_property_string(fdt, FIT_FDT_PROP, str); fdt_end_node(fdt); } if (!upto) { fdt_begin_node(fdt, "conf-1"); typename = genimg_get_type_short_name(params->fit_image_type); snprintf(str, sizeof(str), "%s-1", typename); fdt_property_string(fdt, typename, str); if (params->fit_ramdisk) fdt_property_string(fdt, FIT_RAMDISK_PROP, FIT_RAMDISK_PROP "-1"); fdt_end_node(fdt); } fdt_end_node(fdt); } static int fit_build_fdt(struct image_tool_params *params, char *fdt, int size) { int ret; ret = fdt_create(fdt, size); if (ret) return ret; fdt_finish_reservemap(fdt); fdt_begin_node(fdt, ""); fdt_property_strf(fdt, FIT_DESC_PROP, "%s image with one or more FDT blobs", genimg_get_type_name(params->fit_image_type)); fdt_property_strf(fdt, "creator", "U-Boot mkimage %s", PLAIN_VERSION); fdt_property_u32(fdt, "#address-cells", 1); ret = fit_write_images(params, fdt); if (ret) return ret; fit_write_configs(params, fdt); fdt_end_node(fdt); ret = fdt_finish(fdt); if (ret) return ret; return fdt_totalsize(fdt); } static int fit_build(struct image_tool_params *params, const char *fname) { char *buf; int size; int ret; int fd; size = fit_calc_size(params); if (size < 0) return -1; buf = calloc(1, size); if (!buf) { fprintf(stderr, "%s: Out of memory (%d bytes)\n", params->cmdname, size); return -1; } ret = fit_build_fdt(params, buf, size); if (ret < 0) { fprintf(stderr, "%s: Failed to build FIT image\n", params->cmdname); goto err_buf; } size = ret; fd = open(fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666); if (fd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", params->cmdname, fname, strerror(errno)); goto err_buf; } ret = write(fd, buf, size); if (ret != size) { fprintf(stderr, "%s: Can't write %s: %s\n", params->cmdname, fname, strerror(errno)); goto err; } close(fd); free(buf); return 0; err: close(fd); err_buf: free(buf); return -1; } /** * fit_extract_data() - Move all data outside the FIT * * This takes a normal FIT file and removes all the 'data' properties from it. * The data is placed in an area after the FIT so that it can be accessed * using an offset into that area. The 'data' properties turn into * 'data-offset' properties. * * This function cannot cope with FITs with 'data-offset' properties. All * data must be in 'data' properties on entry. */ static int fit_extract_data(struct image_tool_params *params, const char *fname) { void *buf = NULL; int buf_ptr; int fit_size, new_size; int fd; struct stat sbuf; void *fdt; int ret; int images; int node; int image_number; int align_size; align_size = params->bl_len ? params->bl_len : 4; fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false, false); if (fd < 0) return -EIO; fit_size = fdt_totalsize(fdt); images = fdt_path_offset(fdt, FIT_IMAGES_PATH); if (images < 0) { debug("%s: Cannot find /images node: %d\n", __func__, images); ret = -EINVAL; goto err_munmap; } image_number = fdtdec_get_child_count(fdt, images); /* * Allocate space to hold the image data we will extract, * extral space allocate for image alignment to prevent overflow. */ buf = calloc(1, fit_size + (align_size * image_number)); if (!buf) { ret = -ENOMEM; goto err_munmap; } buf_ptr = 0; for (node = fdt_first_subnode(fdt, images); node >= 0; node = fdt_next_subnode(fdt, node)) { const char *data; int len; data = fdt_getprop(fdt, node, FIT_DATA_PROP, &len); if (!data) continue; memcpy(buf + buf_ptr, data, len); debug("Extracting data size %x\n", len); ret = fdt_delprop(fdt, node, FIT_DATA_PROP); if (ret) { ret = -EPERM; goto err_munmap; } if (params->external_offset > 0) { /* An external offset positions the data absolutely. */ fdt_setprop_u32(fdt, node, FIT_DATA_POSITION_PROP, params->external_offset + buf_ptr); } else { fdt_setprop_u32(fdt, node, FIT_DATA_OFFSET_PROP, buf_ptr); } fdt_setprop_u32(fdt, node, FIT_DATA_SIZE_PROP, len); buf_ptr += ALIGN(len, align_size); } /* Pack the FDT and place the data after it */ fdt_pack(fdt); new_size = fdt_totalsize(fdt); new_size = ALIGN(new_size, align_size); fdt_set_totalsize(fdt, new_size); debug("Size reduced from %x to %x\n", fit_size, fdt_totalsize(fdt)); debug("External data size %x\n", buf_ptr); munmap(fdt, sbuf.st_size); if (ftruncate(fd, new_size)) { debug("%s: Failed to truncate file: %s\n", __func__, strerror(errno)); ret = -EIO; goto err; } /* Check if an offset for the external data was set. */ if (params->external_offset > 0) { if (params->external_offset < new_size) { debug("External offset %x overlaps FIT length %x\n", params->external_offset, new_size); ret = -EINVAL; goto err; } new_size = params->external_offset; } if (lseek(fd, new_size, SEEK_SET) < 0) { debug("%s: Failed to seek to end of file: %s\n", __func__, strerror(errno)); ret = -EIO; goto err; } if (write(fd, buf, buf_ptr) != buf_ptr) { debug("%s: Failed to write external data to file %s\n", __func__, strerror(errno)); ret = -EIO; goto err; } free(buf); close(fd); return 0; err_munmap: munmap(fdt, sbuf.st_size); err: free(buf); close(fd); return ret; } static int fit_import_data(struct image_tool_params *params, const char *fname) { void *fdt, *old_fdt; int fit_size, new_size, size, data_base; int fd; struct stat sbuf; int ret; int images; int node; fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false, false); if (fd < 0) return -EIO; fit_size = fdt_totalsize(old_fdt); data_base = ALIGN(fit_size, 4); /* Allocate space to hold the new FIT */ size = sbuf.st_size + 16384; fdt = calloc(1, size); if (!fdt) { fprintf(stderr, "%s: Failed to allocate memory (%d bytes)\n", __func__, size); ret = -ENOMEM; goto err_munmap; } ret = fdt_open_into(old_fdt, fdt, size); if (ret) { debug("%s: Failed to expand FIT: %s\n", __func__, fdt_strerror(errno)); ret = -EINVAL; goto err_munmap; } images = fdt_path_offset(fdt, FIT_IMAGES_PATH); if (images < 0) { debug("%s: Cannot find /images node: %d\n", __func__, images); ret = -EINVAL; goto err_munmap; } for (node = fdt_first_subnode(fdt, images); node >= 0; node = fdt_next_subnode(fdt, node)) { int buf_ptr; int len; buf_ptr = fdtdec_get_int(fdt, node, "data-offset", -1); len = fdtdec_get_int(fdt, node, "data-size", -1); if (buf_ptr == -1 || len == -1) continue; debug("Importing data size %x\n", len); ret = fdt_setprop(fdt, node, "data", old_fdt + data_base + buf_ptr, len); if (ret) { debug("%s: Failed to write property: %s\n", __func__, fdt_strerror(ret)); ret = -EINVAL; goto err_munmap; } } munmap(old_fdt, sbuf.st_size); /* Close the old fd so we can re-use it. */ close(fd); /* Pack the FDT and place the data after it */ fdt_pack(fdt); new_size = fdt_totalsize(fdt); debug("Size expanded from %x to %x\n", fit_size, new_size); fd = open(fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666); if (fd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", params->cmdname, fname, strerror(errno)); ret = -EIO; goto err; } if (write(fd, fdt, new_size) != new_size) { debug("%s: Failed to write external data to file %s\n", __func__, strerror(errno)); ret = -EIO; goto err; } free(fdt); close(fd); return 0; err_munmap: munmap(old_fdt, sbuf.st_size); err: free(fdt); close(fd); return ret; } static int copyfile(const char *src, const char *dst) { int fd_src = -1, fd_dst = -1; void *buf = NULL; ssize_t size; size_t count; int ret = -1; fd_src = open(src, O_RDONLY); if (fd_src < 0) { printf("Can't open file %s (%s)\n", src, strerror(errno)); goto out; } fd_dst = open(dst, O_WRONLY | O_CREAT, 0666); if (fd_dst < 0) { printf("Can't open file %s (%s)\n", dst, strerror(errno)); goto out; } buf = calloc(1, 512); if (!buf) { printf("Can't allocate buffer to copy file\n"); goto out; } while (1) { size = read(fd_src, buf, 512); if (size < 0) { printf("Can't read file %s\n", src); goto out; } if (!size) break; count = size; size = write(fd_dst, buf, count); if (size < 0) { printf("Can't write file %s\n", dst); goto out; } } ret = 0; out: if (fd_src >= 0) close(fd_src); if (fd_dst >= 0) close(fd_dst); if (buf) free(buf); return ret; } /** * fit_handle_file - main FIT file processing function * * fit_handle_file() runs dtc to convert .its to .itb, includes * binary data, updates timestamp property and calculates hashes. * * datafile - .its file * imagefile - .itb file * * returns: * only on success, otherwise calls exit (EXIT_FAILURE); */ static int fit_handle_file(struct image_tool_params *params) { char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; char bakfile[MKIMAGE_MAX_TMPFILE_LEN + 4] = {0}; char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; size_t size_inc; int ret; /* Flattened Image Tree (FIT) format handling */ debug ("FIT format handling\n"); /* call dtc to include binary properties into the tmp file */ if (strlen (params->imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) { fprintf (stderr, "%s: Image file name (%s) too long, " "can't create tmpfile.\n", params->imagefile, params->cmdname); return (EXIT_FAILURE); } sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); /* We either compile the source file, or use the existing FIT image */ if (params->auto_its) { if (fit_build(params, tmpfile)) { fprintf(stderr, "%s: failed to build FIT\n", params->cmdname); return EXIT_FAILURE; } *cmd = '\0'; } else if (params->datafile) { /* dtc -I dts -O dtb -p 500 -o tmpfile datafile */ snprintf(cmd, sizeof(cmd), "%s %s -o \"%s\" \"%s\"", MKIMAGE_DTC, params->dtc, tmpfile, params->datafile); debug("Trying to execute \"%s\"\n", cmd); } else { snprintf(cmd, sizeof(cmd), "cp \"%s\" \"%s\"", params->imagefile, tmpfile); } if (strlen(cmd) >= MKIMAGE_MAX_DTC_CMDLINE_LEN - 1) { fprintf(stderr, "WARNING: command-line for FIT creation might be truncated and will probably fail.\n"); } if (*cmd && system(cmd) == -1) { fprintf (stderr, "%s: system(%s) failed: %s\n", params->cmdname, cmd, strerror(errno)); goto err_system; } /* Move the data so it is internal to the FIT, if needed */ ret = fit_import_data(params, tmpfile); if (ret) goto err_system; /* * Copy the tmpfile to bakfile, then in the following loop * we copy bakfile to tmpfile. So we always start from the * beginning. */ sprintf(bakfile, "%s%s", tmpfile, ".bak"); rename(tmpfile, bakfile); /* * Set hashes for images in the blob. Unfortunately we may need more * space in either FDT, so keep trying until we succeed. * * Note: this is pretty inefficient for signing, since we must * calculate the signature every time. It would be better to calculate * all the data and then store it in a separate step. However, this * would be considerably more complex to implement. Generally a few * steps of this loop is enough to sign with several keys. */ for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) { if (copyfile(bakfile, tmpfile) < 0) { printf("Can't copy %s to %s\n", bakfile, tmpfile); ret = -EIO; break; } ret = fit_add_file_data(params, size_inc, tmpfile); if (!ret || ret != -ENOSPC) break; } if (ret) { fprintf(stderr, "%s Can't add hashes to FIT blob: %d\n", params->cmdname, ret); goto err_system; } /* Move the data so it is external to the FIT, if requested */ if (params->external_data) { ret = fit_extract_data(params, tmpfile); if (ret) goto err_system; } if (rename (tmpfile, params->imagefile) == -1) { fprintf (stderr, "%s: Can't rename %s to %s: %s\n", params->cmdname, tmpfile, params->imagefile, strerror (errno)); unlink (tmpfile); unlink(bakfile); unlink (params->imagefile); return EXIT_FAILURE; } unlink(bakfile); return EXIT_SUCCESS; err_system: unlink(tmpfile); unlink(bakfile); return -1; } /** * fit_image_extract - extract a FIT component image * @fit: pointer to the FIT format image header * @image_noffset: offset of the component image node * @file_name: name of the file to store the FIT sub-image * * returns: * zero in case of success or a negative value if fail. */ static int fit_image_extract( const void *fit, int image_noffset, const char *file_name) { const void *file_data; size_t file_size = 0; int ret; /* get the data address and size of component at offset "image_noffset" */ ret = fit_image_get_data_and_size(fit, image_noffset, &file_data, &file_size); if (ret) { fprintf(stderr, "Could not get component information\n"); return ret; } /* save the "file_data" into the file specified by "file_name" */ return imagetool_save_subimage(file_name, (ulong) file_data, file_size); } /** * fit_extract_contents - retrieve a sub-image component from the FIT image * @ptr: pointer to the FIT format image header * @params: command line parameters * * returns: * zero in case of success or a negative value if fail. */ static int fit_extract_contents(void *ptr, struct image_tool_params *params) { int images_noffset; int noffset; int ndepth; const void *fit = ptr; int count = 0; const char *p; /* Indent string is defined in header image.h */ p = IMAGE_INDENT_STRING; if (fit_check_format(fit, IMAGE_SIZE_INVAL)) { printf("Bad FIT image format\n"); return -1; } /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (images_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_IMAGES_PATH, fdt_strerror(images_noffset)); return -1; } /* Avoid any overrun */ count = fit_get_subimage_count(fit, images_noffset); if ((params->pflag < 0) || (count <= params->pflag)) { printf("No such component at '%d'\n", params->pflag); return -1; } /* Process its subnodes, extract the desired component from image */ for (ndepth = 0, count = 0, noffset = fdt_next_node(fit, images_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* * Direct child node of the images parent node, * i.e. component image node. */ if (params->pflag == count) { printf("Extracted:\n%s Image %u (%s)\n", p, count, fit_get_name(fit, noffset, NULL)); fit_image_print(fit, noffset, p); return fit_image_extract(fit, noffset, params->outfile); } count++; } } return 0; } static int fit_check_params(struct image_tool_params *params) { if (params->auto_its) return 0; return ((params->dflag && params->fflag) || (params->fflag && params->lflag) || (params->lflag && params->dflag)); } U_BOOT_IMAGE_TYPE( fitimage, "FIT Image support", sizeof(image_header_t), (void *)&header, fit_check_params, fit_verify_header, fit_print_contents, NULL, fit_extract_contents, fit_check_image_types, fit_handle_file, NULL /* FIT images use DTB header */ );
最新发布
11-08
os.access(path, mode) 检验权限模式 2 os.chdir(path) 改变当前工作目录 3 os.chflags(path, flags) 设置路径的标记为数字标记。 4 os.chmod(path, mode) 更改权限 5 os.chown(path, uid, gid) 更改文件所有者 6 os.chroot(path) 改变当前进程的根目录 7 os.close(fd) 关闭文件描述符 fd 8 os.closerange(fd_low, fd_high) 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 9 os.dup(fd) 复制文件描述符 fd 10 os.dup2(fd, fd2) 将一个文件描述符 fd 复制到另一个 fd2 11 os.fchdir(fd) 通过文件描述符改变当前工作目录 12 os.fchmod(fd, mode) 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 13 os.fchown(fd, uid, gid) 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 14 os.fdatasync(fd) 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 15 os.fdopen(fd[, mode[, bufsize]]) 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 16 os.fpathconf(fd, name) 返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 17 os.fstat(fd) 返回文件描述符fd的状态,像stat()。 18 os.fstatvfs(fd) 返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。 19 os.fsync(fd) 强制将文件描述符为fd的文件写入硬盘。 20 os.ftruncate(fd, length) 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 21 os.getcwd() 返回当前工作目录 22 os.getcwdb() 返回一个当前工作目录的Unicode对象 23 os.isatty(fd) 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 24 os.lchflags(path, flags) 设置路径的标记为数字标记,类似 chflags(),但是没有软链接 25 os.lchmod(path, mode) 修改连接文件权限 26 os.lchown(path, uid, gid) 更改文件所有者,类似 chown,但是不追踪链接。 27 os.link(src, dst) 创建硬链接,名为参数 dst,指向参数 src 28 os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表。 29 os.lseek(fd, pos, how) 设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 30 os.lstat(path) 像stat(),但是没有软链接 31 os.major(device) 从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 32 os.makedev(major, minor) 以major和minor设备号组成一个原始设备号 33 os.makedirs(path[, mode]) 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 34 os.minor(device) 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 35 os.mkdir(path[, mode]) 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 36 os.mkfifo(path[, mode]) 创建命名管道,mode 为数字,默认为 0666 (八进制) 37 os.mknod(filename[, mode=0600, device]) 创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。 38 os.open(file, flags[, mode]) 打开一个文件,并且设置需要的打开选项,mode参数是可选的 39 os.openpty() 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 40 os.pathconf(path, name) 返回相关文件的系统配置信息。 41 os.pipe() 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 42 os.popen(command[, mode[, bufsize]]) 从一个 command 打开一个管道 43 os.read(fd, n) 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 44 os.readlink(path) 返回软链接所指向的文件 45 os.remove(path) 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 46 os.removedirs(path) 递归删除目录。 47 os.rename(src, dst) 重命名文件或目录,从 src 到 dst 48 os.renames(old, new) 递归地对目录进行更名,也可以对文件进行更名。 49 os.rmdir(path) 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 50 os.stat(path) 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 51 os.stat_float_times([newvalue]) 决定stat_result是否以float对象显示时间戳 52 os.statvfs(path) 获取指定路径的文件系统统计信息 53 os.symlink(src, dst) 创建一个软链接 54 os.tcgetpgrp(fd) 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 55 os.tcsetpgrp(fd, pg) 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 56 os.tempnam([dir[, prefix]]) Python3 中已删除。返回唯一的路径名用于创建临时文件。 57 os.tmpfile() Python3 中已删除。返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。 58 os.tmpnam() Python3 中已删除。为创建一个临时文件返回一个唯一的路径 59 os.ttyname(fd) 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 60 os.unlink(path) 删除文件路径 61 os.utime(path, times) 返回指定的path文件的访问和修改的时间。 62 os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) 输出在文件夹中的文件名通过在树中游走,向上或者向下。 63 os.write(fd, str) 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 64 os.path 模块 获取文件的属性信息。 65 os.pardir() 获取当前目录的父目录,以字符串形式显示目录名。 66 os.replace() 重命名文件或目录。 帮我整理为md格式,相同类别分为二级标题,例如:文件信息类、路径类,路径下又分为:判断、创建等类别,我要你以md文件形式返回
07-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值