xref: /openbmc/linux/arch/um/os-Linux/mem.c (revision 87c2ce3b)
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 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 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 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 }
162