Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
sanitize the use of logs in unit testing of parmap to fix supernovae
[simgrid.git] / tools / tesh2 / w32 / src / Cat.c
1
2
3 /* must be defined before */
4 #ifdef _MSC_VER
5 #define _CRT_SECURE_NO_DEPRECATE
6 #endif
7
8 #include <windows.h>
9
10 #include <sys/stat.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <locale.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <io.h>
17
18 #ifdef _MSC_VER
19 #define _CRT_SECURE_NO_DEPRECATE
20 #define strdup  _strdup
21 #define fileno  _fileno
22 #define creat   _creat
23 #define open    _open
24 #define read    _read
25 #define write   _write
26 #endif
27
28 #ifdef max
29 #undef max
30 #define max(h,i) ((h) > (i) ? (h) : (i))
31 #endif
32
33 #ifndef S_ISREG
34 #define S_ISREG(__mode) (((__mode) & S_IFMT) == S_IFREG)
35 #endif
36
37 #ifndef STDIN_FILENO
38 #define STDIN_FILENO    0
39 #endif
40
41 #ifndef STDOUT_FILENO
42 #define STDOUT_FILENO   1
43 #endif
44
45
46 static
47 int exit_code = EXIT_SUCCESS;
48
49 static char *rfname;
50
51 static char *wfname = NULL;
52
53 static
54 int wfd;
55
56 #ifndef _MSC_VER
57 static size_t
58 #else
59 static int
60 #endif
61  bsize;
62
63 static char *buf = NULL;
64
65 static int
66  fnumber = 0;
67
68 int cat_files(char **fnames);
69
70 int cat(int);
71
72 char **fnames = NULL;
73
74 void exit0(int errcode)
75 {
76   if (fnames) {
77     int i;
78
79     for (i = 0; i < fnumber; i++)
80       free(fnames[i]);
81
82     free(fnames);
83   }
84
85   if (buf)
86     free(buf);
87
88   if (wfname)
89     free(wfname);
90
91
92   exit(errcode);
93 }
94
95 int main(int argc, char *argv[])
96 {
97   int i, j;
98   int success = 1;
99   int redirect = 0;
100   int exists = 0;
101
102   struct stat stat_buf = { 0 };
103
104   setlocale(LC_ALL, "");
105
106   bsize = BUFSIZ;
107
108   if (!(buf = (char *) malloc(bsize))) {
109     fprintf(stderr, "[ERROR/cat] not enough memory\n");
110     exit0(EXIT_FAILURE);
111   }
112
113   if (argc > 1) {
114     if (!(fnames = (char **) calloc(argc, sizeof(char *)))) {
115       fprintf(stderr, "[ERROR/cat]  not enough memory\n");
116       exit0(EXIT_FAILURE);
117     }
118
119     for (i = 1, j = 0; i < argc; i++) {
120       if (!strcmp(argv[i], ">")) {
121         redirect = 1;
122         break;
123       } else if (!strcmp(argv[i], ">>")) {
124         redirect = 1;
125         exists = 1;
126         break;
127       } else {
128         if (stat(argv[i], &stat_buf)) {
129           fprintf(stderr,
130                   "[ERROR/cat (1)] could not get information about %s\n",
131                   argv[i]);
132           success = 0;
133           break;
134         } else {
135           if (S_ISREG(stat_buf.st_mode)) {
136             fnames[j++] = strdup(argv[i]);
137             fnumber++;
138           } else {
139             fprintf(stderr, "[ERROR/cat] %s is not a file\n", argv[i]);
140             success = 0;
141             break;
142           }
143         }
144       }
145     }
146
147     if (!success)
148       exit0(EXIT_FAILURE);
149   }
150
151   if (redirect) {
152     if (i != argc - 2) {
153       if (exists)
154         fprintf(stderr,
155                 "[ERROR/cat] syntax error near `>>' (i : %d - argc : %d\n",
156                 i, argc);
157       else
158         fprintf(stderr,
159                 "[ERROR/cat] syntax error near `>' (i : %d - argc : %d\n",
160                 i, argc);
161
162       exit0(EXIT_FAILURE);
163     } else {
164       wfname = strdup(argv[i + 1]);
165
166       if (!exists) {
167         if ((wfd = creat(wfname, _S_IREAD | _S_IWRITE)) < 0) {
168           fprintf(stderr, "[ERROR/cat] could not create %s file\n",
169                   wfname);
170
171           exit0(EXIT_FAILURE);
172         }
173       } else {
174         if ((wfd = open(wfname, O_WRONLY | O_APPEND, 0)) < 0) {
175           fprintf(stderr, "[ERROR/cat] could not open %s file\n", wfname);
176
177           exit0(EXIT_FAILURE);
178         }
179       }
180     }
181   } else {
182     wfd = STDOUT_FILENO;
183
184     if (fstat(wfd, &stat_buf)) {
185       fprintf(stderr,
186               "[ERROR/cat (3)] could not get information about stdout\n");
187       exit0(EXIT_FAILURE);
188     }
189   }
190
191   exit_code = cat_files(fnames);
192
193   if (wfd == STDOUT_FILENO) {
194     if (fclose(stdout)) {
195       fprintf(stderr, "[ERROR/cat] could not close stdout\n");
196       exit_code = EXIT_FAILURE;
197     }
198   } else {
199     if (close(wfd)) {
200       fprintf(stderr, "[ERROR/cat] could not close %s\n", wfname);
201       exit_code = EXIT_FAILURE;
202     }
203   }
204
205   exit0(exit_code);
206 }
207
208 int cat_files(char **fnames)
209 {
210   int rfd, i;
211   int failure = 0;
212
213   rfd = STDIN_FILENO;
214
215   rfname = "stdin";
216
217   if (fnumber) {
218
219     for (i = 0; i < fnumber && !failure; i++) {
220       if (!strcmp(fnames[i], "-"))
221         rfd = fileno(stdin);
222       else if ((rfd = open(fnames[i], O_RDONLY, 0)) < 0) {
223         fprintf(stderr, "[WARN/cat] could not open %s file", fnames[i]);
224         exit_code = EXIT_FAILURE;
225         continue;
226       }
227
228       rfname = fnames[i];
229
230       failure = cat(rfd);
231
232       close(rfd);
233
234     }
235   } else
236     failure = cat(rfd);
237
238   return failure ? 1 : 0;
239 }
240
241 int cat(int rfd)
242 {
243
244 #ifndef _MSC_VER
245   size_t bytes_readed_nb;
246 #else
247   int bytes_readed_nb;
248 #endif
249   int bytes_written_nb, pos;
250
251   while ((bytes_readed_nb = read(rfd, buf, bsize)) != -1
252          && bytes_readed_nb != 0) {
253     for (pos = 0; bytes_readed_nb;
254          bytes_readed_nb -= bytes_written_nb, pos += bytes_written_nb) {
255       if ((bytes_written_nb = write(wfd, buf + pos, bytes_readed_nb)) == 0
256           || bytes_written_nb == -1) {
257         fprintf(stderr, "[ERROR/cat] could not write to %s\n",
258                 wfd == fileno(stdout) ? "stdout" : wfname);
259         return 1;
260       }
261     }
262   }
263
264   if (bytes_readed_nb < 0) {
265     fprintf(stderr, "[WARN/cat] could not read %s file", rfname);
266     return 1;
267   }
268
269   return 0;
270 }