mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-02 04:39:01 +00:00
Now that time_t is unconditionally 64-bit (signed int64_t) and the
struct timespec fields tv_sec / tv_nsec are wide enough on their own,
the explicit (uint64_t)/(int64_t)/(int) casts that used to guard the
multiplications and subtractions in *_us / *_ms / *_ns helpers are no
longer needed. Drop them to keep the timekeeping math readable.
In the same spirit, this commit also normalises the printf-style format
specifiers and casts used to print tv_sec / tv_nsec / tv_usec values.
The prior code was a mix of "%d"/"%u"/"%ld"/"%lu"/"%lld" with matching
(int)/(unsigned long)/(long long) casts; some formats truncated time_t
on 32-bit hosts, others mismatched signedness or width. Replace all
such cases with the portable POSIX-recommended forms:
- tv_sec (time_t, signed, impl-defined width) -> %jd + (intmax_t)
- tv_nsec (long, signed) -> %ld (no cast)
- tv_usec (suseconds_t / long) -> %ld (no cast)
Also drop two stale `(FAR const time_t *)&ts.tv_sec` casts that are
unnecessary now that ts.tv_sec is plain time_t.
Arithmetic-cleanup files (existing scope):
- benchmarks/cyclictest/cyclictest.c: timediff_us()
- benchmarks/sd_bench/sd_bench_main.c: get_time_delta_us()
- examples/oneshot/oneshot_main.c: maxus computation
- examples/watchdog/watchdog_main.c: current_time_ms (x2)
- industry/nxmodbus/nxmb_internal.h: nxmb_util_clock_ms()
- netutils/ntpclient/ntpclient.c: timespec2ntp()
- netutils/ptpd/ptpd.c: ptp_adjtime()
- system/dd/dd_main.c: elapsed accounting
- testing/drivers/drivertest/drivertest_posix_timer.c:
get_timestamp()
- testing/drivers/sd_stress/sd_stress_main.c:get_time_delta()
- testing/sched/getprime/getprime_main.c: elapsed accounting
- testing/sched/pthread_mutex_perf/pthread_mutex_perf.c:
timespec_avg()
Printf-format-fix files (new in this revision):
- examples/adjtime/adjtime_main.c
- examples/charger/charger_main.c
- examples/netpkt/netpkt_ethercat.c
- fsutils/mkfatfs/mkfatfs.c
- graphics/tiff/tiff_initialize.c
- netutils/ptpd/ptpd.c
- nshlib/nsh_timcmds.c
- system/coredump/coredump.c
- system/ptpd/ptpd_main.c
- testing/drivers/drivertest/drivertest_oneshot.c
- testing/mm/kasantest/kasantest.c
- testing/ostest/semtimed.c
- testing/sched/pthread_mutex_perf/pthread_mutex_perf.c
- testing/sched/timerjitter/timerjitter.c
- testing/testsuites/kernel/time/cases/clock_test_clock01.c
- testing/testsuites/kernel/time/cases/clock_test_smoke.c
No behavioural change.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
379 lines
11 KiB
C
379 lines
11 KiB
C
/****************************************************************************
|
|
* apps/testing/testsuites/kernel/syscall/cases/pread_test.c
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
#include <nuttx/config.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <syslog.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <inttypes.h>
|
|
#include <stdint.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <setjmp.h>
|
|
#include <cmocka.h>
|
|
#include "SyscallTest.h"
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#define K1 32
|
|
#define K2 (K1 * 2)
|
|
#define K3 (K1 * 3)
|
|
#define K4 (K1 * 4)
|
|
#define K5 (K1 * 5)
|
|
|
|
/****************************************************************************
|
|
* Private data Prototypes
|
|
****************************************************************************/
|
|
|
|
char pread01_filename[64] = "";
|
|
int pread01_fildes; /* file descriptor for tempfile */
|
|
char *pread01_write_buf[4]; /* buffer to hold data to be written */
|
|
char *pread01_read_buf[4]; /* buffer to hold data read from file */
|
|
|
|
/****************************************************************************
|
|
* Private Function Prototypes
|
|
****************************************************************************/
|
|
|
|
void pread01_setup(void); /* Main setup function of test */
|
|
void pread01_cleanup(void); /* cleanup function for the test */
|
|
void pread01_l_seek(int, off_t, int,
|
|
off_t); /* function to call lseek() */
|
|
void pread01_init_buffers(
|
|
void); /* function to initialize/allocate buffers */
|
|
int pread01_compare_bufers(
|
|
void); /* function to compare o/p of pread/pwrite */
|
|
|
|
/****************************************************************************
|
|
* Private Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: pread01_init_buffers
|
|
****************************************************************************/
|
|
|
|
/* init_buffers - allocates both write_buf and read_buf arrays.
|
|
* Allocate the read and write buffers.
|
|
* Fill the write buffer with the following data like,
|
|
* write_buf[0] has 0's, write_buf[1] has 1's, write_buf[2] has 2's
|
|
* write_buf[3] has 3's.
|
|
*/
|
|
|
|
void pread01_init_buffers(void)
|
|
{
|
|
int count; /* counter variable for loop */
|
|
|
|
/* Allocate and Initialize read/write buffer */
|
|
|
|
for (count = 0; count < 4; count++)
|
|
{
|
|
pread01_write_buf[count] = (char *)malloc(K1);
|
|
pread01_read_buf[count] = (char *)malloc(K1);
|
|
|
|
if ((pread01_write_buf[count] == NULL) ||
|
|
(pread01_read_buf[count] == NULL))
|
|
{
|
|
syslog(LOG_ERR, "malloc() failed on read/write buffers\n");
|
|
}
|
|
|
|
memset(pread01_write_buf[count], count, K1);
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: pread01_setup
|
|
****************************************************************************/
|
|
|
|
/* setup() - performs all ONE TIME setup for this test.
|
|
*
|
|
* Initialize/allocate read/write buffers.
|
|
* Create a temporary directory and a file under it and
|
|
* write know data at different offset positions.
|
|
*/
|
|
|
|
void pread01_setup(void)
|
|
{
|
|
int nwrite = 0; /* no. of bytes written by pwrite() */
|
|
|
|
/* Allocate/Initialize the read/write buffer with know data */
|
|
|
|
pread01_init_buffers();
|
|
|
|
sprintf(pread01_filename, "%s_tstfile", __func__);
|
|
|
|
/* Creat a temporary file used for mapping */
|
|
|
|
if ((pread01_fildes = open(pread01_filename, O_RDWR | O_CREAT, 0666)) <
|
|
0)
|
|
{
|
|
syslog(LOG_ERR, "FAIL, open() on %s failed, errno=%d : %s\n",
|
|
pread01_filename, errno, strerror(errno));
|
|
}
|
|
|
|
if (pread01_fildes > 0)
|
|
{
|
|
/* pwrite() K1 of data (0's) at offset 0 of temporary file */
|
|
|
|
if ((nwrite = pwrite(pread01_fildes, pread01_write_buf[0], K1,
|
|
0)) != K1)
|
|
{
|
|
syslog(LOG_ERR,
|
|
"pwrite() failed to write on %s, "
|
|
"errno=%d : %s\n",
|
|
pread01_filename, errno, strerror(errno));
|
|
}
|
|
|
|
/* We should still be at offset 0. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, 0);
|
|
|
|
/* Now, lseek() to a non K boundary, just to be different. */
|
|
|
|
pread01_l_seek(pread01_fildes, K1 / 2, SEEK_SET, K1 / 2);
|
|
|
|
/* Again, pwrite() K1 of data (2's) at offset K2 of temporary file
|
|
*/
|
|
|
|
if ((nwrite = pwrite(pread01_fildes, pread01_write_buf[2], K1,
|
|
K2)) != K1)
|
|
{
|
|
syslog(LOG_ERR,
|
|
"FAIL, pwrite() failed to write at %d off. "
|
|
"on %s, errno=%d : %s\n",
|
|
K2, pread01_filename, errno, strerror(errno));
|
|
}
|
|
|
|
/* We should still be at our non K boundary. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, K1 / 2);
|
|
|
|
/* lseek() to an offset of K3. */
|
|
|
|
pread01_l_seek(pread01_fildes, K3, SEEK_SET, K3);
|
|
|
|
/* Using write(), write of K1 of data (3's) which should take
|
|
* place at an offset of K3, moving the file pointer to K4.
|
|
*/
|
|
|
|
if ((nwrite = write(pread01_fildes, pread01_write_buf[3], K1)) !=
|
|
K1)
|
|
{
|
|
syslog(LOG_ERR,
|
|
"write() failed: nwrite=%d, errno=%d "
|
|
": %s\n",
|
|
nwrite, errno, strerror(errno));
|
|
}
|
|
|
|
/* We should be at offset K4. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, K4);
|
|
|
|
/* Again, pwrite() K1 of data (1's) at offset K1. */
|
|
|
|
if ((nwrite = pwrite(pread01_fildes, pread01_write_buf[1], K1,
|
|
K1)) != K1)
|
|
{
|
|
syslog(LOG_ERR,
|
|
"pwrite() failed to write at %d off. "
|
|
"on %s, errno=%d : %s\n",
|
|
K1, pread01_filename, errno, strerror(errno));
|
|
}
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: pread01_l_seek
|
|
****************************************************************************/
|
|
|
|
/* l_seek() - local front end to lseek().
|
|
*
|
|
* "checkoff" is the offset at which we believe we should be at.
|
|
* Used to validate pread/pwrite don't move the offset.
|
|
*/
|
|
|
|
void pread01_l_seek(int fdesc, off_t offset, int whence, off_t checkoff)
|
|
{
|
|
off_t offloc; /* offset ret. from lseek() */
|
|
|
|
if ((offloc = lseek(fdesc, offset, whence)) != checkoff)
|
|
{
|
|
syslog(LOG_WARNING,
|
|
"return = %jd, expected %jd\n",
|
|
(intmax_t)offloc, (intmax_t)checkoff);
|
|
syslog(LOG_ERR, "lseek() on %s failed\n", pread01_filename);
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: pread01_compare_bufers
|
|
****************************************************************************/
|
|
|
|
/* compare_bufers() - Compare the contents of read buffer against the
|
|
* write buffer contents.
|
|
*
|
|
* The contents of the index of each buffer should be as follows:
|
|
* [0] has 0's, [1] has 1's, [2] has 2's, and [3] has 3's.
|
|
*
|
|
* This function does memcmp of read/write buffer and display message
|
|
* about the functionality of pread().
|
|
*/
|
|
|
|
int pread01_compare_bufers(void)
|
|
{
|
|
int count; /* index for the loop */
|
|
int err_flg = 0; /* flag to indicate error */
|
|
|
|
for (count = 0; count < 4; count++)
|
|
{
|
|
if (memcmp(pread01_write_buf[count], pread01_read_buf[count],
|
|
K1) != 0)
|
|
{
|
|
syslog(LOG_ERR, "FAIL, read/write buffer data mismatch\n");
|
|
err_flg++;
|
|
}
|
|
}
|
|
|
|
/* If no errors, Test successful */
|
|
|
|
if (!err_flg)
|
|
{
|
|
/* syslog(LOG_INFO, "PASS, Functionality of pread() is correct\n"); */
|
|
|
|
return 0;
|
|
}
|
|
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: pread01_cleanup
|
|
****************************************************************************/
|
|
|
|
void pread01_cleanup(void)
|
|
{
|
|
int count;
|
|
|
|
/* Free the memory allocated for the read/write buffer */
|
|
|
|
for (count = 0; count < 4; count++)
|
|
{
|
|
free(pread01_write_buf[count]);
|
|
free(pread01_read_buf[count]);
|
|
}
|
|
|
|
/* Close the temporary file */
|
|
|
|
close(pread01_fildes);
|
|
|
|
unlink(pread01_filename);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: test_nuttx_syscall_pread01
|
|
****************************************************************************/
|
|
|
|
void test_nuttx_syscall_pread01(FAR void **state)
|
|
{
|
|
int lc;
|
|
int nread; /* no. of bytes read by pread() */
|
|
|
|
pread01_setup();
|
|
|
|
for (lc = 0; lc < 1; lc++)
|
|
{
|
|
/* Call pread() of K1 data (should be 2's) at offset K2.
|
|
*/
|
|
|
|
nread = pread(pread01_fildes, pread01_read_buf[2], K1, K2);
|
|
|
|
/* Check for the return value of pread() */
|
|
|
|
assert_int_equal(nread, K1);
|
|
|
|
/* We should still be at offset K4,
|
|
* which we were at the end of block 0.
|
|
*/
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, K4);
|
|
|
|
/* Now lseek() to offset 0. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_SET, 0);
|
|
|
|
/* pread() K1 of data (should be 3's) at offset K3. */
|
|
|
|
nread = pread(pread01_fildes, pread01_read_buf[3], K1, K3);
|
|
assert_int_equal(nread, K1);
|
|
|
|
/* We should still be at offset 0. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, 0);
|
|
|
|
/* Do a normal read() of K1 data (should be 0's)
|
|
* which should take place at offset 0 and move the
|
|
* file pointer to an offset of K1.
|
|
*/
|
|
|
|
nread = read(pread01_fildes, pread01_read_buf[0], K1);
|
|
assert_int_equal(nread, K1);
|
|
|
|
/* We should now be at an offset of K1. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, K1);
|
|
|
|
/* pread() of K1 data (should be 1's) at offset K1. */
|
|
|
|
nread = pread(pread01_fildes, pread01_read_buf[1], K1, K1);
|
|
assert_int_equal(nread, K1);
|
|
|
|
/* We should still be at offset K1. */
|
|
|
|
pread01_l_seek(pread01_fildes, 0, SEEK_CUR, K1);
|
|
|
|
/* Compare the read buffer data read
|
|
* with the data written to write buffer
|
|
* in the setup.
|
|
*/
|
|
|
|
assert_int_equal(pread01_compare_bufers(), 0);
|
|
|
|
/* reset our location to offset K4 in case we are looping */
|
|
|
|
pread01_l_seek(pread01_fildes, K4, SEEK_SET, K4);
|
|
}
|
|
|
|
pread01_cleanup();
|
|
}
|