source: rtems/testsuites/libtests/newlib01/init.c @ 3f7ebdd

Last change on this file since 3f7ebdd was 3f7ebdd, checked in by Chris Johns <chrisj@…>, on Feb 14, 2020 at 3:16:17 AM

testsuite/newlib: Check newlib does not touch an assigned std FILE pointer

Update #3870

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <stdio.h>
20
21#include <sys/reent.h>
22
23#include <rtems.h>
24#include <rtems/console.h>
25#include <rtems/imfs.h>
26#include <rtems/libcsupport.h>
27
28#include "tmacros.h"
29
30const char rtems_test_name[] = "NEWLIB 1";
31
32static const char file_path[] = "/file";
33
34typedef enum {
35  INIT,
36  OPEN,
37  WRITTEN,
38  CLOSED
39} test_state;
40
41typedef struct {
42  rtems_id main_task_id;
43  rtems_id worker_task_id;
44  test_state current;
45} test_context;
46
47static test_context test_instance;
48
49static void wake_up_main(const test_context *ctx)
50{
51  rtems_status_code sc;
52
53  sc = rtems_event_transient_send(ctx->main_task_id);
54  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
55}
56
57static void wait(void)
58{
59  rtems_status_code sc;
60
61  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
62  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
63}
64
65static void worker_task(rtems_task_argument arg)
66{
67  test_context *ctx = &test_instance;
68  struct _reent *reent = _REENT;
69  FILE *output;
70  char buf[1] = { 'x' };
71  size_t n;
72
73  rtems_test_assert(reent->__sdidinit == 0);
74
75  output = stdout = fopen(&file_path[0], "r+");
76  rtems_test_assert(stdout != NULL);
77
78  /*
79   * Check newlib's __sinit does not touch our assigned file pointer.
80   */
81  rtems_test_assert(reent->__sdidinit == 0);
82  rtems_test_assert(fflush(stdout) == 0);
83  rtems_test_assert(reent->__sdidinit != 0);
84  rtems_test_assert(stdout == output);
85
86  n = fwrite(&buf[0], sizeof(buf), 1, stdout);
87  rtems_test_assert(n == 1);
88
89  rtems_test_assert(ctx->current == OPEN);
90
91  wake_up_main(ctx);
92
93  rtems_test_assert(0);
94}
95
96static int handler_open(
97  rtems_libio_t *iop,
98  const char *path,
99  int oflag,
100  mode_t mode
101)
102{
103  test_context *ctx = &test_instance;
104
105  rtems_test_assert(ctx->current == INIT);
106  ctx->current = OPEN;
107
108  return 0;
109}
110
111static int handler_close(
112  rtems_libio_t *iop
113)
114{
115  test_context *ctx = &test_instance;
116
117  rtems_test_assert(ctx->current == WRITTEN);
118  ctx->current = CLOSED;
119
120  return 0;
121}
122
123static ssize_t handler_read(
124  rtems_libio_t *iop,
125  void *buffer,
126  size_t count
127)
128{
129  rtems_test_assert(0);
130
131  return 0;
132}
133
134static ssize_t handler_write(
135  rtems_libio_t *iop,
136  const void *buffer,
137  size_t count
138)
139{
140  test_context *ctx = &test_instance;
141
142  rtems_test_assert(ctx->current == OPEN);
143  ctx->current = WRITTEN;
144
145  iop->offset += count;
146
147  return (ssize_t) count;
148}
149
150static int handler_ioctl(
151  rtems_libio_t *iop,
152  ioctl_command_t request,
153  void *buffer
154)
155{
156  rtems_test_assert(0);
157
158  return 0;
159}
160
161static off_t handler_lseek(
162  rtems_libio_t *iop,
163  off_t length,
164  int whence
165)
166{
167  rtems_test_assert(0);
168
169  return 0;
170}
171
172static int handler_ftruncate(
173  rtems_libio_t *iop,
174  off_t length
175)
176{
177  rtems_test_assert(0);
178
179  return 0;
180}
181
182static int handler_fsync(
183  rtems_libio_t *iop
184)
185{
186  rtems_test_assert(0);
187
188  return 0;
189}
190
191static int handler_fdatasync(
192  rtems_libio_t *iop
193)
194{
195  rtems_test_assert(0);
196
197  return 0;
198}
199
200static int handler_fcntl(
201  rtems_libio_t *iop,
202  int cmd
203)
204{
205  rtems_test_assert(0);
206
207  return 0;
208}
209
210static ssize_t handler_readv(
211  rtems_libio_t *iop,
212  const struct iovec *iov,
213  int iovcnt,
214  ssize_t total
215)
216{
217  rtems_test_assert(0);
218
219  return 0;
220}
221
222static ssize_t handler_writev(
223  rtems_libio_t *iop,
224  const struct iovec *iov,
225  int iovcnt,
226  ssize_t total
227)
228{
229  rtems_test_assert(0);
230
231  return 0;
232}
233
234static const rtems_filesystem_file_handlers_r node_handlers = {
235  .open_h = handler_open,
236  .close_h = handler_close,
237  .read_h = handler_read,
238  .write_h = handler_write,
239  .ioctl_h = handler_ioctl,
240  .lseek_h = handler_lseek,
241  .fstat_h = rtems_filesystem_default_fstat,
242  .ftruncate_h = handler_ftruncate,
243  .fsync_h = handler_fsync,
244  .fdatasync_h = handler_fdatasync,
245  .fcntl_h = handler_fcntl,
246  .readv_h = handler_readv,
247  .writev_h = handler_writev
248};
249
250static const IMFS_node_control node_control = IMFS_GENERIC_INITIALIZER(
251  &node_handlers,
252  IMFS_node_initialize_default,
253  IMFS_node_destroy_default
254);
255
256static void test(void)
257{
258  test_context *ctx = &test_instance;
259  rtems_status_code sc;
260  int rv;
261  rtems_resource_snapshot snapshot;
262  FILE *file;
263
264  ctx->main_task_id = rtems_task_self();
265
266  /* Fill dynamic file pool in Newlib _GLOBAL_REENT */
267  file = fopen(CONSOLE_DEVICE_NAME, "r+");
268  rtems_test_assert(file != NULL);
269  rv = fclose(file);
270  rtems_test_assert(rv == 0);
271
272  rtems_resource_snapshot_take(&snapshot);
273
274  rv = IMFS_make_generic_node(
275    &file_path[0],
276    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
277    &node_control,
278    NULL
279  );
280  rtems_test_assert(rv == 0);
281
282  sc = rtems_task_create(
283    rtems_build_name('W', 'O', 'R', 'K'),
284    2,
285    RTEMS_MINIMUM_STACK_SIZE,
286    RTEMS_DEFAULT_MODES,
287    RTEMS_DEFAULT_ATTRIBUTES,
288    &ctx->worker_task_id
289  );
290  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
291
292  sc = rtems_task_start(ctx->worker_task_id, worker_task, 0);
293  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
294
295  wait();
296
297  sc = rtems_task_delete(ctx->worker_task_id);
298  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
299
300  rv = unlink(&file_path[0]);
301  rtems_test_assert(rv == 0);
302
303  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
304}
305
306static void Init(rtems_task_argument arg)
307{
308  TEST_BEGIN();
309
310  test();
311
312  TEST_END();
313  rtems_test_exit(0);
314}
315
316#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
317#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
318
319#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
320
321#define CONFIGURE_MAXIMUM_TASKS 2
322
323#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
324
325#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
326
327#define CONFIGURE_INIT
328
329#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.