Blob Blame History Raw
From ce74829db630a49569c79aea4aeb288fdd458dd8 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Fri, 13 Dec 2019 17:01:03 +0100
Subject: [PATCH 20/30] 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 <perex@perex.cz>
---
 src/topology/builder.c    | 121 ++++++++++++++++++++++------------------------
 src/topology/tplg_local.h |   3 +-
 2 files changed, 60 insertions(+), 64 deletions(-)

diff --git a/src/topology/builder.c b/src/topology/builder.c
index 5ae3ae89dac7..4e6cbbb08a1a 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 22648fa51f9b..7b8abcdefbcf 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;
 
-- 
2.16.4