• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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