xref: /linux/arch/um/os-Linux/mem.c (revision 02dea0875b0f9b331a65fd6097dfd6115ca4ef24)
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 {
560f80bc85SJeff Dike 	char tempname[MAXPATHLEN];
570f80bc85SJeff Dike 	int fd;
580f80bc85SJeff Dike 
590f80bc85SJeff Dike 	find_tempdir();
600f80bc85SJeff Dike 	if (*template != '/')
610f80bc85SJeff Dike 		strcpy(tempname, tempdir);
620f80bc85SJeff Dike 	else
630f80bc85SJeff Dike 		*tempname = 0;
640f80bc85SJeff Dike 	strcat(tempname, template);
650f80bc85SJeff Dike 	fd = mkstemp(tempname);
660f80bc85SJeff Dike 	if(fd < 0){
670f80bc85SJeff Dike 		fprintf(stderr, "open - cannot create %s: %s\n", tempname,
680f80bc85SJeff Dike 			strerror(errno));
690f80bc85SJeff Dike 		return -1;
700f80bc85SJeff Dike 	}
710f80bc85SJeff Dike 	if(do_unlink && (unlink(tempname) < 0)){
720f80bc85SJeff Dike 		perror("unlink");
730f80bc85SJeff Dike 		return -1;
740f80bc85SJeff Dike 	}
750f80bc85SJeff Dike 	if(out_tempname){
760f80bc85SJeff Dike 		*out_tempname = strdup(tempname);
770f80bc85SJeff Dike 		if(*out_tempname == NULL){
780f80bc85SJeff Dike 			perror("strdup");
790f80bc85SJeff Dike 			return -1;
800f80bc85SJeff Dike 		}
810f80bc85SJeff Dike 	}
820f80bc85SJeff Dike 	return(fd);
830f80bc85SJeff Dike }
840f80bc85SJeff Dike 
850f80bc85SJeff Dike #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
860f80bc85SJeff Dike 
870f80bc85SJeff Dike /*
880f80bc85SJeff Dike  * This proc is used in start_up.c
890f80bc85SJeff Dike  * So it isn't 'static'.
900f80bc85SJeff Dike  */
91ae173816SJeff Dike int create_tmp_file(unsigned long long len)
920f80bc85SJeff Dike {
930f80bc85SJeff Dike 	int fd, err;
940f80bc85SJeff Dike 	char zero;
950f80bc85SJeff Dike 
960f80bc85SJeff Dike 	fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
970f80bc85SJeff Dike 	if(fd < 0) {
980f80bc85SJeff Dike 		exit(1);
990f80bc85SJeff Dike 	}
1000f80bc85SJeff Dike 
1010f80bc85SJeff Dike 	err = fchmod(fd, 0777);
1020f80bc85SJeff Dike 	if(err < 0){
1030f80bc85SJeff Dike 		perror("os_mode_fd");
1040f80bc85SJeff Dike 		exit(1);
1050f80bc85SJeff Dike 	}
1060f80bc85SJeff Dike 
1070f80bc85SJeff Dike         if (lseek64(fd, len, SEEK_SET) < 0) {
1080f80bc85SJeff Dike  		perror("os_seek_file");
1090f80bc85SJeff Dike 		exit(1);
1100f80bc85SJeff Dike 	}
1110f80bc85SJeff Dike 
1120f80bc85SJeff Dike 	zero = 0;
1130f80bc85SJeff Dike 
1140f80bc85SJeff Dike 	err = os_write_file(fd, &zero, 1);
1150f80bc85SJeff Dike 	if(err != 1){
1160f80bc85SJeff Dike 		errno = -err;
1170f80bc85SJeff Dike 		perror("os_write_file");
1180f80bc85SJeff Dike 		exit(1);
1190f80bc85SJeff Dike 	}
1200f80bc85SJeff Dike 
1210f80bc85SJeff Dike 	return(fd);
1220f80bc85SJeff Dike }
1230f80bc85SJeff Dike 
124ae173816SJeff Dike int create_mem_file(unsigned long long len)
1250f80bc85SJeff Dike {
1260f80bc85SJeff Dike 	int err, fd;
1270f80bc85SJeff Dike 
128*02dea087SJeff Dike 	fd = create_tmp_file(len);
1290f80bc85SJeff Dike 
1300f80bc85SJeff Dike 	err = os_set_exec_close(fd, 1);
1310f80bc85SJeff Dike 	if(err < 0){
1320f80bc85SJeff Dike 		errno = -err;
1330f80bc85SJeff Dike 		perror("exec_close");
1340f80bc85SJeff Dike 	}
1350f80bc85SJeff Dike 	return(fd);
1360f80bc85SJeff Dike }
137