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