1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Linux Test Project, 2001-2022
4 */
5
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <sys/param.h>
13 #include <sys/wait.h>
14 #include <dirent.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17
18 #define TEMPLATE_PREFIX "ltp"
19 #define TEMPLATE_PREFIX_LEN (sizeof(TEMPLATE_PREFIX) - 1)
20 #define TEMPLATE TEMPLATE_PREFIX "XXXXXX"
21 #define MSG "I Love Linux!!!\n"
22 #define MSG_LEN (sizeof(MSG) - 1)
23
24 int write_something(int);
25 void delete_files(void);
26 void abortx(char *fmt, ...);
27
main(int argc,char * argv[])28 int main(int argc, char *argv[])
29 {
30 int filedes[25500];
31 int i, n, first, n_files;
32 int cid, fork_number;
33 int status;
34 char filename[PATH_MAX];
35
36 if (argc != 2) {
37 fprintf(stderr, "Usage: %s <number of files>\n", argv[0]);
38 exit(1);
39 }
40
41 n = sscanf(argv[1], "%d", &n_files);
42 if (n != 1) {
43 fprintf(stderr, "Usage: %s <number of files>\n", argv[0]);
44 exit(1);
45 }
46
47 first = 0;
48 fork_number = 0;
49 for (n = 0; n < n_files; n++) {
50 strcpy(filename, TEMPLATE);
51 filedes[n] = mkstemp(filename);
52 if (filedes[n] == -1) {
53 if (errno != EMFILE)
54 abortx
55 ("open() error: file = \"%s\", errno = %d",
56 filename, errno);
57 else {
58 if ((cid = fork())) {
59 if (cid == -1)
60 abortx("Error forking child");
61 else {
62 waitpid(cid, &status, 0);
63 for (i = first; i < n; i++)
64 if (!write_something
65 (filedes[i]))
66 abortx
67 ("Error writing to files");
68 if (fork_number == 0)
69 delete_files();
70 exit(WEXITSTATUS(status));
71 }
72 } else {
73 fork_number++;
74 for (i = first; i < n; i++)
75 close(filedes[i]);
76 first = n;
77 n--;
78 }
79 }
80 }
81 }
82
83 for (i = first; i < n; i++)
84 if (!write_something(filedes[i]))
85 abortx("Error writing to files");
86 if (fork_number == 0)
87 delete_files();
88 exit(0);
89 }
90
write_something(int fd)91 int write_something(int fd)
92 {
93 int rc;
94 const char msg[] = MSG;
95 int msg_len = strlen(msg);
96
97 rc = write(fd, msg, msg_len);
98 if (rc != msg_len)
99 return (0);
100 if (close(fd))
101 return (0);
102 return (1);
103 }
104
delete_files(void)105 void delete_files(void)
106 {
107 DIR *dirp;
108 struct dirent *entp;
109 struct stat stat_buffer;
110
111 dirp = opendir(".");
112 for (entp = readdir(dirp); entp; entp = readdir(dirp))
113 if (!strncmp(entp->d_name, TEMPLATE_PREFIX, TEMPLATE_PREFIX_LEN)) {
114 if (stat(entp->d_name, &stat_buffer))
115 abortx("stat() failed for \"%s\", errno = %d",
116 entp->d_name, errno);
117
118 if (stat_buffer.st_size != MSG_LEN)
119 abortx("wrong file size for \"%s\": %d",
120 entp->d_name, stat_buffer.st_size);
121
122 if (unlink(entp->d_name))
123 abortx("unlink failed for \"%s\"",
124 entp->d_name);
125 }
126 }
127
abortx(char * fmt,...)128 void abortx(char *fmt, ...)
129 {
130 va_list args;
131
132 va_start(args, fmt);
133 vfprintf(stderr, fmt, args);
134 va_end(args);
135 fprintf(stderr, "\n");
136 exit(1);
137 }
138