Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | static FILE *tempFileDes (void) { |
2 | int fd; | |
3 | FILE *f; | |
4 | char *template; | |
5 | const char *tmpDir; | |
6 | const char *tag = "/TempFileXXXXXXXXXX"; | |
7 | size_t tmpDirLen, tagLen; | |
8 | mode_t m; | |
9 | ||
10 | tmpDir = getenv ("TMP"); | |
11 | if (NULL == tmpDir) { | |
12 | tmpDir = getenv ("TMPDIR"); | |
13 | if (NULL == tmpDir) | |
14 | tmpDir = "/var/tmp"; | |
15 | } | |
16 | tmpDirLen = strlen(tmpDir); | |
17 | tagLen = strlen(tag); | |
18 | template = malloc_safe (tmpDirLen + tagLen + 1); | |
19 | strncpy (template, tmpDir, tmpDirLen + 1); | |
20 | strncpy (template + tmpDirLen, tag, tagLen + 1); | |
21 | m = umask(077); | |
22 | fd = mkstemp_safe (template); | |
23 | f = fdopen_safe (fd, "w+"); | |
24 | (void)umask(m); | |
25 | unlink_safe (template); | |
26 | free (template); | |
27 | return f; | |
28 | } | |
29 | ||
30 | typedef struct { | |
31 | FILE *f; | |
32 | } *WriteToDiskData; | |
33 | ||
34 | void GC_diskBack_read (void *data, pointer buf, size_t size) { | |
35 | FILE *f; | |
36 | ||
37 | const size_t READ_CHUNK_SIZE = 0x2000000; /* 32M */ | |
38 | ||
39 | f = ((WriteToDiskData)data)->f; | |
40 | fseek_safe (f, 0, SEEK_SET); | |
41 | /* fread (_, 1, size, _) succeeds | |
42 | * with size >= 2^31 | |
43 | * for a 32-bit executable on 64-bit linux. | |
44 | * Nonetheless, match GC_diskBack_write. | |
45 | */ | |
46 | while (size > 0) { | |
47 | size_t s = min (READ_CHUNK_SIZE, size); | |
48 | fread_safe (buf, 1, s, f); | |
49 | buf += s; | |
50 | size -= s; | |
51 | } | |
52 | } | |
53 | ||
54 | void GC_diskBack_close (void *data) { | |
55 | FILE *f; | |
56 | ||
57 | f = ((WriteToDiskData)data)->f; | |
58 | fclose_safe (f); | |
59 | free (data); | |
60 | } | |
61 | ||
62 | void *GC_diskBack_write (pointer buf, size_t size) { | |
63 | FILE *f; | |
64 | WriteToDiskData d; | |
65 | ||
66 | const size_t WRITE_CHUNK_SIZE = 0x2000000; /* 32M */ | |
67 | ||
68 | f = tempFileDes (); | |
69 | /* fwrite (_, 1, size, _) fails | |
70 | * (with no helpful error conditions!) | |
71 | * with size >= 2^31 | |
72 | * on x86-linux. | |
73 | */ | |
74 | while (size > 0) { | |
75 | size_t s = min (WRITE_CHUNK_SIZE, size); | |
76 | fwrite_safe (buf, 1, s, f); | |
77 | buf += s; | |
78 | size -= s; | |
79 | } | |
80 | d = (WriteToDiskData)(malloc_safe (sizeof(*d))); | |
81 | d->f = f; | |
82 | return d; | |
83 | } |