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