1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) International Business Machines Corp., 2001
4 * 07/2001 Ported by Wayne Boyer
5 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <[email protected]>
6 */
7
8 /*\
9 * [Description]
10 *
11 * This test verifies inheritance of file descriptors from parent to child
12 * process. We open a file from parent, then we check if file offset changes
13 * accordingly with file descriptor usage.
14 *
15 * [Algorithm]
16 *
17 * Test steps are the following:
18 * - create a file made in three parts -> | aa..a | bb..b | cc..c |
19 * - from parent, open the file
20 * - from child, move file offset after the first part
21 * - from parent, read second part and check if it's | bb..b |
22 * - from child, read third part and check if it's | cc..c |
23 *
24 * Test passes if we were able to read the correct file parts from parent and
25 * child.
26 */
27
28 #include <stdlib.h>
29 #include "tst_test.h"
30
31 #define FILENAME "file.txt"
32 #define DATASIZE 1024
33
34 static int fd = -1;
35
run(void)36 static void run(void)
37 {
38 int status;
39 char buff[DATASIZE];
40 char data[DATASIZE];
41
42 fd = SAFE_OPEN(FILENAME, 0);
43
44 if (!SAFE_FORK()) {
45 SAFE_LSEEK(fd, DATASIZE, SEEK_SET);
46 exit(0);
47 }
48
49 SAFE_WAIT(&status);
50
51 memset(buff, 'b', DATASIZE);
52 SAFE_READ(1, fd, data, DATASIZE);
53
54 TST_EXP_EXPR(strncmp(buff, data, DATASIZE) == 0,
55 "read first part of data from parent process");
56
57 if (!SAFE_FORK()) {
58 memset(buff, 'c', DATASIZE);
59 SAFE_READ(1, fd, data, DATASIZE);
60
61 TST_EXP_EXPR(strncmp(buff, data, DATASIZE) == 0,
62 "read second part of data from child process");
63
64 exit(0);
65 }
66
67 SAFE_CLOSE(fd);
68 }
69
setup(void)70 static void setup(void)
71 {
72 char buff[DATASIZE];
73
74 fd = SAFE_CREAT(FILENAME, 0600);
75
76 memset(buff, 'a', DATASIZE);
77 SAFE_WRITE(SAFE_WRITE_ALL, fd, buff, DATASIZE);
78
79 memset(buff, 'b', DATASIZE);
80 SAFE_WRITE(SAFE_WRITE_ALL, fd, buff, DATASIZE);
81
82 memset(buff, 'c', DATASIZE);
83 SAFE_WRITE(SAFE_WRITE_ALL, fd, buff, DATASIZE);
84
85 SAFE_CLOSE(fd);
86 }
87
cleanup(void)88 static void cleanup(void)
89 {
90 if (fd >= 0)
91 SAFE_CLOSE(fd);
92 }
93
94 static struct tst_test test = {
95 .forks_child = 1,
96 .needs_tmpdir = 1,
97 .test_all = run,
98 .setup = setup,
99 .cleanup = cleanup,
100 };
101