File: diskBack.unix.c

package info (click to toggle)
mlton 20100608-5
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 36,624 kB
  • sloc: ansic: 18,441; lisp: 2,879; makefile: 1,572; sh: 1,326; pascal: 256; asm: 97
file content (83 lines) | stat: -rw-r--r-- 1,822 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
static FILE *tempFileDes (void) {
  int fd;
  FILE *f;
  char *template;
  const char *tmpDir;
  const char *tag = "/TempFileXXXXXXXXXX";
  size_t tmpDirLen, tagLen;
  mode_t m;

  tmpDir = getenv ("TMP");
  if (NULL == tmpDir) {
    tmpDir = getenv ("TMPDIR");
    if (NULL == tmpDir)
      tmpDir = "/var/tmp";
  }
  tmpDirLen = strlen(tmpDir);
  tagLen = strlen(tag);
  template = malloc_safe (tmpDirLen + tagLen + 1);
  strncpy (template, tmpDir, tmpDirLen + 1);
  strncpy (template + tmpDirLen, tag, tagLen + 1);
  m = umask(077);
  fd = mkstemp_safe (template);
  f = fdopen_safe (fd, "w+");
  (void)umask(m);
  unlink_safe (template);
  free (template);
  return f;
}

typedef struct {
  FILE *f;
} *WriteToDiskData;

void GC_diskBack_read (void *data, pointer buf, size_t size) {
  FILE *f;

  const size_t READ_CHUNK_SIZE = 0x2000000; /* 32M */

  f = ((WriteToDiskData)data)->f;
  fseek_safe (f, 0, SEEK_SET);
  /* fread (_, 1, size, _) succeeds
   * with size >= 2^31
   * for a 32-bit executable on 64-bit linux.
   * Nonetheless, match GC_diskBack_write.
   */
  while (size > 0) {
    size_t s = min (READ_CHUNK_SIZE, size);
    fread_safe (buf, 1, s, f);
    buf += s;
    size -= s;
  }
}

void GC_diskBack_close (void *data) {
  FILE *f;

  f = ((WriteToDiskData)data)->f;
  fclose_safe (f);
  free (data);
}

void *GC_diskBack_write (pointer buf, size_t size) {
  FILE *f;
  WriteToDiskData d;

  const size_t WRITE_CHUNK_SIZE = 0x2000000; /* 32M */

  f = tempFileDes ();
  /* fwrite (_, 1, size, _) fails
   * (with no helpful error conditions!)
   * with size >= 2^31
   * on x86-linux.
   */
  while (size > 0) {
    size_t s = min (WRITE_CHUNK_SIZE, size);
    fwrite_safe (buf, 1, s, f);
    buf += s;
    size -= s;
  }
  d = (WriteToDiskData)(malloc_safe (sizeof(*d)));
  d->f = f;
  return d;
}