xref: /openbmc/linux/arch/um/os-Linux/mem.c (revision 87276f721a9407a4a152b09265dc079f37674672)
10f80bc85SJeff Dike #include <stdio.h>
20f80bc85SJeff Dike #include <stdlib.h>
30f80bc85SJeff Dike #include <stddef.h>
40f80bc85SJeff Dike #include <stdarg.h>
50f80bc85SJeff Dike #include <unistd.h>
60f80bc85SJeff Dike #include <errno.h>
70f80bc85SJeff Dike #include <string.h>
80f80bc85SJeff Dike #include <fcntl.h>
90f80bc85SJeff Dike #include <sys/types.h>
100f80bc85SJeff Dike #include <sys/mman.h>
110f80bc85SJeff Dike #include "kern_util.h"
120f80bc85SJeff Dike #include "user.h"
130f80bc85SJeff Dike #include "user_util.h"
140f80bc85SJeff Dike #include "mem_user.h"
150f80bc85SJeff Dike #include "init.h"
160f80bc85SJeff Dike #include "os.h"
170f80bc85SJeff Dike #include "tempfile.h"
180f80bc85SJeff Dike #include "kern_constants.h"
190f80bc85SJeff Dike 
200f80bc85SJeff Dike #include <sys/param.h>
210f80bc85SJeff Dike 
220f80bc85SJeff Dike static char *tempdir = NULL;
230f80bc85SJeff Dike 
240f80bc85SJeff Dike static void __init find_tempdir(void)
250f80bc85SJeff Dike {
260f80bc85SJeff Dike 	char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
270f80bc85SJeff Dike 	int i;
280f80bc85SJeff Dike 	char *dir = NULL;
290f80bc85SJeff Dike 
300f80bc85SJeff Dike 	if(tempdir != NULL) return;	/* We've already been called */
310f80bc85SJeff Dike 	for(i = 0; dirs[i]; i++){
320f80bc85SJeff Dike 		dir = getenv(dirs[i]);
330f80bc85SJeff Dike 		if((dir != NULL) && (*dir != '\0'))
340f80bc85SJeff Dike 			break;
350f80bc85SJeff Dike 	}
360f80bc85SJeff Dike 	if((dir == NULL) || (*dir == '\0'))
370f80bc85SJeff Dike 		dir = "/tmp";
380f80bc85SJeff Dike 
390f80bc85SJeff Dike 	tempdir = malloc(strlen(dir) + 2);
400f80bc85SJeff Dike 	if(tempdir == NULL){
410f80bc85SJeff Dike 		fprintf(stderr, "Failed to malloc tempdir, "
420f80bc85SJeff Dike 			"errno = %d\n", errno);
430f80bc85SJeff Dike 		return;
440f80bc85SJeff Dike 	}
450f80bc85SJeff Dike 	strcpy(tempdir, dir);
460f80bc85SJeff Dike 	strcat(tempdir, "/");
470f80bc85SJeff Dike }
480f80bc85SJeff Dike 
490f80bc85SJeff Dike /*
500f80bc85SJeff Dike  * This proc still used in tt-mode
510f80bc85SJeff Dike  * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
520f80bc85SJeff Dike  * So it isn't 'static' yet.
530f80bc85SJeff Dike  */
540f80bc85SJeff Dike int make_tempfile(const char *template, char **out_tempname, int do_unlink)
550f80bc85SJeff Dike {
56*87276f72SPaolo 'Blaisorblade' Giarrusso 	char *tempname;
570f80bc85SJeff Dike 	int fd;
580f80bc85SJeff Dike 
59*87276f72SPaolo 'Blaisorblade' Giarrusso 	tempname = malloc(MAXPATHLEN);
60*87276f72SPaolo 'Blaisorblade' Giarrusso 
610f80bc85SJeff Dike 	find_tempdir();
62*87276f72SPaolo 'Blaisorblade' Giarrusso 	if (template[0] != '/')
630f80bc85SJeff Dike 		strcpy(tempname, tempdir);
640f80bc85SJeff Dike 	else
65*87276f72SPaolo 'Blaisorblade' Giarrusso 		tempname[0] = '\0';
660f80bc85SJeff Dike 	strcat(tempname, template);
670f80bc85SJeff Dike 	fd = mkstemp(tempname);
680f80bc85SJeff Dike 	if(fd < 0){
690f80bc85SJeff Dike 		fprintf(stderr, "open - cannot create %s: %s\n", tempname,
700f80bc85SJeff Dike 			strerror(errno));
71*87276f72SPaolo 'Blaisorblade' Giarrusso 		goto out;
720f80bc85SJeff Dike 	}
730f80bc85SJeff Dike 	if(do_unlink && (unlink(tempname) < 0)){
740f80bc85SJeff Dike 		perror("unlink");
75*87276f72SPaolo 'Blaisorblade' Giarrusso 		goto out;
760f80bc85SJeff Dike 	}
770f80bc85SJeff Dike 	if(out_tempname){
78*87276f72SPaolo 'Blaisorblade' Giarrusso 		*out_tempname = tempname;
79*87276f72SPaolo 'Blaisorblade' Giarrusso 	} else {
80*87276f72SPaolo 'Blaisorblade' Giarrusso 		free(tempname);
810f80bc85SJeff Dike 	}
820f80bc85SJeff Dike 	return(fd);
83*87276f72SPaolo 'Blaisorblade' Giarrusso out:
84*87276f72SPaolo 'Blaisorblade' Giarrusso 	free(tempname);
85*87276f72SPaolo 'Blaisorblade' Giarrusso 	return -1;
860f80bc85SJeff Dike }
870f80bc85SJeff Dike 
880f80bc85SJeff Dike #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
890f80bc85SJeff Dike 
900f80bc85SJeff Dike /*
910f80bc85SJeff Dike  * This proc is used in start_up.c
920f80bc85SJeff Dike  * So it isn't 'static'.
930f80bc85SJeff Dike  */
94ae173816SJeff Dike int create_tmp_file(unsigned long long len)
950f80bc85SJeff Dike {
960f80bc85SJeff Dike 	int fd, err;
970f80bc85SJeff Dike 	char zero;
980f80bc85SJeff Dike 
990f80bc85SJeff Dike 	fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
1000f80bc85SJeff Dike 	if(fd < 0) {
1010f80bc85SJeff Dike 		exit(1);
1020f80bc85SJeff Dike 	}
1030f80bc85SJeff Dike 
1040f80bc85SJeff Dike 	err = fchmod(fd, 0777);
1050f80bc85SJeff Dike 	if(err < 0){
1060f80bc85SJeff Dike 		perror("os_mode_fd");
1070f80bc85SJeff Dike 		exit(1);
1080f80bc85SJeff Dike 	}
1090f80bc85SJeff Dike 
1100f80bc85SJeff Dike         if (lseek64(fd, len, SEEK_SET) < 0) {
1110f80bc85SJeff Dike  		perror("os_seek_file");
1120f80bc85SJeff Dike 		exit(1);
1130f80bc85SJeff Dike 	}
1140f80bc85SJeff Dike 
1150f80bc85SJeff Dike 	zero = 0;
1160f80bc85SJeff Dike 
1170f80bc85SJeff Dike 	err = os_write_file(fd, &zero, 1);
1180f80bc85SJeff Dike 	if(err != 1){
1190f80bc85SJeff Dike 		errno = -err;
1200f80bc85SJeff Dike 		perror("os_write_file");
1210f80bc85SJeff Dike 		exit(1);
1220f80bc85SJeff Dike 	}
1230f80bc85SJeff Dike 
1240f80bc85SJeff Dike 	return(fd);
1250f80bc85SJeff Dike }
1260f80bc85SJeff Dike 
127ae173816SJeff Dike int create_mem_file(unsigned long long len)
1280f80bc85SJeff Dike {
1290f80bc85SJeff Dike 	int err, fd;
1300f80bc85SJeff Dike 
13102dea087SJeff Dike 	fd = create_tmp_file(len);
1320f80bc85SJeff Dike 
1330f80bc85SJeff Dike 	err = os_set_exec_close(fd, 1);
1340f80bc85SJeff Dike 	if(err < 0){
1350f80bc85SJeff Dike 		errno = -err;
1360f80bc85SJeff Dike 		perror("exec_close");
1370f80bc85SJeff Dike 	}
1380f80bc85SJeff Dike 	return(fd);
1390f80bc85SJeff Dike }
140