1c72fcc34Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
2c72fcc34Sopenharmony_ci//
3c72fcc34Sopenharmony_ci// container-io.c - a unit test for parser/builder of supported containers.
4c72fcc34Sopenharmony_ci//
5c72fcc34Sopenharmony_ci// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6c72fcc34Sopenharmony_ci//
7c72fcc34Sopenharmony_ci// Licensed under the terms of the GNU General Public License, version 2.
8c72fcc34Sopenharmony_ci
9c72fcc34Sopenharmony_ci#include <aconfig.h>
10c72fcc34Sopenharmony_ci#ifdef HAVE_MEMFD_CREATE
11c72fcc34Sopenharmony_ci#define _GNU_SOURCE
12c72fcc34Sopenharmony_ci#endif
13c72fcc34Sopenharmony_ci
14c72fcc34Sopenharmony_ci#include "../container.h"
15c72fcc34Sopenharmony_ci#include "../misc.h"
16c72fcc34Sopenharmony_ci
17c72fcc34Sopenharmony_ci#include "generator.h"
18c72fcc34Sopenharmony_ci
19c72fcc34Sopenharmony_ci#ifdef HAVE_MEMFD_CREATE
20c72fcc34Sopenharmony_ci#include <sys/mman.h>
21c72fcc34Sopenharmony_ci#endif
22c72fcc34Sopenharmony_ci
23c72fcc34Sopenharmony_ci#include <stdlib.h>
24c72fcc34Sopenharmony_ci#include <unistd.h>
25c72fcc34Sopenharmony_ci#include <stdbool.h>
26c72fcc34Sopenharmony_ci
27c72fcc34Sopenharmony_ci#include <assert.h>
28c72fcc34Sopenharmony_ci
29c72fcc34Sopenharmony_cistruct container_trial {
30c72fcc34Sopenharmony_ci	enum container_format format;
31c72fcc34Sopenharmony_ci
32c72fcc34Sopenharmony_ci	struct container_context cntr;
33c72fcc34Sopenharmony_ci	bool verbose;
34c72fcc34Sopenharmony_ci};
35c72fcc34Sopenharmony_ci
36c72fcc34Sopenharmony_cistatic void test_builder(struct container_context *cntr, int fd,
37c72fcc34Sopenharmony_ci			 enum container_format format,
38c72fcc34Sopenharmony_ci			 snd_pcm_access_t access,
39c72fcc34Sopenharmony_ci			 snd_pcm_format_t sample_format,
40c72fcc34Sopenharmony_ci			 unsigned int samples_per_frame,
41c72fcc34Sopenharmony_ci			 unsigned int frames_per_second,
42c72fcc34Sopenharmony_ci			 void *frame_buffer, unsigned int frame_count,
43c72fcc34Sopenharmony_ci			 bool verbose)
44c72fcc34Sopenharmony_ci{
45c72fcc34Sopenharmony_ci	snd_pcm_format_t sample;
46c72fcc34Sopenharmony_ci	unsigned int channels;
47c72fcc34Sopenharmony_ci	unsigned int rate;
48c72fcc34Sopenharmony_ci	uint64_t max_frame_count;
49c72fcc34Sopenharmony_ci	unsigned int handled_frame_count;
50c72fcc34Sopenharmony_ci	uint64_t total_frame_count;
51c72fcc34Sopenharmony_ci	int err;
52c72fcc34Sopenharmony_ci
53c72fcc34Sopenharmony_ci	err = container_builder_init(cntr, fd, format, verbose);
54c72fcc34Sopenharmony_ci	assert(err == 0);
55c72fcc34Sopenharmony_ci
56c72fcc34Sopenharmony_ci	sample = sample_format;
57c72fcc34Sopenharmony_ci	channels = samples_per_frame;
58c72fcc34Sopenharmony_ci	rate = frames_per_second;
59c72fcc34Sopenharmony_ci	max_frame_count = 0;
60c72fcc34Sopenharmony_ci	err = container_context_pre_process(cntr, &sample, &channels, &rate,
61c72fcc34Sopenharmony_ci					    &max_frame_count);
62c72fcc34Sopenharmony_ci	assert(err == 0);
63c72fcc34Sopenharmony_ci	assert(sample == sample_format);
64c72fcc34Sopenharmony_ci	assert(channels == samples_per_frame);
65c72fcc34Sopenharmony_ci	assert(rate == frames_per_second);
66c72fcc34Sopenharmony_ci	assert(max_frame_count > 0);
67c72fcc34Sopenharmony_ci
68c72fcc34Sopenharmony_ci	handled_frame_count = frame_count;
69c72fcc34Sopenharmony_ci	err = container_context_process_frames(cntr, frame_buffer,
70c72fcc34Sopenharmony_ci					       &handled_frame_count);
71c72fcc34Sopenharmony_ci	assert(err == 0);
72c72fcc34Sopenharmony_ci	assert(handled_frame_count > 0);
73c72fcc34Sopenharmony_ci	assert(handled_frame_count <= frame_count);
74c72fcc34Sopenharmony_ci
75c72fcc34Sopenharmony_ci	total_frame_count = 0;
76c72fcc34Sopenharmony_ci	err = container_context_post_process(cntr, &total_frame_count);
77c72fcc34Sopenharmony_ci	assert(err == 0);
78c72fcc34Sopenharmony_ci	assert(total_frame_count == frame_count);
79c72fcc34Sopenharmony_ci
80c72fcc34Sopenharmony_ci	container_context_destroy(cntr);
81c72fcc34Sopenharmony_ci}
82c72fcc34Sopenharmony_ci
83c72fcc34Sopenharmony_cistatic void test_parser(struct container_context *cntr, int fd,
84c72fcc34Sopenharmony_ci			enum container_format format,
85c72fcc34Sopenharmony_ci		        snd_pcm_access_t access, snd_pcm_format_t sample_format,
86c72fcc34Sopenharmony_ci		        unsigned int samples_per_frame,
87c72fcc34Sopenharmony_ci		        unsigned int frames_per_second,
88c72fcc34Sopenharmony_ci		        void *frame_buffer, unsigned int frame_count,
89c72fcc34Sopenharmony_ci			bool verbose)
90c72fcc34Sopenharmony_ci{
91c72fcc34Sopenharmony_ci	snd_pcm_format_t sample;
92c72fcc34Sopenharmony_ci	unsigned int channels;
93c72fcc34Sopenharmony_ci	unsigned int rate;
94c72fcc34Sopenharmony_ci	uint64_t total_frame_count;
95c72fcc34Sopenharmony_ci	unsigned int handled_frame_count;
96c72fcc34Sopenharmony_ci	int err;
97c72fcc34Sopenharmony_ci
98c72fcc34Sopenharmony_ci	err = container_parser_init(cntr, fd, verbose);
99c72fcc34Sopenharmony_ci	assert(err == 0);
100c72fcc34Sopenharmony_ci
101c72fcc34Sopenharmony_ci	sample = sample_format;
102c72fcc34Sopenharmony_ci	channels = samples_per_frame;
103c72fcc34Sopenharmony_ci	rate = frames_per_second;
104c72fcc34Sopenharmony_ci	total_frame_count = 0;
105c72fcc34Sopenharmony_ci	err = container_context_pre_process(cntr, &sample, &channels, &rate,
106c72fcc34Sopenharmony_ci					    &total_frame_count);
107c72fcc34Sopenharmony_ci	assert(err == 0);
108c72fcc34Sopenharmony_ci	assert(sample == sample_format);
109c72fcc34Sopenharmony_ci	assert(channels == samples_per_frame);
110c72fcc34Sopenharmony_ci	assert(rate == frames_per_second);
111c72fcc34Sopenharmony_ci	assert(total_frame_count == frame_count);
112c72fcc34Sopenharmony_ci
113c72fcc34Sopenharmony_ci	handled_frame_count = total_frame_count;
114c72fcc34Sopenharmony_ci	err = container_context_process_frames(cntr, frame_buffer,
115c72fcc34Sopenharmony_ci					       &handled_frame_count);
116c72fcc34Sopenharmony_ci	assert(err == 0);
117c72fcc34Sopenharmony_ci	assert(handled_frame_count == frame_count);
118c72fcc34Sopenharmony_ci
119c72fcc34Sopenharmony_ci	total_frame_count = 0;
120c72fcc34Sopenharmony_ci	err = container_context_post_process(cntr, &total_frame_count);
121c72fcc34Sopenharmony_ci	assert(err == 0);
122c72fcc34Sopenharmony_ci	assert(total_frame_count == handled_frame_count);
123c72fcc34Sopenharmony_ci
124c72fcc34Sopenharmony_ci	container_context_destroy(cntr);
125c72fcc34Sopenharmony_ci}
126c72fcc34Sopenharmony_ci
127c72fcc34Sopenharmony_cistatic int callback(struct test_generator *gen, snd_pcm_access_t access,
128c72fcc34Sopenharmony_ci		    snd_pcm_format_t sample_format,
129c72fcc34Sopenharmony_ci		    unsigned int samples_per_frame, void *frame_buffer,
130c72fcc34Sopenharmony_ci		    unsigned int frame_count)
131c72fcc34Sopenharmony_ci{
132c72fcc34Sopenharmony_ci	static const unsigned int entries[] = {
133c72fcc34Sopenharmony_ci		[0] = 44100,
134c72fcc34Sopenharmony_ci		[1] = 48000,
135c72fcc34Sopenharmony_ci		[2] = 88200,
136c72fcc34Sopenharmony_ci		[3] = 96000,
137c72fcc34Sopenharmony_ci		[4] = 176400,
138c72fcc34Sopenharmony_ci		[5] = 192000,
139c72fcc34Sopenharmony_ci	};
140c72fcc34Sopenharmony_ci	struct container_trial *trial = gen->private_data;
141c72fcc34Sopenharmony_ci	unsigned int frames_per_second;
142c72fcc34Sopenharmony_ci	const char *const name = "hoge";
143c72fcc34Sopenharmony_ci	unsigned int size;
144c72fcc34Sopenharmony_ci	void *buf;
145c72fcc34Sopenharmony_ci	int i;
146c72fcc34Sopenharmony_ci	int err = 0;
147c72fcc34Sopenharmony_ci
148c72fcc34Sopenharmony_ci	size = frame_count * samples_per_frame *
149c72fcc34Sopenharmony_ci			snd_pcm_format_physical_width(sample_format) / 8;
150c72fcc34Sopenharmony_ci	buf = malloc(size);
151c72fcc34Sopenharmony_ci	if (buf == NULL)
152c72fcc34Sopenharmony_ci		return -ENOMEM;
153c72fcc34Sopenharmony_ci
154c72fcc34Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
155c72fcc34Sopenharmony_ci		int fd;
156c72fcc34Sopenharmony_ci		off_t pos;
157c72fcc34Sopenharmony_ci
158c72fcc34Sopenharmony_ci		frames_per_second = entries[i];
159c72fcc34Sopenharmony_ci
160c72fcc34Sopenharmony_ci#ifdef HAVE_MEMFD_CREATE
161c72fcc34Sopenharmony_ci		fd = memfd_create(name, 0);
162c72fcc34Sopenharmony_ci#else
163c72fcc34Sopenharmony_ci		fd = open(name, O_RDWR | O_CREAT | O_TRUNC, 0644);
164c72fcc34Sopenharmony_ci#endif
165c72fcc34Sopenharmony_ci		if (fd < 0) {
166c72fcc34Sopenharmony_ci			err = -errno;
167c72fcc34Sopenharmony_ci			break;
168c72fcc34Sopenharmony_ci		}
169c72fcc34Sopenharmony_ci
170c72fcc34Sopenharmony_ci		test_builder(&trial->cntr, fd, trial->format, access,
171c72fcc34Sopenharmony_ci			     sample_format, samples_per_frame,
172c72fcc34Sopenharmony_ci			     frames_per_second, frame_buffer, frame_count,
173c72fcc34Sopenharmony_ci			     trial->verbose);
174c72fcc34Sopenharmony_ci
175c72fcc34Sopenharmony_ci		pos = lseek(fd, 0, SEEK_SET);
176c72fcc34Sopenharmony_ci		if (pos < 0) {
177c72fcc34Sopenharmony_ci			err = -errno;
178c72fcc34Sopenharmony_ci			break;
179c72fcc34Sopenharmony_ci		}
180c72fcc34Sopenharmony_ci
181c72fcc34Sopenharmony_ci		test_parser(&trial->cntr, fd, trial->format, access,
182c72fcc34Sopenharmony_ci			    sample_format, samples_per_frame, frames_per_second,
183c72fcc34Sopenharmony_ci			    buf, frame_count, trial->verbose);
184c72fcc34Sopenharmony_ci
185c72fcc34Sopenharmony_ci		err = memcmp(buf, frame_buffer, size);
186c72fcc34Sopenharmony_ci		assert(err == 0);
187c72fcc34Sopenharmony_ci
188c72fcc34Sopenharmony_ci		close(fd);
189c72fcc34Sopenharmony_ci	}
190c72fcc34Sopenharmony_ci
191c72fcc34Sopenharmony_ci	free(buf);
192c72fcc34Sopenharmony_ci
193c72fcc34Sopenharmony_ci	return err;
194c72fcc34Sopenharmony_ci}
195c72fcc34Sopenharmony_ci
196c72fcc34Sopenharmony_ciint main(int argc, const char *argv[])
197c72fcc34Sopenharmony_ci{
198c72fcc34Sopenharmony_ci	static const uint64_t sample_format_masks[] = {
199c72fcc34Sopenharmony_ci		[CONTAINER_FORMAT_RIFF_WAVE] =
200c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U8) |
201c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S16_LE) |
202c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S16_BE) |
203c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_LE) |
204c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_BE) |
205c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S32_LE) |
206c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S32_BE) |
207c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT_LE) |
208c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT_BE) |
209c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT64_LE) |
210c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT64_BE) |
211c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_MU_LAW) |
212c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_A_LAW) |
213c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_3LE) |
214c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_3BE) |
215c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S20_3LE) |
216c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S20_3BE) |
217c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S18_3LE) |
218c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S18_3BE),
219c72fcc34Sopenharmony_ci		[CONTAINER_FORMAT_AU] =
220c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S8) |
221c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S16_BE) |
222c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S32_BE) |
223c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT_BE) |
224c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT64_BE) |
225c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_MU_LAW) |
226c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_A_LAW),
227c72fcc34Sopenharmony_ci		[CONTAINER_FORMAT_VOC] =
228c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U8) |
229c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S16_LE) |
230c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_MU_LAW) |
231c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_A_LAW),
232c72fcc34Sopenharmony_ci		[CONTAINER_FORMAT_RAW] =
233c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S8) |
234c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U8) |
235c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S16_LE) |
236c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S16_BE) |
237c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U16_LE) |
238c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U16_BE) |
239c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_LE) |
240c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_BE) |
241c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U24_LE) |
242c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U24_BE) |
243c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S32_LE) |
244c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S32_BE) |
245c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U32_LE) |
246c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U32_BE) |
247c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT_LE) |
248c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT_BE) |
249c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT64_LE) |
250c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_FLOAT64_BE) |
251c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_IEC958_SUBFRAME_LE) |
252c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_IEC958_SUBFRAME_BE) |
253c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_MU_LAW) |
254c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_A_LAW) |
255c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_3LE) |
256c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S24_3BE) |
257c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U24_3LE) |
258c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U24_3BE) |
259c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S20_3LE) |
260c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S20_3BE) |
261c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U20_3LE) |
262c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U20_3BE) |
263c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S18_3LE) |
264c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_S18_3BE) |
265c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U18_3LE) |
266c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_U18_3BE) |
267c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_DSD_U8) |
268c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_DSD_U16_LE) |
269c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_DSD_U32_LE) |
270c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_DSD_U16_BE) |
271c72fcc34Sopenharmony_ci			(1ull << SND_PCM_FORMAT_DSD_U32_BE),
272c72fcc34Sopenharmony_ci	};
273c72fcc34Sopenharmony_ci	static const uint64_t access_mask =
274c72fcc34Sopenharmony_ci		(1ull << SND_PCM_ACCESS_MMAP_INTERLEAVED) |
275c72fcc34Sopenharmony_ci		(1ull << SND_PCM_ACCESS_RW_INTERLEAVED);
276c72fcc34Sopenharmony_ci	struct test_generator gen = {0};
277c72fcc34Sopenharmony_ci	struct container_trial *trial;
278c72fcc34Sopenharmony_ci	int i;
279c72fcc34Sopenharmony_ci	int begin;
280c72fcc34Sopenharmony_ci	int end;
281c72fcc34Sopenharmony_ci	bool verbose;
282c72fcc34Sopenharmony_ci	int err;
283c72fcc34Sopenharmony_ci
284c72fcc34Sopenharmony_ci	if (argc > 1) {
285c72fcc34Sopenharmony_ci		char *term;
286c72fcc34Sopenharmony_ci		begin = strtol(argv[1], &term, 10);
287c72fcc34Sopenharmony_ci		if (errno || *term != '\0')
288c72fcc34Sopenharmony_ci			return EXIT_FAILURE;
289c72fcc34Sopenharmony_ci		if (begin < CONTAINER_FORMAT_RIFF_WAVE &&
290c72fcc34Sopenharmony_ci		    begin > CONTAINER_FORMAT_RAW)
291c72fcc34Sopenharmony_ci			return -EXIT_FAILURE;
292c72fcc34Sopenharmony_ci		end = begin + 1;
293c72fcc34Sopenharmony_ci		verbose = true;
294c72fcc34Sopenharmony_ci	} else {
295c72fcc34Sopenharmony_ci		begin = CONTAINER_FORMAT_RIFF_WAVE;
296c72fcc34Sopenharmony_ci		end = CONTAINER_FORMAT_RAW + 1;
297c72fcc34Sopenharmony_ci		verbose = false;
298c72fcc34Sopenharmony_ci	}
299c72fcc34Sopenharmony_ci
300c72fcc34Sopenharmony_ci	for (i = begin; i < end; ++i) {
301c72fcc34Sopenharmony_ci		err = generator_context_init(&gen, access_mask,
302c72fcc34Sopenharmony_ci					     sample_format_masks[i],
303c72fcc34Sopenharmony_ci					     1, 32, 23, 3000, 512,
304c72fcc34Sopenharmony_ci					     sizeof(struct container_trial));
305c72fcc34Sopenharmony_ci		if (err >= 0) {
306c72fcc34Sopenharmony_ci			trial = gen.private_data;
307c72fcc34Sopenharmony_ci			trial->format = i;
308c72fcc34Sopenharmony_ci			trial->verbose = verbose;
309c72fcc34Sopenharmony_ci			err = generator_context_run(&gen, callback);
310c72fcc34Sopenharmony_ci		}
311c72fcc34Sopenharmony_ci
312c72fcc34Sopenharmony_ci		generator_context_destroy(&gen);
313c72fcc34Sopenharmony_ci
314c72fcc34Sopenharmony_ci		if (err < 0)
315c72fcc34Sopenharmony_ci			break;
316c72fcc34Sopenharmony_ci	}
317c72fcc34Sopenharmony_ci
318c72fcc34Sopenharmony_ci	if (err < 0) {
319c72fcc34Sopenharmony_ci		printf("%s\n", strerror(-err));
320c72fcc34Sopenharmony_ci		return EXIT_FAILURE;
321c72fcc34Sopenharmony_ci	}
322c72fcc34Sopenharmony_ci
323c72fcc34Sopenharmony_ci	return EXIT_SUCCESS;
324c72fcc34Sopenharmony_ci}
325