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