source: rtems/testsuites/fstests/fsclose01/init.c @ 98c6d50

5
Last change on this file since 98c6d50 was 98c6d50, checked in by Chris Johns <chrisj@…>, on 10/19/17 at 05:39:16

testsuite: Use printk for all test output where possible.

  • Remove the printf support leaving the direct printk support configured with TESTS_USE_PRINTK and all other output goes via a buffered vsniprintf call to printk.
  • Control the test's single init for functions and global data with TEST_INIT and not CONFIGURE_INIT. They are now separate.

Updates #3170.

  • Property mode set to 100644
File size: 10.3 KB
Line 
1/*
2 * Copyright (c) 2012, 2017 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#define TEST_INIT
20
21#include <sys/stat.h>
22#include <sys/ioctl.h>
23#include <sys/uio.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <errno.h>
27
28#include <rtems/imfs.h>
29#include <rtems/malloc.h>
30#include <rtems/libcsupport.h>
31
32#include <tmacros.h>
33
34const char rtems_test_name[] = "FSCLOSE 1";
35
36typedef enum {
37  ACTION_ClOSE,
38  ACTION_FCNTL,
39  ACTION_FDATASYNC,
40  ACTION_FCHDIR,
41  ACTION_FCHMOD,
42  ACTION_FCHOWN,
43  /* ACTION_FPATHCONF, not easy to test */
44  ACTION_FSTAT,
45  ACTION_FSYNC,
46  ACTION_FTRUNCATE,
47  ACTION_IOCTL,
48  ACTION_LSEEK,
49  ACTION_READ,
50  ACTION_READV,
51  ACTION_WRITE,
52  ACTION_WRITEV
53} test_action;
54
55typedef struct {
56  rtems_id worker_id;
57  int fd;
58  test_action action;
59  bool wait_in_close;
60  bool wait_in_fstat;
61  int close_count;
62  int fcntl_count;
63  int fdatasync_count;
64  int fstat_count;
65  int fsync_count;
66  int ftruncate_count;
67  int ioctl_count;
68  int lseek_count;
69  int open_count;
70  int read_count;
71  int readv_count;
72  int write_count;
73  int writev_count;
74} test_context;
75
76static test_context test_instance;
77
78static void wait(void)
79{
80  rtems_status_code sc;
81
82  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
83  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
84}
85
86static void wakeup_worker(const test_context *ctx)
87{
88  rtems_status_code sc;
89
90  sc = rtems_event_transient_send(ctx->worker_id);
91  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
92}
93
94static int handler_open(
95  rtems_libio_t *iop,
96  const char *path,
97  int oflag,
98  mode_t mode
99)
100{
101  test_context *ctx;
102
103  ctx = IMFS_generic_get_context_by_iop(iop);
104  ++ctx->open_count;
105
106  return 0;
107}
108
109static int handler_close(
110  rtems_libio_t *iop
111)
112{
113  test_context *ctx;
114
115  ctx = IMFS_generic_get_context_by_iop(iop);
116  ++ctx->close_count;
117
118  if (ctx->wait_in_close) {
119    ctx->wait_in_close = false;
120    wait();
121  }
122
123  return 0;
124}
125
126static ssize_t handler_read(
127  rtems_libio_t *iop,
128  void *buffer,
129  size_t count
130)
131{
132  test_context *ctx;
133
134  ctx = IMFS_generic_get_context_by_iop(iop);
135  ++ctx->read_count;
136
137  wait();
138  return 0;
139}
140
141static ssize_t handler_write(
142  rtems_libio_t *iop,
143  const void *buffer,
144  size_t count
145)
146{
147  test_context *ctx;
148
149  ctx = IMFS_generic_get_context_by_iop(iop);
150  ++ctx->write_count;
151
152  wait();
153  return 0;
154}
155
156static int handler_ioctl(
157  rtems_libio_t *iop,
158  ioctl_command_t request,
159  void *buffer
160)
161{
162  test_context *ctx;
163
164  ctx = IMFS_generic_get_context_by_iop(iop);
165  ++ctx->ioctl_count;
166
167  wait();
168  return 0;
169}
170
171static off_t handler_lseek(
172  rtems_libio_t *iop,
173  off_t length,
174  int whence
175)
176{
177  test_context *ctx;
178
179  ctx = IMFS_generic_get_context_by_iop(iop);
180  ++ctx->lseek_count;
181
182  wait();
183  return 0;
184}
185
186static int handler_fstat(
187  const rtems_filesystem_location_info_t *loc,
188  struct stat *buf
189)
190{
191  test_context *ctx;
192
193  buf->st_mode = S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO;
194  ctx = IMFS_generic_get_context_by_location(loc);
195  ++ctx->fstat_count;
196
197  if (ctx->wait_in_fstat) {
198    ctx->wait_in_fstat = false;
199    wait();
200  }
201
202  return 0;
203}
204
205static int handler_ftruncate(
206  rtems_libio_t *iop,
207  off_t length
208)
209{
210  test_context *ctx;
211
212  ctx = IMFS_generic_get_context_by_iop(iop);
213  ++ctx->ftruncate_count;
214
215  wait();
216  return 0;
217}
218
219static int handler_fsync(
220  rtems_libio_t *iop
221)
222{
223  test_context *ctx;
224
225  ctx = IMFS_generic_get_context_by_iop(iop);
226  ++ctx->fsync_count;
227
228  wait();
229  return 0;
230}
231
232static int handler_fdatasync(
233  rtems_libio_t *iop
234)
235{
236  test_context *ctx;
237
238  ctx = IMFS_generic_get_context_by_iop(iop);
239  ++ctx->fdatasync_count;
240
241  wait();
242  return 0;
243}
244
245static int handler_fcntl(
246  rtems_libio_t *iop,
247  int cmd
248)
249{
250  test_context *ctx;
251
252  ctx = IMFS_generic_get_context_by_iop(iop);
253  ++ctx->fcntl_count;
254
255  wait();
256  return 0;
257}
258
259static ssize_t handler_readv(
260  rtems_libio_t *iop,
261  const struct iovec *iov,
262  int iovcnt,
263  ssize_t total
264)
265{
266  test_context *ctx;
267
268  ctx = IMFS_generic_get_context_by_iop(iop);
269  ++ctx->readv_count;
270
271  wait();
272  return 0;
273}
274
275static ssize_t handler_writev(
276  rtems_libio_t *iop,
277  const struct iovec *iov,
278  int iovcnt,
279  ssize_t total
280)
281{
282  test_context *ctx;
283
284  ctx = IMFS_generic_get_context_by_iop(iop);
285  ++ctx->writev_count;
286
287  wait();
288  return 0;
289}
290
291static const rtems_filesystem_file_handlers_r node_handlers = {
292  .open_h = handler_open,
293  .close_h = handler_close,
294  .read_h = handler_read,
295  .write_h = handler_write,
296  .ioctl_h = handler_ioctl,
297  .lseek_h = handler_lseek,
298  .fstat_h = handler_fstat,
299  .ftruncate_h = handler_ftruncate,
300  .fsync_h = handler_fsync,
301  .fdatasync_h = handler_fdatasync,
302  .fcntl_h = handler_fcntl,
303  .readv_h = handler_readv,
304  .writev_h = handler_writev
305};
306
307static const IMFS_node_control node_control = {
308  .handlers = &node_handlers,
309  .node_initialize = IMFS_node_initialize_generic,
310  .node_remove = IMFS_node_remove_default,
311  .node_destroy = IMFS_node_destroy_default
312};
313
314static void worker_task(rtems_task_argument arg)
315{
316  test_context *ctx;
317  int rv;
318  char buf[1];
319  ssize_t n;
320  off_t off;
321  struct iovec iov = {
322    .iov_base = &buf[0],
323    .iov_len = sizeof(buf)
324  };
325  struct stat st;
326
327  ctx = (test_context *) arg;
328
329  while (true) {
330    wait();
331
332    switch (ctx->action) {
333      case ACTION_ClOSE:
334        ctx->wait_in_close = true;
335        rv = close(ctx->fd);
336        rtems_test_assert(rv == 0);
337        break;
338      case ACTION_FCNTL:
339        rv = fcntl(ctx->fd, F_GETFD);
340        rtems_test_assert(rv >= 0);
341        break;
342      case ACTION_FDATASYNC:
343        rv = fdatasync(ctx->fd);
344        rtems_test_assert(rv == 0);
345        break;
346      case ACTION_FCHDIR:
347        ctx->wait_in_fstat = true;
348        rv = fchdir(ctx->fd);
349        rtems_test_assert(rv == -1);
350        rtems_test_assert(errno == ENOTDIR);
351        break;
352      case ACTION_FCHMOD:
353        rv = fstat(ctx->fd, &st);
354        rtems_test_assert(rv == 0);
355        ctx->wait_in_fstat = true;
356        rv = fchmod(ctx->fd, st.st_mode);
357        rtems_test_assert(rv == 0);
358        break;
359      case ACTION_FCHOWN:
360        rv = fstat(ctx->fd, &st);
361        rtems_test_assert(rv == 0);
362        ctx->wait_in_fstat = true;
363        rv = fchown(ctx->fd, st.st_uid, st.st_gid);
364        rtems_test_assert(rv == 0);
365        break;
366      case ACTION_FSTAT:
367        ctx->wait_in_fstat = true;
368        rv = fstat(ctx->fd, &st);
369        rtems_test_assert(rv == 0);
370        break;
371      case ACTION_FSYNC:
372        rv = fsync(ctx->fd);
373        rtems_test_assert(rv == 0);
374        break;
375      case ACTION_FTRUNCATE:
376        rv = ftruncate(ctx->fd, 0);
377        rtems_test_assert(rv == 0);
378        break;
379      case ACTION_IOCTL:
380        rv = ioctl(ctx->fd, 0);
381        rtems_test_assert(rv == 0);
382        break;
383      case ACTION_LSEEK:
384        off = lseek(ctx->fd, off, SEEK_SET);
385        rtems_test_assert(off == 0);
386        break;
387      case ACTION_READ:
388        n = read(ctx->fd, buf, sizeof(buf));
389        rtems_test_assert(n == 0);
390        break;
391      case ACTION_READV:
392        n = readv(ctx->fd, &iov, 1);
393        rtems_test_assert(n == 0);
394        break;
395      case ACTION_WRITE:
396        n = write(ctx->fd, buf, sizeof(buf));
397        rtems_test_assert(n == 0);
398        break;
399      case ACTION_WRITEV:
400        n = writev(ctx->fd, &iov, 1);
401        rtems_test_assert(n == 0);
402        break;
403      default:
404        rtems_test_assert(0);
405        break;
406    }
407  }
408}
409
410static void test_fd_free_fifo(const char *path)
411{
412  int a;
413  int b;
414  int rv;
415
416  a = open(path, O_RDWR);
417  rtems_test_assert(a >= 0);
418
419  rv = close(a);
420  rtems_test_assert(rv == 0);
421
422  b = open(path, O_RDWR);
423  rtems_test_assert(b >= 0);
424
425  rv = close(b);
426  rtems_test_assert(rv == 0);
427
428  rtems_test_assert(a != b);
429}
430
431static void test(test_context *ctx)
432{
433  const char *path = "generic";
434  int rv;
435  rtems_status_code sc;
436  test_action ac;
437
438  rv = IMFS_make_generic_node(
439    path,
440    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
441    &node_control,
442    ctx
443  );
444  rtems_test_assert(rv == 0);
445
446  test_fd_free_fifo(path);
447
448  sc = rtems_task_create(
449    rtems_build_name('W', 'O', 'R', 'K'),
450    1,
451    RTEMS_MINIMUM_STACK_SIZE,
452    RTEMS_DEFAULT_MODES,
453    RTEMS_DEFAULT_ATTRIBUTES,
454    &ctx->worker_id
455  );
456  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
457
458  sc = rtems_task_start(
459    ctx->worker_id,
460    worker_task,
461    (rtems_task_argument) ctx
462  );
463  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
464
465  for (ac = ACTION_ClOSE; ac <= ACTION_WRITEV; ++ac) {
466    ctx->action = ac;
467    ctx->fd = open(path, O_RDWR);
468    rtems_test_assert(ctx->fd >= 0);
469
470    wakeup_worker(ctx);
471    rv = close(ctx->fd);
472    rtems_test_assert(rv == -1);
473
474    if (ac == ACTION_ClOSE) {
475      rtems_test_assert(errno == EBADF);
476    } else {
477      rtems_test_assert(errno == EBUSY);
478    }
479
480    wakeup_worker(ctx);
481    rv = close(ctx->fd);
482
483    if (ac == ACTION_ClOSE) {
484      rtems_test_assert(rv == -1);
485      rtems_test_assert(errno == EBADF);
486    } else {
487      rtems_test_assert(rv == 0);
488    }
489  }
490
491  sc = rtems_task_delete(ctx->worker_id);
492  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
493
494  rv = unlink(path);
495  rtems_test_assert(rv == 0);
496
497  rtems_test_assert(ctx->close_count == 17);
498  rtems_test_assert(ctx->fcntl_count == 1);
499  rtems_test_assert(ctx->fdatasync_count == 1);
500  rtems_test_assert(ctx->fstat_count == 42);
501  rtems_test_assert(ctx->fsync_count == 1);
502  rtems_test_assert(ctx->ftruncate_count == 1);
503  rtems_test_assert(ctx->ioctl_count == 1);
504  rtems_test_assert(ctx->lseek_count == 1);
505  rtems_test_assert(ctx->open_count == 17);
506  rtems_test_assert(ctx->read_count == 1);
507  rtems_test_assert(ctx->readv_count == 1);
508  rtems_test_assert(ctx->write_count == 1);
509  rtems_test_assert(ctx->writev_count == 1);
510}
511
512static void Init(rtems_task_argument arg)
513{
514  TEST_BEGIN();
515  test(&test_instance);
516  TEST_END();
517  rtems_test_exit(0);
518}
519
520#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
521#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
522
523#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 5
524
525#define CONFIGURE_MAXIMUM_TASKS 2
526
527#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
528
529#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
530
531#define CONFIGURE_INIT_TASK_PRIORITY 2
532#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
533
534#define CONFIGURE_INIT
535
536#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.