comparison lib/swig/swigwin-2.0.11/CCache/util.c @ 1899:b3009adc0e2f

Adding swig, gitignore, hgignore
author Nomad
date Mon, 21 Oct 2013 10:42:27 +0200
parents
children
comparison
equal deleted inserted replaced
1867:eb580660bbbb 1899:b3009adc0e2f
1 /*
2 Copyright (C) Andrew Tridgell 2002
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include "ccache.h"
20
21 static FILE *logfile;
22
23 /* log a message to the CCACHE_LOGFILE location */
24 void cc_log(const char *format, ...)
25 {
26 va_list ap;
27 extern char *cache_logfile;
28
29 if (!cache_logfile) return;
30
31 if (!logfile) logfile = fopen(cache_logfile, "a");
32 if (!logfile) return;
33
34 va_start(ap, format);
35 vfprintf(logfile, format, ap);
36 va_end(ap);
37 fflush(logfile);
38 }
39
40 /* something went badly wrong! */
41 void fatal(const char *msg)
42 {
43 cc_log("FATAL: %s\n", msg);
44 exit(1);
45 }
46
47 int safe_rename(const char* oldpath, const char* newpath)
48 {
49 /* safe_rename is for creating entries in the cache.
50
51 Works like rename(), but it never overwrites an existing
52 cache entry. This avoids corruption on NFS. */
53 #ifndef _WIN32
54 int status = link(oldpath, newpath);
55 if( status == 0 || errno == EEXIST )
56 #else
57 int status = CreateHardLinkA(newpath, oldpath, NULL) ? 0 : -1;
58 if( status == 0 || GetLastError() == ERROR_ALREADY_EXISTS )
59 #endif
60 {
61 return unlink( oldpath );
62 }
63 else
64 {
65 return -1;
66 }
67 }
68
69 #ifndef ENABLE_ZLIB
70 /* copy all data from one file descriptor to another */
71 void copy_fd(int fd_in, int fd_out)
72 {
73 char buf[10240];
74 int n;
75
76 while ((n = read(fd_in, buf, sizeof(buf))) > 0) {
77 if (write(fd_out, buf, n) != n) {
78 fatal("Failed to copy fd");
79 }
80 }
81 }
82
83 #ifndef HAVE_MKSTEMP
84 /* cheap and nasty mkstemp replacement */
85 int mkstemp(char *template)
86 {
87 mktemp(template);
88 return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
89 }
90 #endif
91
92 /* move a file using rename */
93 int move_file(const char *src, const char *dest) {
94 return safe_rename(src, dest);
95 }
96
97 /* copy a file - used when hard links don't work
98 the copy is done via a temporary file and atomic rename
99 */
100 static int copy_file(const char *src, const char *dest)
101 {
102 int fd1, fd2;
103 char buf[10240];
104 int n;
105 char *tmp_name;
106 mode_t mask;
107
108 x_asprintf(&tmp_name, "%s.XXXXXX", dest);
109
110 fd1 = open(src, O_RDONLY|O_BINARY);
111 if (fd1 == -1) {
112 free(tmp_name);
113 return -1;
114 }
115
116 fd2 = mkstemp(tmp_name);
117 if (fd2 == -1) {
118 close(fd1);
119 free(tmp_name);
120 return -1;
121 }
122
123 while ((n = read(fd1, buf, sizeof(buf))) > 0) {
124 if (write(fd2, buf, n) != n) {
125 close(fd2);
126 close(fd1);
127 unlink(tmp_name);
128 free(tmp_name);
129 return -1;
130 }
131 }
132
133 close(fd1);
134
135 /* get perms right on the tmp file */
136 #ifndef _WIN32
137 mask = umask(0);
138 fchmod(fd2, 0666 & ~mask);
139 umask(mask);
140 #else
141 (void)mask;
142 #endif
143
144 /* the close can fail on NFS if out of space */
145 if (close(fd2) == -1) {
146 unlink(tmp_name);
147 free(tmp_name);
148 return -1;
149 }
150
151 unlink(dest);
152
153 if (rename(tmp_name, dest) == -1) {
154 unlink(tmp_name);
155 free(tmp_name);
156 return -1;
157 }
158
159 free(tmp_name);
160
161 return 0;
162 }
163
164 /* copy a file to the cache */
165 static int copy_file_to_cache(const char *src, const char *dest) {
166 return copy_file(src, dest);
167 }
168
169 /* copy a file from the cache */
170 static int copy_file_from_cache(const char *src, const char *dest) {
171 return copy_file(src, dest);
172 }
173
174 #else /* ENABLE_ZLIB */
175
176 /* copy all data from one file descriptor to another
177 possibly decompressing it
178 */
179 void copy_fd(int fd_in, int fd_out) {
180 char buf[10240];
181 int n;
182 gzFile gz_in;
183
184 gz_in = gzdopen(dup(fd_in), "rb");
185
186 if (!gz_in) {
187 fatal("Failed to copy fd");
188 }
189
190 while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
191 if (write(fd_out, buf, n) != n) {
192 fatal("Failed to copy fd");
193 }
194 }
195 }
196
197 static int _copy_file(const char *src, const char *dest, int mode) {
198 int fd_in, fd_out;
199 gzFile gz_in, gz_out = NULL;
200 char buf[10240];
201 int n, ret;
202 char *tmp_name;
203 mode_t mask;
204 struct stat st;
205
206 x_asprintf(&tmp_name, "%s.XXXXXX", dest);
207
208 if (getenv("CCACHE_NOCOMPRESS")) {
209 mode = COPY_UNCOMPRESSED;
210 }
211
212 /* open source file */
213 fd_in = open(src, O_RDONLY);
214 if (fd_in == -1) {
215 return -1;
216 }
217
218 gz_in = gzdopen(fd_in, "rb");
219 if (!gz_in) {
220 close(fd_in);
221 return -1;
222 }
223
224 /* open destination file */
225 fd_out = mkstemp(tmp_name);
226 if (fd_out == -1) {
227 gzclose(gz_in);
228 free(tmp_name);
229 return -1;
230 }
231
232 if (mode == COPY_TO_CACHE) {
233 /* The gzip file format occupies at least 20 bytes. So
234 it will always occupy an entire filesystem block,
235 even for empty files.
236 Since most stderr files will be empty, we turn off
237 compression in this case to save space.
238 */
239 if (fstat(fd_in, &st) != 0) {
240 gzclose(gz_in);
241 close(fd_out);
242 free(tmp_name);
243 return -1;
244 }
245 if (file_size(&st) == 0) {
246 mode = COPY_UNCOMPRESSED;
247 }
248 }
249
250 if (mode == COPY_TO_CACHE) {
251 gz_out = gzdopen(dup(fd_out), "wb");
252 if (!gz_out) {
253 gzclose(gz_in);
254 close(fd_out);
255 free(tmp_name);
256 return -1;
257 }
258 }
259
260 while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
261 if (mode == COPY_TO_CACHE) {
262 ret = gzwrite(gz_out, buf, n);
263 } else {
264 ret = write(fd_out, buf, n);
265 }
266 if (ret != n) {
267 gzclose(gz_in);
268 if (gz_out) {
269 gzclose(gz_out);
270 }
271 close(fd_out);
272 unlink(tmp_name);
273 free(tmp_name);
274 return -1;
275 }
276 }
277
278 gzclose(gz_in);
279 if (gz_out) {
280 gzclose(gz_out);
281 }
282
283 /* get perms right on the tmp file */
284 mask = umask(0);
285 fchmod(fd_out, 0666 & ~mask);
286 umask(mask);
287
288 /* the close can fail on NFS if out of space */
289 if (close(fd_out) == -1) {
290 unlink(tmp_name);
291 free(tmp_name);
292 return -1;
293 }
294
295 unlink(dest);
296
297 if (rename(tmp_name, dest) == -1) {
298 unlink(tmp_name);
299 free(tmp_name);
300 return -1;
301 }
302
303 free(tmp_name);
304
305 return 0;
306 }
307
308 /* move a file to the cache, compressing it */
309 int move_file(const char *src, const char *dest) {
310 int ret;
311
312 ret = _copy_file(src, dest, COPY_TO_CACHE);
313 if (ret != -1) unlink(src);
314 return ret;
315 }
316
317 /* copy a file to the cache, compressing it */
318 static int copy_file_to_cache(const char *src, const char *dest) {
319 return _copy_file(src, dest, COPY_TO_CACHE);
320 }
321
322 /* copy a file from the cache, decompressing it */
323 static int copy_file_from_cache(const char *src, const char *dest) {
324 return _copy_file(src, dest, COPY_FROM_CACHE);
325 }
326 #endif /* ENABLE_ZLIB */
327
328 /* test if a file is zlib compressed */
329 int test_if_compressed(const char *filename) {
330 FILE *f;
331
332 f = fopen(filename, "rb");
333 if (!f) {
334 return 0;
335 }
336
337 /* test if file starts with 1F8B, which is zlib's
338 * magic number */
339 if ((fgetc(f) != 0x1f) || (fgetc(f) != 0x8b)) {
340 fclose(f);
341 return 0;
342 }
343
344 fclose(f);
345 return 1;
346 }
347
348 /* copy file to the cache with error checking taking into account compression and hard linking if desired */
349 int commit_to_cache(const char *src, const char *dest, int hardlink)
350 {
351 int ret = -1;
352 struct stat st;
353 if (stat(src, &st) == 0) {
354 unlink(dest);
355 if (hardlink) {
356 #ifdef _WIN32
357 ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
358 #else
359 ret = link(src, dest);
360 #endif
361 }
362 if (ret == -1) {
363 ret = copy_file_to_cache(src, dest);
364 if (ret == -1) {
365 cc_log("failed to commit %s -> %s (%s)\n", src, dest, strerror(errno));
366 stats_update(STATS_ERROR);
367 }
368 }
369 } else {
370 cc_log("failed to put %s in the cache (%s)\n", src, strerror(errno));
371 stats_update(STATS_ERROR);
372 }
373 return ret;
374 }
375
376 /* copy file out of the cache with error checking taking into account compression and hard linking if desired */
377 int retrieve_from_cache(const char *src, const char *dest, int hardlink)
378 {
379 int ret = 0;
380
381 x_utimes(src);
382
383 if (strcmp(dest, "/dev/null") == 0) {
384 ret = 0;
385 } else {
386 unlink(dest);
387 /* only make a hardlink if the cache file is uncompressed */
388 if (hardlink && test_if_compressed(src) == 0) {
389 #ifdef _WIN32
390 ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
391 #else
392 ret = link(src, dest);
393 #endif
394 } else {
395 ret = copy_file_from_cache(src, dest);
396 }
397 }
398
399 /* the cached file might have been deleted by some external process */
400 if (ret == -1 && errno == ENOENT) {
401 cc_log("hashfile missing for %s\n", dest);
402 stats_update(STATS_MISSING);
403 return -1;
404 }
405
406 if (ret == -1) {
407 ret = copy_file_from_cache(src, dest);
408 if (ret == -1) {
409 cc_log("failed to retrieve %s -> %s (%s)\n", src, dest, strerror(errno));
410 stats_update(STATS_ERROR);
411 return -1;
412 }
413 }
414 return ret;
415 }
416
417 /* make sure a directory exists */
418 int create_dir(const char *dir)
419 {
420 struct stat st;
421 if (stat(dir, &st) == 0) {
422 if (S_ISDIR(st.st_mode)) {
423 return 0;
424 }
425 errno = ENOTDIR;
426 return 1;
427 }
428 #ifdef _WIN32
429 if (mkdir(dir) != 0 && errno != EEXIST) {
430 return 1;
431 }
432 #else
433 if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
434 return 1;
435 }
436 #endif
437 return 0;
438 }
439
440 char const CACHEDIR_TAG[] =
441 "Signature: 8a477f597d28d172789f06886806bc55\n"
442 "# This file is a cache directory tag created by ccache.\n"
443 "# For information about cache directory tags, see:\n"
444 "# http://www.brynosaurus.com/cachedir/\n";
445
446 int create_cachedirtag(const char *dir)
447 {
448 char *filename;
449 struct stat st;
450 FILE *f;
451 x_asprintf(&filename, "%s/CACHEDIR.TAG", dir);
452 if (stat(filename, &st) == 0) {
453 if (S_ISREG(st.st_mode)) {
454 goto success;
455 }
456 errno = EEXIST;
457 goto error;
458 }
459 f = fopen(filename, "w");
460 if (!f) goto error;
461 if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
462 goto error;
463 }
464 if (fclose(f)) goto error;
465 success:
466 free(filename);
467 return 0;
468 error:
469 free(filename);
470 return 1;
471 }
472
473 /*
474 this is like asprintf() but dies if the malloc fails
475 note that we use vsnprintf in a rather poor way to make this more portable
476 */
477 void x_asprintf(char **ptr, const char *format, ...)
478 {
479 va_list ap;
480
481 *ptr = NULL;
482 va_start(ap, format);
483 if (vasprintf(ptr, format, ap) == -1) {
484 fatal("out of memory in x_asprintf");
485 }
486 va_end(ap);
487
488 if (!ptr) fatal("out of memory in x_asprintf");
489 }
490
491 /*
492 this is like strdup() but dies if the malloc fails
493 */
494 char *x_strdup(const char *s)
495 {
496 char *ret;
497 ret = strdup(s);
498 if (!ret) {
499 fatal("out of memory in strdup\n");
500 }
501 return ret;
502 }
503
504 /*
505 this is like malloc() but dies if the malloc fails
506 */
507 void *x_malloc(size_t size)
508 {
509 void *ret;
510 ret = malloc(size);
511 if (!ret) {
512 fatal("out of memory in malloc\n");
513 }
514 return ret;
515 }
516
517 /*
518 this is like realloc() but dies if the malloc fails
519 */
520 void *x_realloc(void *ptr, size_t size)
521 {
522 void *p2;
523 #if 1
524 /* Avoid invalid read in memcpy below */
525 p2 = realloc(ptr, size);
526 if (!p2) {
527 fatal("out of memory in x_realloc");
528 }
529 #else
530 if (!ptr) return x_malloc(size);
531 p2 = malloc(size);
532 if (!p2) {
533 fatal("out of memory in x_realloc");
534 }
535 if (ptr) {
536 /* Note invalid read as the memcpy reads beyond the memory allocated by ptr */
537 memcpy(p2, ptr, size);
538 free(ptr);
539 }
540 #endif
541 return p2;
542 }
543
544
545 /*
546 revsusive directory traversal - used for cleanup
547 fn() is called on all files/dirs in the tree
548 */
549 void traverse(const char *dir, void (*fn)(const char *, struct stat *))
550 {
551 DIR *d;
552 struct dirent *de;
553
554 d = opendir(dir);
555 if (!d) return;
556
557 while ((de = readdir(d))) {
558 char *fname;
559 struct stat st;
560
561 if (strcmp(de->d_name,".") == 0) continue;
562 if (strcmp(de->d_name,"..") == 0) continue;
563
564 if (strlen(de->d_name) == 0) continue;
565
566 x_asprintf(&fname, "%s/%s", dir, de->d_name);
567 #ifdef _WIN32
568 if (stat(fname, &st))
569 #else
570 if (lstat(fname, &st))
571 #endif
572 {
573 if (errno != ENOENT) {
574 perror(fname);
575 }
576 free(fname);
577 continue;
578 }
579
580 if (S_ISDIR(st.st_mode)) {
581 traverse(fname, fn);
582 }
583
584 fn(fname, &st);
585 free(fname);
586 }
587
588 closedir(d);
589 }
590
591
592 /* return the base name of a file - caller frees */
593 char *str_basename(const char *s)
594 {
595 char *p = strrchr(s, '/');
596 if (p) {
597 s = (p+1);
598 }
599
600 #ifdef _WIN32
601 p = strrchr(s, '\\');
602
603 if (p) {
604 s = (p+1);
605 }
606 #endif
607
608 return x_strdup(s);
609 }
610
611 /* return the dir name of a file - caller frees */
612 char *dirname(char *s)
613 {
614 char *p;
615 s = x_strdup(s);
616 p = strrchr(s, '/');
617 #ifdef _WIN32
618 p = strrchr(s, '\\');
619 #endif
620 if (p) {
621 *p = 0;
622 }
623 return s;
624 }
625
626 /*
627 http://www.ecst.csuchico.edu/~beej/guide/ipc/flock.html
628 http://cvs.php.net/viewvc.cgi/php-src/win32/flock.c?revision=1.2&view=markup
629 Should return 0 for success, >0 otherwise
630 */
631 int lock_fd(int fd)
632 {
633 #ifdef _WIN32
634 # if 1
635 return _locking(fd, _LK_NBLCK, 1);
636 # else
637 HANDLE fl = (HANDLE)_get_osfhandle(fd);
638 OVERLAPPED o;
639 memset(&o, 0, sizeof(o));
640 return (LockFileEx(fl, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &o))
641 ? 0 : GetLastError();
642 # endif
643 #else
644 struct flock fl;
645 int ret;
646
647 fl.l_type = F_WRLCK;
648 fl.l_whence = SEEK_SET;
649 fl.l_start = 0;
650 fl.l_len = 1;
651 fl.l_pid = 0;
652
653 /* not sure why we would be getting a signal here,
654 but one user claimed it is possible */
655 do {
656 ret = fcntl(fd, F_SETLKW, &fl);
657 } while (ret == -1 && errno == EINTR);
658 return ret;
659 #endif
660 }
661
662 /* return size on disk of a file */
663 size_t file_size(struct stat *st)
664 {
665 #ifdef _WIN32
666 return (st->st_size + 1023) & ~1023;
667 #else
668 size_t size = st->st_blocks * 512;
669 if ((size_t)st->st_size > size) {
670 /* probably a broken stat() call ... */
671 size = (st->st_size + 1023) & ~1023;
672 }
673 return size;
674 #endif
675 }
676
677
678 /* a safe open/create for read-write */
679 int safe_open(const char *fname)
680 {
681 int fd = open(fname, O_RDWR|O_BINARY);
682 if (fd == -1 && errno == ENOENT) {
683 fd = open(fname, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0666);
684 if (fd == -1 && errno == EEXIST) {
685 fd = open(fname, O_RDWR|O_BINARY);
686 }
687 }
688 return fd;
689 }
690
691 /* display a kilobyte unsigned value in M, k or G */
692 void display_size(unsigned v)
693 {
694 if (v > 1024*1024) {
695 printf("%8.1f Gbytes", v/((double)(1024*1024)));
696 } else if (v > 1024) {
697 printf("%8.1f Mbytes", v/((double)(1024)));
698 } else {
699 printf("%8u Kbytes", v);
700 }
701 }
702
703 /* return a value in multiples of 1024 give a string that can end
704 in K, M or G
705 */
706 size_t value_units(const char *s)
707 {
708 char m;
709 double v = atof(s);
710 m = s[strlen(s)-1];
711 switch (m) {
712 case 'G':
713 case 'g':
714 default:
715 v *= 1024*1024;
716 break;
717 case 'M':
718 case 'm':
719 v *= 1024;
720 break;
721 case 'K':
722 case 'k':
723 v *= 1;
724 break;
725 }
726 return (size_t)v;
727 }
728
729
730 /*
731 a sane realpath() function, trying to cope with stupid path limits and
732 a broken API
733 */
734 char *x_realpath(const char *path)
735 {
736 #ifdef _WIN32
737 char namebuf[MAX_PATH];
738 DWORD ret;
739
740 ret = GetFullPathNameA(path, sizeof(namebuf), namebuf, NULL);
741 if (ret == 0 || ret >= sizeof(namebuf)) {
742 return NULL;
743 }
744
745 return x_strdup(namebuf);
746 #else
747 int maxlen;
748 char *ret, *p;
749 #ifdef PATH_MAX
750 maxlen = PATH_MAX;
751 #elif defined(MAXPATHLEN)
752 maxlen = MAXPATHLEN;
753 #elif defined(_PC_PATH_MAX)
754 maxlen = pathconf(path, _PC_PATH_MAX);
755 #endif
756 if (maxlen < 4096) maxlen = 4096;
757
758 ret = x_malloc(maxlen);
759
760 #if HAVE_REALPATH
761 p = realpath(path, ret);
762 #else
763 /* yes, there are such systems. This replacement relies on
764 the fact that when we call x_realpath we only care about symlinks */
765 {
766 int len = readlink(path, ret, maxlen-1);
767 if (len == -1) {
768 free(ret);
769 return NULL;
770 }
771 ret[len] = 0;
772 p = ret;
773 }
774 #endif
775 if (p) {
776 p = x_strdup(p);
777 free(ret);
778 return p;
779 }
780 free(ret);
781 return NULL;
782 #endif
783 }
784
785 /* a getcwd that will returns an allocated buffer */
786 char *gnu_getcwd(void)
787 {
788 unsigned size = 128;
789
790 while (1) {
791 char *buffer = (char *)x_malloc(size);
792 if (getcwd(buffer, size) == buffer) {
793 return buffer;
794 }
795 free(buffer);
796 if (errno != ERANGE) {
797 return 0;
798 }
799 size *= 2;
800 }
801 }
802
803 /* create an empty file */
804 int create_empty_file(const char *fname)
805 {
806 int fd;
807
808 fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
809 if (fd == -1) {
810 return -1;
811 }
812 close(fd);
813 return 0;
814 }
815
816 /*
817 return current users home directory or die
818 */
819 const char *get_home_directory(void)
820 {
821 #ifdef _WIN32
822 static char home_path[MAX_PATH] = {0};
823 HRESULT ret;
824
825 /* we already have the path */
826 if (home_path[0] != 0) {
827 return home_path;
828 }
829
830 /* get the path to "Application Data" folder */
831 ret = SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, home_path);
832 if (SUCCEEDED(ret)) {
833 return home_path;
834 }
835
836 fprintf(stderr, "ccache: Unable to determine home directory\n");
837 return NULL;
838 #else
839 const char *p = getenv("HOME");
840 if (p) {
841 return p;
842 }
843 #ifdef HAVE_GETPWUID
844 {
845 struct passwd *pwd = getpwuid(getuid());
846 if (pwd) {
847 return pwd->pw_dir;
848 }
849 }
850 #endif
851 fatal("Unable to determine home directory");
852 return NULL;
853 #endif
854 }
855
856 int x_utimes(const char *filename)
857 {
858 #ifdef HAVE_UTIMES
859 return utimes(filename, NULL);
860 #else
861 return utime(filename, NULL);
862 #endif
863 }
864
865 #ifdef _WIN32
866 /* perror for Win32 API calls, using GetLastError() instead of errno */
867 void perror_win32(LPTSTR pszFunction)
868 {
869 LPTSTR pszMessage;
870 DWORD dwLastError = GetLastError();
871
872 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
873 FORMAT_MESSAGE_FROM_SYSTEM |
874 FORMAT_MESSAGE_IGNORE_INSERTS,
875 NULL,
876 dwLastError,
877 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
878 (LPTSTR)&pszMessage,
879 0, NULL );
880
881 fprintf(stderr, "%s: %s\n", pszFunction, pszMessage);
882 LocalFree(pszMessage);
883 }
884 #endif