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