Commit | Line | Data |
---|---|---|
0f80bc85 JD |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <stddef.h> | |
4 | #include <stdarg.h> | |
5 | #include <unistd.h> | |
6 | #include <errno.h> | |
7 | #include <string.h> | |
8 | #include <fcntl.h> | |
9 | #include <sys/types.h> | |
10 | #include <sys/mman.h> | |
11 | #include "kern_util.h" | |
12 | #include "user.h" | |
13 | #include "user_util.h" | |
14 | #include "mem_user.h" | |
15 | #include "init.h" | |
16 | #include "os.h" | |
17 | #include "tempfile.h" | |
18 | #include "kern_constants.h" | |
19 | ||
20 | #include <sys/param.h> | |
21 | ||
22 | static char *tempdir = NULL; | |
23 | ||
24 | static void __init find_tempdir(void) | |
25 | { | |
26 | char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; | |
27 | int i; | |
28 | char *dir = NULL; | |
29 | ||
30 | if(tempdir != NULL) return; /* We've already been called */ | |
31 | for(i = 0; dirs[i]; i++){ | |
32 | dir = getenv(dirs[i]); | |
33 | if((dir != NULL) && (*dir != '\0')) | |
34 | break; | |
35 | } | |
36 | if((dir == NULL) || (*dir == '\0')) | |
37 | dir = "/tmp"; | |
38 | ||
39 | tempdir = malloc(strlen(dir) + 2); | |
40 | if(tempdir == NULL){ | |
41 | fprintf(stderr, "Failed to malloc tempdir, " | |
42 | "errno = %d\n", errno); | |
43 | return; | |
44 | } | |
45 | strcpy(tempdir, dir); | |
46 | strcat(tempdir, "/"); | |
47 | } | |
48 | ||
49 | /* | |
50 | * This proc still used in tt-mode | |
51 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). | |
52 | * So it isn't 'static' yet. | |
53 | */ | |
54 | int make_tempfile(const char *template, char **out_tempname, int do_unlink) | |
55 | { | |
56 | char tempname[MAXPATHLEN]; | |
57 | int fd; | |
58 | ||
59 | find_tempdir(); | |
60 | if (*template != '/') | |
61 | strcpy(tempname, tempdir); | |
62 | else | |
63 | *tempname = 0; | |
64 | strcat(tempname, template); | |
65 | fd = mkstemp(tempname); | |
66 | if(fd < 0){ | |
67 | fprintf(stderr, "open - cannot create %s: %s\n", tempname, | |
68 | strerror(errno)); | |
69 | return -1; | |
70 | } | |
71 | if(do_unlink && (unlink(tempname) < 0)){ | |
72 | perror("unlink"); | |
73 | return -1; | |
74 | } | |
75 | if(out_tempname){ | |
76 | *out_tempname = strdup(tempname); | |
77 | if(*out_tempname == NULL){ | |
78 | perror("strdup"); | |
79 | return -1; | |
80 | } | |
81 | } | |
82 | return(fd); | |
83 | } | |
84 | ||
85 | #define TEMPNAME_TEMPLATE "vm_file-XXXXXX" | |
86 | ||
87 | /* | |
88 | * This proc is used in start_up.c | |
89 | * So it isn't 'static'. | |
90 | */ | |
91 | int create_tmp_file(unsigned long len) | |
92 | { | |
93 | int fd, err; | |
94 | char zero; | |
95 | ||
96 | fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1); | |
97 | if(fd < 0) { | |
98 | exit(1); | |
99 | } | |
100 | ||
101 | err = fchmod(fd, 0777); | |
102 | if(err < 0){ | |
103 | perror("os_mode_fd"); | |
104 | exit(1); | |
105 | } | |
106 | ||
107 | if (lseek64(fd, len, SEEK_SET) < 0) { | |
108 | perror("os_seek_file"); | |
109 | exit(1); | |
110 | } | |
111 | ||
112 | zero = 0; | |
113 | ||
114 | err = os_write_file(fd, &zero, 1); | |
115 | if(err != 1){ | |
116 | errno = -err; | |
117 | perror("os_write_file"); | |
118 | exit(1); | |
119 | } | |
120 | ||
121 | return(fd); | |
122 | } | |
123 | ||
124 | static int create_anon_file(unsigned long len) | |
125 | { | |
126 | void *addr; | |
127 | int fd; | |
128 | ||
129 | fd = open("/dev/anon", O_RDWR); | |
130 | if(fd < 0) { | |
131 | perror("opening /dev/anon"); | |
132 | exit(1); | |
133 | } | |
134 | ||
135 | addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | |
136 | if(addr == MAP_FAILED){ | |
137 | perror("mapping physmem file"); | |
138 | exit(1); | |
139 | } | |
140 | munmap(addr, len); | |
141 | ||
142 | return(fd); | |
143 | } | |
144 | ||
145 | extern int have_devanon; | |
146 | ||
147 | int create_mem_file(unsigned long len) | |
148 | { | |
149 | int err, fd; | |
150 | ||
151 | if(have_devanon) | |
152 | fd = create_anon_file(len); | |
153 | else fd = create_tmp_file(len); | |
154 | ||
155 | err = os_set_exec_close(fd, 1); | |
156 | if(err < 0){ | |
157 | errno = -err; | |
158 | perror("exec_close"); | |
159 | } | |
160 | return(fd); | |
161 | } |