From: Jaroslav Kysela Date: Fri, 13 Dec 2019 16:01:03 +0000 (+0100) Subject: topology: file position and size cleanups X-Git-Tag: v1.2.2~59 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=ce74829db630a49569c79aea4aeb288fdd458dd8;p=alsa-lib.git topology: file position and size cleanups - try to use size_t/ssize_t - track the position in own variable, do not use lseek Signed-off-by: Jaroslav Kysela --- diff --git a/src/topology/builder.c b/src/topology/builder.c index 5ae3ae89..4e6cbbb0 100644 --- a/src/topology/builder.c +++ b/src/topology/builder.c @@ -23,28 +23,41 @@ /* verbose output detailing each object size and file position */ static void verbose(snd_tplg_t *tplg, const char *fmt, ...) { - int offset; va_list va; if (!tplg->verbose) return; - offset = lseek(tplg->out_fd, 0, SEEK_CUR); - va_start(va, fmt); - fprintf(stdout, "0x%6.6x/%6.6d -", offset, offset); + fprintf(stdout, "0x%6.6zx/%6.6zd -", tplg->out_pos, tplg->out_pos); vfprintf(stdout, fmt, va); va_end(va); } +/* write a block, track the position */ +static ssize_t twrite(snd_tplg_t *tplg, void *data, size_t data_size) +{ + ssize_t r = write(tplg->out_fd, data, data_size); + if (r != (ssize_t)data_size) { + if (r < 0) { + SNDERR("error: unable to write: %s", strerror(errno)); + return -errno; + } + tplg->out_pos += r; + SNDERR("error: unable to write (partial)"); + return -EIO; + } + tplg->out_pos += r; + return r; +} + /* write out block header to output file */ -static int write_block_header(snd_tplg_t *tplg, unsigned int type, - unsigned int vendor_type, unsigned int version, unsigned int index, - size_t payload_size, int count) +static ssize_t write_block_header(snd_tplg_t *tplg, unsigned int type, + unsigned int vendor_type, + unsigned int version, unsigned int index, + size_t payload_size, int count) { struct snd_soc_tplg_hdr hdr; - size_t bytes; - int offset = lseek(tplg->out_fd, 0, SEEK_CUR); memset(&hdr, 0, sizeof(hdr)); hdr.magic = SND_SOC_TPLG_MAGIC; @@ -58,13 +71,13 @@ static int write_block_header(snd_tplg_t *tplg, unsigned int type, hdr.count = count; /* make sure file offset is aligned with the calculated HDR offset */ - if ((unsigned int)offset != tplg->next_hdr_pos) { - SNDERR("error: New header is at offset 0x%x but file" - " offset 0x%x is %s by %d bytes\n", - tplg->next_hdr_pos, offset, - (unsigned int)offset > tplg->next_hdr_pos ? "ahead" : "behind", - abs(offset - tplg->next_hdr_pos)); - exit(-EINVAL); + if (tplg->out_pos != tplg->next_hdr_pos) { + SNDERR("error: New header is at offset 0x%zx but file" + " offset 0x%zx is %s by %ld bytes\n", + tplg->next_hdr_pos, tplg->out_pos, + tplg->out_pos > tplg->next_hdr_pos ? "ahead" : "behind", + labs(tplg->out_pos - tplg->next_hdr_pos)); + return -EINVAL; } verbose(tplg, " header index %d type %d count %d size 0x%lx/%ld vendor %d " @@ -74,22 +87,16 @@ static int write_block_header(snd_tplg_t *tplg, unsigned int type, tplg->next_hdr_pos += hdr.payload_size + sizeof(hdr); - bytes = write(tplg->out_fd, &hdr, sizeof(hdr)); - if (bytes != sizeof(hdr)) { - SNDERR("error: can't write section header %lu\n", - (long unsigned int)bytes); - return bytes; - } - - return bytes; + return twrite(tplg, &hdr, sizeof(hdr)); } static int write_elem_block(snd_tplg_t *tplg, - struct list_head *base, int size, int tplg_type, const char *obj_name) + struct list_head *base, size_t size, int tplg_type, const char *obj_name) { struct list_head *pos, *sub_pos, *sub_base; struct tplg_elem *elem, *elem_next; - int ret, wsize = 0, total_size = 0, count = 0, block_size = 0; + size_t total_size = 0, count = 0, block_size = 0; + ssize_t ret, wsize; sub_base = base; list_for_each(pos, base) { @@ -129,12 +136,9 @@ static int write_elem_block(snd_tplg_t *tplg, elem->route->control, elem->route->sink, elem->size); - wsize = write(tplg->out_fd, elem->obj, elem->size); - if (wsize < 0) { - SNDERR("error: failed to write %s %d\n", - obj_name, ret); - return ret; - } + wsize = twrite(tplg, elem->obj, elem->size); + if (wsize < 0) + return size; total_size += wsize; /* get to the end of sub list */ @@ -151,7 +155,7 @@ static int write_elem_block(snd_tplg_t *tplg, /* make sure we have written the correct size */ if (total_size != size) { - SNDERR("error: size mismatch. Expected %d wrote %d\n", + SNDERR("error: size mismatch. Expected %zu wrote %zu\n", size, total_size); return -EIO; } @@ -179,8 +183,7 @@ static int calc_block_size(struct list_head *base) return size; } -static int write_block(snd_tplg_t *tplg, struct list_head *base, - int type) +static int write_block(snd_tplg_t *tplg, struct list_head *base, int type) { int size; @@ -231,44 +234,36 @@ static int write_block(snd_tplg_t *tplg, struct list_head *base, } /* write the manifest including its private data */ -static int write_manifest_data(snd_tplg_t *tplg) +static ssize_t write_manifest_data(snd_tplg_t *tplg) { - int ret; + ssize_t ret; /* write the header for this block */ ret = write_block_header(tplg, SND_SOC_TPLG_TYPE_MANIFEST, 0, tplg->version, 0, sizeof(tplg->manifest) + tplg->manifest.priv.size, 1); if (ret < 0) { - SNDERR("error: failed to write manifest block %d\n", ret); + SNDERR("error: failed to write manifest block\n"); return ret; } verbose(tplg, "manifest : write %d bytes\n", sizeof(tplg->manifest)); - ret = write(tplg->out_fd, &tplg->manifest, sizeof(tplg->manifest)); - if (ret < 0) { - SNDERR("error: failed to write manifest %d\n", ret); - return ret; + ret = twrite(tplg, &tplg->manifest, sizeof(tplg->manifest)); + if (ret >= 0) { + verbose(tplg, "manifest : write %d priv bytes\n", tplg->manifest.priv.size); + ret = twrite(tplg, tplg->manifest_pdata, tplg->manifest.priv.size); } - - verbose(tplg, "manifest : write %d priv bytes\n", tplg->manifest.priv.size); - ret = write(tplg->out_fd, tplg->manifest_pdata, tplg->manifest.priv.size); - if (ret < 0) { - SNDERR("error: failed to write manifest priv data %d\n", ret); - return ret; - } - - return 0; + return ret; } int tplg_write_data(snd_tplg_t *tplg) { - int ret; + ssize_t ret; /* write manifest */ ret = write_manifest_data(tplg); if (ret < 0) { - SNDERR("failed to write manifest %d\n", ret); + SNDERR("failed to write manifest %zd\n", ret); return ret; } @@ -276,7 +271,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->mixer_list, SND_TPLG_TYPE_MIXER); if (ret < 0) { - SNDERR("failed to write control elems %d\n", ret); + SNDERR("failed to write control elems %zd\n", ret); return ret; } @@ -284,7 +279,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->enum_list, SND_TPLG_TYPE_ENUM); if (ret < 0) { - SNDERR("failed to write control elems %d\n", ret); + SNDERR("failed to write control elems %zd\n", ret); return ret; } @@ -292,7 +287,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->bytes_ext_list, SND_TPLG_TYPE_BYTES); if (ret < 0) { - SNDERR("failed to write control elems %d\n", ret); + SNDERR("failed to write control elems %zd\n", ret); return ret; } @@ -300,7 +295,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->widget_list, SND_TPLG_TYPE_DAPM_WIDGET); if (ret < 0) { - SNDERR("failed to write widget elems %d\n", ret); + SNDERR("failed to write widget elems %zd\n", ret); return ret; } @@ -308,7 +303,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->pcm_list, SND_TPLG_TYPE_PCM); if (ret < 0) { - SNDERR("failed to write pcm elems %d\n", ret); + SNDERR("failed to write pcm elems %zd\n", ret); return ret; } @@ -316,7 +311,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->dai_list, SND_TPLG_TYPE_DAI); if (ret < 0) { - SNDERR("failed to write physical dai elems %d\n", ret); + SNDERR("failed to write physical dai elems %zd\n", ret); return ret; } @@ -324,7 +319,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->be_list, SND_TPLG_TYPE_BE); if (ret < 0) { - SNDERR("failed to write be elems %d\n", ret); + SNDERR("failed to write be elems %zd\n", ret); return ret; } @@ -332,7 +327,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->cc_list, SND_TPLG_TYPE_CC); if (ret < 0) { - SNDERR("failed to write cc elems %d\n", ret); + SNDERR("failed to write cc elems %zd\n", ret); return ret; } @@ -340,7 +335,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->route_list, SND_TPLG_TYPE_DAPM_GRAPH); if (ret < 0) { - SNDERR("failed to write graph elems %d\n", ret); + SNDERR("failed to write graph elems %zd\n", ret); return ret; } @@ -348,7 +343,7 @@ int tplg_write_data(snd_tplg_t *tplg) ret = write_block(tplg, &tplg->pdata_list, SND_TPLG_TYPE_DATA); if (ret < 0) { - SNDERR("failed to write private data %d\n", ret); + SNDERR("failed to write private data %zd\n", ret); return ret; } diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h index 22648fa5..7b8abcde 100644 --- a/src/topology/tplg_local.h +++ b/src/topology/tplg_local.h @@ -62,12 +62,13 @@ typedef enum _snd_pcm_rates { struct snd_tplg { /* out file */ int out_fd; + size_t out_pos; int verbose; unsigned int version; /* runtime state */ - unsigned int next_hdr_pos; + size_t next_hdr_pos; int index; int channel_idx;