blob: 656d3164cfcff6f366e7e03d5a2fc789ad8b955a [file] [log] [blame]
Misha Brukman2e1fbdd2003-09-29 22:37:00 +00001/*===- StorageProxy.c - OS implementation of the caching interface --------===*\
2 * *
3 * This file implements the interface that we will expect operating *
4 * systems to implement if they wish to support offline cachine. *
5 * *
6\*===----------------------------------------------------------------------===*/
7
8#include "OSInterface.h"
9#include "SysUtils.h"
10#include "Config/fcntl.h"
Misha Brukman2e1fbdd2003-09-29 22:37:00 +000011#include "Config/unistd.h"
12#include "Config/sys/types.h"
13#include "Config/sys/stat.h"
Chris Lattner335eb9d2004-01-10 19:12:09 +000014#include <stdlib.h>
Misha Brukman2e1fbdd2003-09-29 22:37:00 +000015#include <stdio.h>
16#include <string.h>
17
18static const char CacheRoot[] = "/tmp/LLVMCache";
19static const char ExeSuffix[] = ".exe";
20
21char* computeCachedFile(const char *key) {
22 /* CacheRoot + "/" + std::string(key) + ExeSuffix; */
23 char *cacheFile = (char*) malloc(strlen(CacheRoot) + 1 + strlen(key) +
24 strlen(ExeSuffix) + 1);
25 char *pCacheFile = cacheFile;
26 if (!cacheFile) return 0;
27 memcpy(cacheFile, CacheRoot, strlen(CacheRoot));
28 pCacheFile += strlen(CacheRoot);
29 *pCacheFile++ = '/';
30 memcpy(pCacheFile, key, strlen(key));
31 pCacheFile += strlen(key);
32 memcpy(pCacheFile, ExeSuffix, strlen(ExeSuffix));
33 pCacheFile += strlen(ExeSuffix);
34 *pCacheFile = 0; // Null-terminate
35 return cacheFile;
36}
37
38/*
39 * llvmStat - equivalent to stat(3), except the key may not necessarily
40 * correspond to a file by that name, implementation is up to the OS.
41 * Values returned in buf are similar as they are in Unix.
42 */
43void llvmStat(const char *key, struct stat *buf) {
44 char* cacheFile = computeCachedFile(key);
45 fprintf(stderr, "llvmStat(%s)\n", cacheFile);
46 stat(cacheFile, buf);
47 free(cacheFile);
48}
49
50/*
51 * llvmWriteFile - implements a 'save' of a file in the OS. 'key' may not
52 * necessarily map to a file of the same name.
53 * Returns:
54 * 0 - success
55 * non-zero - error
56 */
57int llvmWriteFile(const char *key, const void *data, size_t len)
58{
59 char* cacheFile = computeCachedFile(key);
60 int fd = open(cacheFile, O_CREAT|O_WRONLY|O_TRUNC);
61 free(cacheFile);
62 if (fd < 0) return -1; // encountered an error
63 if (write(fd, data, len)) return -1;
64 if (fsync(fd)) return -1;
65 if (close(fd)) return -1;
66 return 0;
67}
68
69/*
70 * llvmReadFile - tells the OS to load data corresponding to a particular key
71 * somewhere into memory.
72 * Returns:
73 * 0 - failure
74 * non-zero - address of loaded file
75 *
76 * Value of size is the length of data loaded into memory.
77 */
78void* llvmReadFile(const char *key, size_t *size) {
79 char* cacheFile = computeCachedFile(key);
80 if (!cacheFile) return 0;
81 struct stat buf;
82 stat(cacheFile, &buf);
83 int fd = open(cacheFile, O_RDONLY);
84 if (fd < 0) return 0; // encountered an error
85 void* data = malloc(buf.st_size);
86 if (read(fd, data, buf.st_size)) {
87 free(data);
88 return 0;
89 }
90 *size = buf.st_size;
91 return data;
92}
93
94/*
95 * llvmExecve - execute a file from cache. This is a temporary proof-of-concept
96 * because we do not relocate what we can read from disk.
97 */
98int llvmExecve(const char *filename, char *const argv[], char *const envp[]) {
99 char* cacheFile = computeCachedFile(filename);
100 executeProgram(cacheFile, argv, envp);
101}