radare2/libr/util/file.c

796 lines
16 KiB
C
Raw Normal View History

2016-06-14 00:22:14 +00:00
/* radare - LGPL - Copyright 2007-2016 - pancake */
#include "r_types.h"
#include "r_util.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#if __UNIX__
#include <sys/mman.h>
#endif
R_API bool r_file_truncate (const char *filename, ut64 newsize) {
int fd;
if (r_file_is_directory (filename)) {
return false;
}
if (!r_file_exists (filename) || !r_file_is_regular (filename)) {
return false;
}
2014-05-19 08:54:29 +00:00
#if __WINDOWS__
fd = r_sandbox_open (filename, O_RDWR, 0644);
#else
fd = r_sandbox_open (filename, O_RDWR|O_SYNC, 0644);
2014-05-19 08:54:29 +00:00
#endif
if (fd == -1) {
return false;
}
ftruncate (fd, newsize);
close (fd);
return true;
}
/*
Example:
str = r_file_basename ("home/inisider/Downloads/user32.dll");
2015-04-10 22:42:30 +00:00
// str == user32.dll
*/
R_API const char *r_file_basename (const char *path) {
const char *ptr = r_str_rchr (path, NULL, '/');
if (ptr) {
path = ptr + 1;
} else {
ptr = r_str_rchr (path, NULL, '\\');
if (ptr) path = ptr + 1;
}
return path;
}
/*
Example:
str = r_file_basename ("home/inisider/Downloads");
// str == "home/inisider/Downloads"
free (str);
*/
R_API char *r_file_dirname (const char *path) {
char *newpath = strdup (path);
char *ptr = (char*)r_str_rchr (newpath, NULL, '/');
if (ptr) {
*ptr = 0;
} else {
ptr = (char*)r_str_rchr (newpath, NULL, '\\');
if (ptr) *ptr = 0;
}
return newpath;
}
R_API bool r_file_is_regular(const char *str) {
struct stat buf = {0};
if (!str || !*str || stat (str, &buf) == -1) {
return false;
}
return ((S_IFREG & buf.st_mode)==S_IFREG)? true: false;
}
R_API bool r_file_is_directory(const char *str) {
struct stat buf = {0};
if (!str||!*str)
return false;
if (stat (str, &buf)==-1)
return false;
2014-01-21 01:08:51 +00:00
if ((S_IFBLK & buf.st_mode) == S_IFBLK)
return false;
return (S_IFDIR==(S_IFDIR & buf.st_mode))? true: false;
}
R_API bool r_file_fexists(const char *fmt, ...) {
int ret;
char string[1024];
va_list ap;
va_start (ap, fmt);
vsnprintf (string, sizeof (string), fmt, ap);
ret = r_file_exists (string);
va_end (ap);
return ret;
}
R_API bool r_file_exists(const char *str) {
struct stat buf = {0};
if (str && *str && stat (str, &buf)==-1)
return false;
return (S_ISREG (buf.st_mode))? true: false;
}
R_API long r_file_proc_size(FILE *fd) {
long size = 0;
while (fgetc (fd) != EOF) {
size++;
}
return size;
}
R_API ut64 r_file_size(const char *str) {
struct stat buf = {0};
if (stat (str, &buf)==-1)
return 0;
return (ut64)buf.st_size;
}
R_API int r_file_is_abspath(const char *file) {
return ((*file && file[1]==':') || *file == '/');
}
R_API char *r_file_abspath(const char *file) {
char *cwd, *ret = NULL;
if (!file || !strcmp (file, ".") || !strcmp (file, "./")) {
return r_sys_getdir ();
}
if (strstr (file, "://")) {
return strdup (file);
}
cwd = r_sys_getdir ();
if (!strncmp (file, "~/", 2) || !strncmp (file, "~\\", 2)) {
ret = r_str_home (file + 2);
} else {
2015-04-10 22:42:30 +00:00
#if __UNIX__ || __CYGWIN__
if (cwd && *file != '/')
ret = r_str_newf ("%s"R_SYS_DIR"%s", cwd, file);
2015-04-10 22:42:30 +00:00
#elif __WINDOWS__ && !__CYGWIN__
if (cwd && !strchr (file, ':')) {
ret = r_str_newf ("%s\\%s", cwd, file);
}
2010-02-20 05:40:02 +00:00
#endif
}
free (cwd);
if (!ret) ret = strdup (file);
#if __UNIX__
{
2016-06-06 15:30:07 +00:00
char *resolved_path = calloc(4096, 1); // TODO: use MAXPATH
char *abspath = realpath (ret, resolved_path);
if (abspath) {
free (ret);
ret = abspath;
} else {
free (resolved_path);
}
}
#endif
return ret;
2010-02-20 05:40:02 +00:00
}
R_API char *r_file_path(const char *bin) {
char file[1024];
2015-03-22 21:41:46 +00:00
char *path_env;
char *path = NULL;
char *str, *ptr;
if (!bin) {
return NULL;
}
if (!strncmp (bin, "./", 2)) {
if (r_file_exists (bin)) {
return r_file_abspath (bin);
}
return NULL;
}
2015-03-22 21:41:46 +00:00
path_env = (char *)r_sys_getenv ("PATH");
if (path_env) {
str = path = strdup (path_env);
do {
ptr = strchr (str, ':');
if (ptr) {
*ptr = '\0';
snprintf (file, sizeof (file), "%s"R_SYS_DIR"%s", str, bin);
2012-09-06 06:59:13 +00:00
if (r_file_exists (file)) {
free (path);
2011-08-27 22:01:03 +00:00
free (path_env);
return strdup (file);
}
str = ptr + 1;
}
} while (ptr);
2011-08-27 22:01:03 +00:00
}
free (path_env);
free (path);
return strdup (bin);
}
R_API char *r_stdin_slurp (int *sz) {
#define BS 1024
#if __UNIX__
2015-01-14 01:53:34 +00:00
int i, ret, newfd;
char *buf;
2015-01-25 11:10:08 +00:00
if ((newfd = dup(0)) < 0)
2015-01-14 01:53:34 +00:00
return NULL;
buf = malloc (BS);
for (i=ret=0;;i+=ret) {
char *new = realloc (buf, i+BS);
if (!new) {
eprintf ("Cannot realloc to %d\n", i+BS);
break;
}
buf = new;
ret = read (0, buf+i, BS);
if (ret<1)
break;
}
buf[i] = 0;
dup2 (newfd, 0);
close (newfd);
if (sz)
*sz = i;
if (i==0) {
R_FREE (buf);
}
return buf;
#else
#warning TODO r_stdin_slurp
return NULL;
#endif
}
R_API char *r_file_slurp(const char *str, int *usz) {
size_t rsz;
char *ret;
FILE *fd;
long sz;
2012-09-06 06:59:13 +00:00
if (!r_file_exists (str))
return NULL;
fd = r_sandbox_fopen (str, "rb");
2016-06-14 00:22:14 +00:00
if (!fd) {
return NULL;
2016-06-14 00:22:14 +00:00
}
(void)fseek (fd, 0, SEEK_END);
sz = ftell (fd);
2016-06-14 00:22:14 +00:00
if (sz == 0) {
if (r_file_is_regular (str)) {
/* proc file */
fseek (fd, 0, SEEK_SET);
sz = r_file_proc_size (fd);
if (!sz) sz = -1;
} else {
sz = 65536;
}
}
2016-06-14 00:22:14 +00:00
if (sz < 0) {
fclose (fd);
return NULL;
}
fseek (fd, 0, SEEK_SET);
2016-06-14 00:22:14 +00:00
ret = (char *)calloc (sz + 1, 1);
2015-04-10 22:42:30 +00:00
if (!ret) {
fclose (fd);
return NULL;
}
rsz = fread (ret, 1, sz, fd);
2014-06-04 01:51:18 +00:00
if (rsz != sz) {
// eprintf ("r_file_slurp: fread: error\n");
sz = rsz;
}
fclose (fd);
2016-08-05 11:25:20 +00:00
ret[sz] = '\0';
if (usz) {
*usz = (int)sz;
2016-08-05 11:25:20 +00:00
}
return ret;
}
2014-08-10 16:24:00 +00:00
R_API ut8 *r_file_gzslurp(const char *str, int *outlen, int origonfail) {
int sz;
2014-08-10 16:24:00 +00:00
ut8 *in, *out;
if (outlen) *outlen = 0;
2014-08-10 16:24:00 +00:00
in = (ut8*)r_file_slurp (str, &sz);
if (!in) return NULL;
out = r_inflate (in, sz, NULL, outlen);
2014-08-10 16:24:00 +00:00
if (!out && origonfail) {
// if uncompression fails, return orig buffer ?
2016-06-14 00:22:14 +00:00
if (outlen) {
2014-08-10 16:24:00 +00:00
*outlen = sz;
2016-06-14 00:22:14 +00:00
}
2014-08-10 16:24:00 +00:00
in[sz] = 0;
return in;
}
free (in);
return out;
}
R_API ut8 *r_file_slurp_hexpairs(const char *str, int *usz) {
ut8 *ret;
long sz;
int c, bytes = 0;
FILE *fd = r_sandbox_fopen (str, "r");
2016-06-14 00:22:14 +00:00
if (!fd) {
return NULL;
2016-06-14 00:22:14 +00:00
}
(void)fseek (fd, 0, SEEK_END);
sz = ftell (fd);
2016-06-14 00:22:14 +00:00
(void)fseek (fd, 0, SEEK_SET);
ret = (ut8*)malloc ((sz>>1)+1);
2014-03-08 06:41:22 +00:00
if (!ret) {
fclose (fd);
return NULL;
2014-03-08 06:41:22 +00:00
}
for (;;) {
if (fscanf (fd, " #%*[^\n]") == 1)
continue;
if (fscanf (fd, "%02x", &c) == 1) {
ret[bytes++] = c;
continue;
}
if (feof (fd))
break;
free (ret);
2014-03-08 06:41:22 +00:00
fclose (fd);
return NULL;
}
ret[bytes] = '\0';
fclose (fd);
if (usz) *usz = bytes;
return ret;
}
R_API char *r_file_slurp_range(const char *str, ut64 off, int sz, int *osz) {
char *ret;
2014-03-08 06:41:22 +00:00
size_t read_items;
FILE *fd = r_sandbox_fopen (str, "rb");
if (!fd)
return NULL;
// XXX handle out of bound reads (eof)
2014-03-08 06:41:22 +00:00
if (fseek (fd, off, SEEK_SET) < 0) {
fclose (fd);
return NULL;
}
ret = (char *)malloc (sz+1);
if (ret != NULL) {
if (osz)
*osz = (int)(size_t)fread (ret, 1, sz, fd);
2014-03-08 06:41:22 +00:00
else {
read_items = fread (ret, 1, sz, fd);
if (!read_items) {
fclose (fd);
return ret;
}
}
ret[sz] = '\0';
}
fclose (fd);
return ret;
}
R_API char *r_file_slurp_random_line(const char *file) {
int i = 0;
return r_file_slurp_random_line_count(file, &i);
}
R_API char *r_file_slurp_random_line_count(const char *file, int *line) {
/* Reservoir Sampling */
char *ptr = NULL, *str;
int sz, i, lines, selection = -1;
struct timeval tv;
int start = *line;
if ((str = r_file_slurp (file, &sz))) {
gettimeofday (&tv,NULL);
srand (getpid()+tv.tv_usec);
for (i=0; str[i]; i++) {
if (str[i]=='\n') {
if (rand() % (++(*line)) == 0) {
selection = (*line - 1); /* The line we want. */
}
}
}
if ((selection < start) || (selection == -1)) {
free (str);
return NULL;
} else {
lines = selection - start;
}
if (lines>0) {
for (i=0; str[i] && lines; i++)
if (str[i]=='\n')
lines--;
ptr = str+i;
for (i=0; ptr[i]; i++)
if (ptr[i]=='\n') {
ptr[i]='\0';
break;
}
ptr = strdup (ptr);
}
free (str);
}
return ptr;
}
R_API char *r_file_slurp_line(const char *file, int line, int context) {
int i, lines = 0;
int sz;
2010-04-20 17:32:04 +00:00
char *ptr = NULL, *str = r_file_slurp (file, &sz);
// TODO: Implement context
if (str) {
for (i=0; str[i]; i++)
if (str[i]=='\n')
lines++;
if (line > lines) {
free (str);
return NULL;
}
2014-04-21 15:17:52 +00:00
lines = line - 1;
for (i=0; str[i]&&lines; i++)
if (str[i]=='\n')
lines--;
ptr = str+i;
for (i=0; ptr[i]; i++) {
if (ptr[i]=='\n') {
ptr[i]='\0';
break;
}
}
ptr = strdup (ptr);
free (str);
}
return ptr;
}
R_API char *r_file_root(const char *root, const char *path) {
char *ret, *s = r_str_replace (strdup (path), "..", "", 1);
// XXX ugly hack
while (strstr (s, "..")) s = r_str_replace (s, "..", "", 1);
while (strstr (s, "./")) s = r_str_replace (s, "./", "", 1);
while (strstr (s, "//")) s = r_str_replace (s, "//", "", 1);
ret = r_str_concat (strdup (root), R_SYS_DIR);
ret = r_str_concat (ret, s);
free (s);
return ret;
}
R_API bool r_file_dump(const char *file, const ut8 *buf, int len, int append) {
FILE *fd;
2016-05-21 13:11:16 +00:00
if (!file || !*file || !buf || len < 0) {
2015-07-08 17:13:30 +00:00
eprintf ("r_file_dump file: %s buf: %p\n", file, buf);
2016-05-21 13:11:16 +00:00
return false;
2015-04-03 02:04:46 +00:00
}
if (append) {
fd = r_sandbox_fopen (file, "awb");
} else {
r_sys_truncate (file, 0);
fd = r_sandbox_fopen (file, "wb");
}
if (!fd) {
eprintf ("Cannot open '%s' for writing\n", file);
2016-05-21 13:11:16 +00:00
return false;
}
if (len < 0) {
len = strlen ((const char *)buf);
}
if (fwrite (buf, len, 1, fd) != 1) {
r_sys_perror ("r_file_dump: fwrite: error\n");
fclose (fd);
return false;
}
fclose (fd);
2016-05-21 13:11:16 +00:00
return true;
}
R_API bool r_file_rm(const char *file) {
if (r_sandbox_enable (0)) {
return false;
}
if (r_file_is_directory (file)) {
#if __WINDOWS__
return !RemoveDirectory (file);
#else
return !rmdir (file);
#endif
} else {
#if __WINDOWS__
return !DeleteFile (file);
#else
return !unlink (file);
#endif
2014-03-08 06:41:22 +00:00
}
}
R_API char *r_file_readlink(const char *path) {
if (!r_sandbox_enable (0)) {
#if __UNIX__
int ret;
2016-06-14 00:22:14 +00:00
char pathbuf[4096] = {0};
strncpy (pathbuf, path, sizeof (pathbuf) - 1);
repeat:
ret = readlink (path, pathbuf, sizeof (pathbuf)-1);
if (ret != -1) {
pathbuf[ret] = 0;
path = pathbuf;
goto repeat;
}
return strdup (pathbuf);
#endif
}
return NULL;
}
R_API int r_file_mmap_write(const char *file, ut64 addr, const ut8 *buf, int len) {
#if __WINDOWS__
HANDLE fh;
DWORD written = 0;
2013-03-12 12:24:48 +00:00
if (r_sandbox_enable (0)) return -1;
fh = CreateFile (file, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
2013-03-12 12:24:48 +00:00
if (fh == INVALID_HANDLE_VALUE) {
r_sys_perror ("r_file_mmap_write: CreateFile");
2013-03-12 12:24:48 +00:00
return -1;
}
2014-09-23 08:59:26 +00:00
// no need to overengineer the file write more
#if 0
HANDLE fm;
fm = CreateFileMapping (fh, NULL,
PAGE_READWRITE, 0, 0, NULL);
if (!fm) {
r_sys_perror ("r_file_mmap_write: CreateFileMapping");
2013-03-12 12:24:48 +00:00
CloseHandle (fh);
return -1;
}
2013-03-12 12:24:48 +00:00
if (fm != INVALID_HANDLE_VALUE) {
2014-09-23 08:59:26 +00:00
MEMORY_BASIC_INFORMATION info;
ut8 *obuf = MapViewOfFile (fm,
FILE_MAP_WRITE,
2014-09-23 08:59:26 +00:00
0,0,
0);
VirtualQuery (obuf, &info, sizeof(info);
memcpy (obuf+addr, buf, len);
2013-03-12 12:24:48 +00:00
UnmapViewOfFile (obuf);
}
CloseHandle (fm);
2014-09-23 08:59:26 +00:00
#else
SetFilePointer (fh, addr, NULL, FILE_BEGIN);
if (!WriteFile (fh, buf, len, &written, NULL)) {
2014-09-23 08:59:26 +00:00
r_sys_perror ("WriteFile");
len = -1;
}
#endif
CloseHandle (fh);
2013-08-26 23:18:42 +00:00
return len;
2013-03-12 12:24:48 +00:00
#elif __UNIX__
int fd = r_sandbox_open (file, O_RDWR|O_SYNC, 0644);
2016-02-16 23:38:54 +00:00
const int pagesize = getpagesize ();
int mmlen = len + pagesize;
int rest = addr % pagesize;
ut8 *mmap_buf;
if (fd == -1) return -1;
2016-02-16 23:38:54 +00:00
if ((st64)addr < 0) return -1;
mmap_buf = mmap (NULL, mmlen*2, PROT_READ|PROT_WRITE,
2016-02-16 23:38:54 +00:00
MAP_SHARED, fd, (off_t)addr - rest);
if (((int)(size_t)mmap_buf)==-1)
return -1;
memcpy (mmap_buf+rest, buf, len);
munmap (mmap_buf, mmlen*2);
close (fd);
return len;
2013-03-12 12:24:48 +00:00
#else
return -1;
#endif
}
R_API int r_file_mmap_read (const char *file, ut64 addr, ut8 *buf, int len) {
#if __WINDOWS__
2013-03-12 12:24:48 +00:00
HANDLE fm, fh;
2013-03-12 12:24:48 +00:00
if (r_sandbox_enable (0)) return -1;
fh = CreateFile (file, GENERIC_READ,
2013-03-12 12:24:48 +00:00
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2013-03-12 12:24:48 +00:00
if (fh == INVALID_HANDLE_VALUE) {
r_sys_perror ("CreateFile");
2013-03-12 12:24:48 +00:00
return -1;
}
fm = CreateFileMapping (fh, NULL,
PAGE_READONLY, 0, 0, NULL);
2013-03-12 12:24:48 +00:00
if (fm != INVALID_HANDLE_VALUE) {
ut8 *obuf = MapViewOfFile (fm,
FILE_MAP_READ,
0, 0, len);
2013-03-12 12:24:48 +00:00
memcpy (obuf, buf, len);
UnmapViewOfFile (obuf);
} else {
r_sys_perror ("CreateFileMapping");
CloseHandle (fh);
return -1;
2013-03-12 12:24:48 +00:00
}
CloseHandle (fh);
CloseHandle (fm);
return len;
2013-03-12 12:24:48 +00:00
#elif __UNIX__
int fd = r_sandbox_open (file, O_RDONLY, 0644);
const int pagesize = 4096;
int mmlen = len+pagesize;
int rest = addr%pagesize;
ut8 *mmap_buf;
if (fd == -1) return -1;
mmap_buf = mmap (NULL, mmlen*2, PROT_READ,
MAP_SHARED, fd, (off_t)addr-rest);
if (((int)(size_t)mmap_buf)==-1)
return -1;
memcpy (buf, mmap_buf+rest, len);
munmap (mmap_buf, mmlen*2);
close (fd);
return len;
#endif
return 0;
}
#if __UNIX__
static RMmap *r_file_mmap_unix (RMmap *m, int fd) {
ut8 empty = m->len == 0;
m->buf = mmap (NULL, (empty?1024:m->len) ,
m->rw?PROT_READ|PROT_WRITE:PROT_READ,
MAP_SHARED, fd, (off_t)m->base);
2013-03-12 12:24:48 +00:00
if (m->buf == MAP_FAILED) {
free (m);
m = NULL;
}
return m;
}
#elif __WINDOWS__
2014-05-19 08:54:29 +00:00
static RMmap *r_file_mmap_windows (RMmap *m, const char *file) {
m->fh = CreateFile (file, GENERIC_READ | (m->rw?GENERIC_WRITE:0),
FILE_SHARE_READ|(m->rw?FILE_SHARE_WRITE:0), NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
2013-03-12 12:24:48 +00:00
if (m->fh == INVALID_HANDLE_VALUE) {
r_sys_perror ("CreateFile");
2013-03-12 12:24:48 +00:00
free (m);
return NULL;
}
m->fm = CreateFileMapping (m->fh, NULL,
PAGE_READONLY, 0, 0, NULL);
//m->rw?PAGE_READWRITE:PAGE_READONLY, 0, 0, NULL);
2013-03-12 12:24:48 +00:00
if (m->fm != INVALID_HANDLE_VALUE) {
m->buf = MapViewOfFile (m->fm,
// m->rw?(FILE_MAP_READ|FILE_MAP_WRITE):FILE_MAP_READ,
FILE_MAP_COPY,
UT32_HI (m->base), UT32_LO (m->base), 0);
2013-03-12 12:24:48 +00:00
} else {
r_sys_perror ("CreateFileMapping");
2013-03-12 12:24:48 +00:00
CloseHandle (m->fh);
free (m);
m = NULL;
}
return m;
}
#else
static RMmap *r_file_mmap_other (RMmap *m) {
ut8 empty = m->len == 0;
m->buf = malloc ((empty?1024:m->len));
if (!empty && m->buf) {
lseek (m->fd, (off_t)0, SEEK_SET);
read (m->fd, m->buf, m->len);
2013-03-12 12:24:48 +00:00
} else {
free (m);
m = NULL;
}
return m;
}
#endif
// TODO: add rwx support?
R_API RMmap *r_file_mmap (const char *file, bool rw, ut64 base) {
RMmap *m = NULL;
int fd = -1;
if (!rw && !r_file_exists (file)) return m;
fd = r_sandbox_open (file, rw? O_RDWR: O_RDONLY, 0644);
if (fd == -1 && !rw) {
eprintf ("r_file_mmap: file does not exis.\n");
//m->buf = malloc (m->len);
return m;
}
m = R_NEW (RMmap);
if (!m) {
if (fd != -1) close (fd);
return NULL;
}
m->base = base;
m->rw = rw;
m->fd = fd;
m->len = fd != -1? lseek (fd, (off_t)0, SEEK_END) : 0;
if (m->fd == -1) {
return m;
}
if (m->len == (off_t)-1) {
close (fd);
R_FREE (m);
return NULL;
}
#if __UNIX__
return r_file_mmap_unix (m, fd);
#elif __WINDOWS__
close (fd);
m->fd = -1;
2014-05-19 08:54:29 +00:00
return r_file_mmap_windows (m, file);
#else
return r_file_mmap_other (m);
#endif
}
R_API void r_file_mmap_free (RMmap *m) {
if (!m) return;
#if __WINDOWS__
if (m->fm != INVALID_HANDLE_VALUE)
CloseHandle (m->fm);
if (m->fh != INVALID_HANDLE_VALUE)
CloseHandle (m->fh);
if (m->buf)
UnmapViewOfFile (m->buf);
#endif
if (m->fd == -1) {
free (m);
return;
}
#if __UNIX__
munmap (m->buf, m->len);
#endif
close (m->fd);
free (m);
}
R_API char *r_file_temp (const char *prefix) {
int namesz;
char *name;
2011-08-27 22:01:03 +00:00
char *path = r_file_tmpdir ();
namesz = strlen (prefix) + strlen (path) + 32;
name = malloc (namesz);
snprintf (name, namesz, "%s/%s.%"PFMT64x, path, prefix, r_sys_now ());
2011-08-27 22:01:03 +00:00
free (path);
return name;
}
R_API int r_file_mkstemp (const char *prefix, char **oname) {
int h;
2011-08-27 22:01:03 +00:00
char *path = r_file_tmpdir ();
char name[1024];
#if __WINDOWS__
if (GetTempFileName (path, prefix, 0, name))
h = r_sandbox_open (name, O_RDWR|O_EXCL|O_BINARY, 0644);
else h = -1;
#else
2014-06-25 02:19:23 +00:00
mode_t mask;
snprintf (name, sizeof (name), "%s/%sXXXXXX", path, prefix);
2014-03-08 20:01:04 +00:00
mask = umask(S_IWGRP | S_IWOTH);
h = mkstemp (name);
2014-03-08 06:41:22 +00:00
umask(mask);
#endif
if (oname) *oname = (h!=-1)? strdup (name): NULL;
2011-08-27 22:01:03 +00:00
free (path);
return h;
}
2011-05-03 17:36:06 +00:00
2011-08-27 22:01:03 +00:00
R_API char *r_file_tmpdir() {
2011-05-03 17:36:06 +00:00
#if __WINDOWS__
2011-08-27 22:01:03 +00:00
char *path = r_sys_getenv ("TEMP");
if (!path) path = strdup ("C:\\WINDOWS\\Temp\\");
#elif __ANDROID__
2015-04-22 02:50:37 +00:00
char *path = strdup ("/data/data/org.radare2.installer/radare2/tmp");
2011-05-03 17:36:06 +00:00
#else
2011-08-27 22:01:03 +00:00
char *path = r_sys_getenv ("TMPDIR");
if (path && !*path) {
free (path);
path = NULL;
}
2011-08-27 22:01:03 +00:00
if (!path) path = strdup ("/tmp");
2011-05-03 17:36:06 +00:00
#endif
if (!r_file_is_directory (path)) {
eprintf ("Cannot find temporary directory '%s'\n", path);
}
2011-05-03 17:36:06 +00:00
return path;
}