2008-08-06 11:15:24 -07:00
|
|
|
/* EINA - EFL data type library
|
2008-09-01 05:51:50 -07:00
|
|
|
* Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Vincent Torri
|
2011-09-15 08:37:28 -07:00
|
|
|
* Copyright (C) 2010-2011 Cedric Bail
|
2008-08-06 11:15:24 -07:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2008-08-28 00:46:42 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2009-09-06 21:32:49 -07:00
|
|
|
# include "config.h"
|
2008-08-28 00:46:42 -07:00
|
|
|
#endif
|
|
|
|
|
2020-08-14 07:22:17 -07:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
# define _GNU_SOURCE
|
|
|
|
#endif
|
|
|
|
|
2011-12-06 13:33:39 -08:00
|
|
|
#include <stdlib.h>
|
2009-08-23 02:18:14 -07:00
|
|
|
#include <string.h>
|
2010-10-28 02:59:27 -07:00
|
|
|
#include <stddef.h>
|
2012-05-08 03:31:12 -07:00
|
|
|
#include <stdint.h>
|
2011-12-05 05:57:10 -08:00
|
|
|
#ifdef HAVE_DIRENT_H
|
|
|
|
# include <dirent.h>
|
|
|
|
#endif
|
2010-11-06 14:00:58 -07:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
2011-12-05 06:25:25 -08:00
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
2011-12-05 05:57:10 -08:00
|
|
|
# include <sys/mman.h>
|
|
|
|
#endif
|
2011-04-13 09:15:30 -07:00
|
|
|
#include <fcntl.h>
|
2009-08-23 02:18:14 -07:00
|
|
|
|
2020-08-21 04:48:32 -07:00
|
|
|
#if defined(__linux__)
|
|
|
|
# include <sys/syscall.h>
|
|
|
|
#endif
|
|
|
|
|
2019-11-20 00:43:26 -08:00
|
|
|
#ifdef HAVE_SYS_RESOURCE_H
|
|
|
|
# include <sys/resource.h>
|
|
|
|
#endif
|
|
|
|
|
2010-11-06 14:00:58 -07:00
|
|
|
#define PATH_DELIM '/'
|
2008-07-30 06:35:49 -07:00
|
|
|
|
2009-08-28 05:03:34 -07:00
|
|
|
#include "eina_config.h"
|
2008-07-30 05:46:55 -07:00
|
|
|
#include "eina_private.h"
|
2013-01-03 07:10:34 -08:00
|
|
|
#include "eina_alloca.h"
|
2009-09-06 15:21:56 -07:00
|
|
|
|
|
|
|
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
2008-12-26 10:31:14 -08:00
|
|
|
#include "eina_safety_checks.h"
|
2014-05-30 01:25:05 -07:00
|
|
|
#include "eina_cpu.h"
|
2009-08-28 05:03:34 -07:00
|
|
|
#include "eina_file.h"
|
2010-07-02 10:23:05 -07:00
|
|
|
#include "eina_stringshare.h"
|
2011-04-13 09:15:30 -07:00
|
|
|
#include "eina_hash.h"
|
|
|
|
#include "eina_list.h"
|
2011-06-06 10:08:06 -07:00
|
|
|
#include "eina_lock.h"
|
2011-07-04 02:29:59 -07:00
|
|
|
#include "eina_mmap.h"
|
2011-12-05 05:57:10 -08:00
|
|
|
#include "eina_log.h"
|
2012-01-03 07:24:15 -08:00
|
|
|
#include "eina_xattr.h"
|
2013-03-14 04:49:45 -07:00
|
|
|
#include "eina_file_common.h"
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2010-11-06 00:37:52 -07:00
|
|
|
/*============================================================================*
|
|
|
|
* Local *
|
|
|
|
*============================================================================*/
|
|
|
|
|
2011-04-13 10:03:24 -07:00
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
2013-11-10 00:26:12 -08:00
|
|
|
#define EINA_SMALL_PAGE eina_cpu_page_size()
|
2017-09-14 23:56:17 -07:00
|
|
|
|
|
|
|
// FIXME: This assumes HugeTLB size of 2Mb. How to get this information at runtime?
|
|
|
|
#define EINA_HUGE_PAGE (2 * 1024 * 1024)
|
|
|
|
#define EINA_HUGE_PAGE_MIN (8 * EINA_HUGE_PAGE)
|
2011-05-13 03:44:29 -07:00
|
|
|
|
2011-12-05 05:57:10 -08:00
|
|
|
#ifdef HAVE_DIRENT_H
|
2010-07-02 10:23:05 -07:00
|
|
|
typedef struct _Eina_File_Iterator Eina_File_Iterator;
|
|
|
|
struct _Eina_File_Iterator
|
|
|
|
{
|
|
|
|
Eina_Iterator iterator;
|
|
|
|
|
|
|
|
DIR *dirp;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
char dir[1];
|
|
|
|
};
|
2011-12-05 05:57:10 -08:00
|
|
|
#endif
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2013-03-15 00:05:05 -07:00
|
|
|
int _eina_file_log_dom = -1;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2010-11-03 03:19:55 -07:00
|
|
|
/*
|
|
|
|
* This complex piece of code is needed due to possible race condition.
|
|
|
|
* The code and description of the issue can be found at :
|
|
|
|
* http://womble.decadent.org.uk/readdir_r-advisory.html
|
|
|
|
*/
|
2011-12-05 05:57:10 -08:00
|
|
|
#ifdef HAVE_DIRENT_H
|
2011-09-18 14:56:54 -07:00
|
|
|
static long
|
2018-11-06 08:53:24 -08:00
|
|
|
_eina_name_max(DIR *dirp EINA_UNUSED)
|
2010-11-03 03:19:55 -07:00
|
|
|
{
|
|
|
|
long name_max;
|
|
|
|
|
|
|
|
#if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) && defined(_PC_NAME_MAX)
|
|
|
|
name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
|
|
|
|
|
|
|
|
if (name_max == -1)
|
|
|
|
{
|
|
|
|
# if defined(NAME_MAX)
|
|
|
|
name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
|
|
|
|
# else
|
2010-11-03 10:32:07 -07:00
|
|
|
name_max = PATH_MAX;
|
2010-11-03 03:19:55 -07:00
|
|
|
# endif
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
# if defined(NAME_MAX)
|
|
|
|
name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
|
|
|
|
# else
|
|
|
|
# ifdef _PC_NAME_MAX
|
|
|
|
# warning "buffer size for readdir_r cannot be determined safely, best effort, but racy"
|
|
|
|
name_max = pathconf(dirp, _PC_NAME_MAX);
|
|
|
|
# else
|
|
|
|
# error "buffer size for readdir_r cannot be determined safely"
|
2010-11-06 00:37:52 -07:00
|
|
|
# endif
|
2010-11-03 03:19:55 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
2011-09-18 14:56:54 -07:00
|
|
|
|
|
|
|
return name_max;
|
|
|
|
}
|
|
|
|
|
2010-07-02 10:23:05 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_eina_file_ls_iterator_next(Eina_File_Iterator *it, void **data)
|
|
|
|
{
|
|
|
|
struct dirent *dp;
|
|
|
|
char *name;
|
|
|
|
size_t length;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2016-08-25 15:20:19 -07:00
|
|
|
dp = readdir(it->dirp);
|
2010-10-28 02:59:27 -07:00
|
|
|
if (dp == NULL)
|
|
|
|
return EINA_FALSE;
|
2010-07-02 10:23:05 -07:00
|
|
|
}
|
2010-07-06 08:45:12 -07:00
|
|
|
while ((dp->d_name[0] == '.') &&
|
2010-07-27 19:37:05 -07:00
|
|
|
((dp->d_name[1] == '\0') ||
|
|
|
|
((dp->d_name[1] == '.') && (dp->d_name[2] == '\0'))));
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2010-11-02 08:11:05 -07:00
|
|
|
#ifdef _DIRENT_HAVE_D_NAMLEN
|
2010-10-29 22:48:07 -07:00
|
|
|
length = dp->d_namlen;
|
|
|
|
#else
|
2010-07-02 10:23:05 -07:00
|
|
|
length = strlen(dp->d_name);
|
2010-11-02 08:11:05 -07:00
|
|
|
#endif
|
2010-07-02 10:23:05 -07:00
|
|
|
name = alloca(length + 2 + it->length);
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
memcpy(name, it->dir, it->length);
|
|
|
|
memcpy(name + it->length, "/", 1);
|
2010-07-02 10:23:05 -07:00
|
|
|
memcpy(name + it->length + 1, dp->d_name, length + 1);
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
*data = (char *)eina_stringshare_add(name);
|
2010-07-02 10:23:05 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2010-10-25 05:25:24 -07:00
|
|
|
static DIR *
|
2010-07-02 10:23:05 -07:00
|
|
|
_eina_file_ls_iterator_container(Eina_File_Iterator *it)
|
|
|
|
{
|
2010-10-25 05:25:24 -07:00
|
|
|
return it->dirp;
|
2010-07-02 10:23:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eina_file_ls_iterator_free(Eina_File_Iterator *it)
|
|
|
|
{
|
|
|
|
closedir(it->dirp);
|
|
|
|
|
|
|
|
EINA_MAGIC_SET(&it->iterator, 0);
|
|
|
|
free(it);
|
|
|
|
}
|
2008-08-08 22:47:15 -07:00
|
|
|
|
2010-07-06 08:45:12 -07:00
|
|
|
typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
|
|
|
|
struct _Eina_File_Direct_Iterator
|
|
|
|
{
|
|
|
|
Eina_Iterator iterator;
|
|
|
|
|
|
|
|
DIR *dirp;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
Eina_File_Direct_Info info;
|
|
|
|
|
|
|
|
char dir[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eina_file_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
|
|
|
|
{
|
|
|
|
struct dirent *dp;
|
|
|
|
size_t length;
|
2010-11-02 10:07:04 -07:00
|
|
|
|
2010-07-06 08:45:12 -07:00
|
|
|
do
|
|
|
|
{
|
2016-08-25 15:20:19 -07:00
|
|
|
dp = readdir(it->dirp);
|
|
|
|
if (dp == NULL)
|
|
|
|
return EINA_FALSE;
|
2010-07-06 08:45:12 -07:00
|
|
|
|
2010-11-02 08:11:05 -07:00
|
|
|
#ifdef _DIRENT_HAVE_D_NAMLEN
|
2010-10-29 22:48:07 -07:00
|
|
|
length = dp->d_namlen;
|
|
|
|
#else
|
2010-07-27 19:37:05 -07:00
|
|
|
length = strlen(dp->d_name);
|
2010-11-02 08:11:05 -07:00
|
|
|
#endif
|
2010-12-09 02:14:11 -08:00
|
|
|
if (it->info.name_start + length + 1 >= EINA_PATH_MAX)
|
2010-07-27 19:37:05 -07:00
|
|
|
continue;
|
2010-07-06 08:45:12 -07:00
|
|
|
}
|
|
|
|
while ((dp->d_name[0] == '.') &&
|
2010-07-27 19:37:05 -07:00
|
|
|
((dp->d_name[1] == '\0') ||
|
|
|
|
((dp->d_name[1] == '.') && (dp->d_name[2] == '\0'))));
|
2010-07-06 08:45:12 -07:00
|
|
|
|
|
|
|
memcpy(it->info.path + it->info.name_start, dp->d_name, length);
|
|
|
|
it->info.name_length = length;
|
|
|
|
it->info.path_length = it->info.name_start + length;
|
|
|
|
it->info.path[it->info.path_length] = '\0';
|
2010-11-02 08:11:05 -07:00
|
|
|
|
2010-10-29 22:48:07 -07:00
|
|
|
#ifdef _DIRENT_HAVE_D_TYPE
|
|
|
|
switch (dp->d_type)
|
|
|
|
{
|
|
|
|
case DT_FIFO:
|
|
|
|
it->info.type = EINA_FILE_FIFO;
|
|
|
|
break;
|
|
|
|
case DT_CHR:
|
|
|
|
it->info.type = EINA_FILE_CHR;
|
|
|
|
break;
|
|
|
|
case DT_DIR:
|
|
|
|
it->info.type = EINA_FILE_DIR;
|
|
|
|
break;
|
|
|
|
case DT_BLK:
|
|
|
|
it->info.type = EINA_FILE_BLK;
|
|
|
|
break;
|
|
|
|
case DT_REG:
|
|
|
|
it->info.type = EINA_FILE_REG;
|
|
|
|
break;
|
|
|
|
case DT_LNK:
|
|
|
|
it->info.type = EINA_FILE_LNK;
|
|
|
|
break;
|
|
|
|
case DT_SOCK:
|
|
|
|
it->info.type = EINA_FILE_SOCK;
|
|
|
|
break;
|
|
|
|
case DT_WHT:
|
|
|
|
it->info.type = EINA_FILE_WHT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
it->info.type = EINA_FILE_UNKNOWN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#else
|
2010-11-02 10:07:04 -07:00
|
|
|
it->info.type = EINA_FILE_UNKNOWN;
|
2010-10-29 22:48:07 -07:00
|
|
|
#endif
|
2010-11-02 10:07:04 -07:00
|
|
|
|
2010-07-06 08:45:12 -07:00
|
|
|
*data = &it->info;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2010-10-25 05:25:24 -07:00
|
|
|
static DIR *
|
2010-07-06 08:45:12 -07:00
|
|
|
_eina_file_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
|
|
|
|
{
|
2010-10-25 05:25:24 -07:00
|
|
|
return it->dirp;
|
2010-07-06 08:45:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eina_file_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
|
|
|
|
{
|
|
|
|
closedir(it->dirp);
|
|
|
|
|
|
|
|
EINA_MAGIC_SET(&it->iterator, 0);
|
|
|
|
free(it);
|
|
|
|
}
|
|
|
|
|
2010-11-02 10:07:04 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
|
|
|
|
{
|
2012-02-23 03:45:25 -08:00
|
|
|
Eina_Stat st;
|
2010-11-02 10:07:04 -07:00
|
|
|
|
|
|
|
if (!_eina_file_direct_ls_iterator_next(it, data))
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
if (it->info.type == EINA_FILE_UNKNOWN)
|
|
|
|
{
|
2012-02-23 03:45:25 -08:00
|
|
|
if (eina_file_statat(it->dirp, &it->info, &st) != 0)
|
2010-11-02 10:07:04 -07:00
|
|
|
it->info.type = EINA_FILE_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2011-12-05 05:57:10 -08:00
|
|
|
#endif
|
2010-11-02 10:07:04 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
void
|
|
|
|
eina_file_real_close(Eina_File *file)
|
2011-04-13 09:15:30 -07:00
|
|
|
{
|
2013-07-31 01:16:20 -07:00
|
|
|
Eina_File_Map *map;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(file->dead_map, map)
|
|
|
|
{
|
|
|
|
munmap(map->map, map->length);
|
|
|
|
free(map);
|
|
|
|
}
|
|
|
|
|
2017-08-02 12:37:10 -07:00
|
|
|
if (file->fd != -1)
|
|
|
|
{
|
2017-11-30 05:57:25 -08:00
|
|
|
if (!file->copied && file->global_map != MAP_FAILED)
|
2017-08-02 12:37:10 -07:00
|
|
|
munmap(file->global_map, file->length);
|
|
|
|
close(file->fd);
|
|
|
|
}
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eina_file_map_close(Eina_File_Map *map)
|
|
|
|
{
|
|
|
|
munmap(map->map, map->length);
|
|
|
|
free(map);
|
|
|
|
}
|
|
|
|
|
2011-05-13 03:44:29 -07:00
|
|
|
#ifndef MAP_POPULATE
|
2011-11-14 14:08:02 -08:00
|
|
|
static unsigned int
|
2016-09-20 05:57:47 -07:00
|
|
|
_eina_file_map_populate(char *map, unsigned long int size, Eina_Bool hugetlb)
|
2011-05-13 03:44:29 -07:00
|
|
|
{
|
2011-11-14 14:08:02 -08:00
|
|
|
unsigned int r = 0xDEADBEEF;
|
2016-09-20 05:57:47 -07:00
|
|
|
unsigned long int i;
|
2011-11-14 14:08:02 -08:00
|
|
|
unsigned int s;
|
2011-05-13 03:44:29 -07:00
|
|
|
|
2016-09-19 14:02:43 -07:00
|
|
|
if (size == 0) return 0;
|
|
|
|
|
2011-10-19 09:09:14 -07:00
|
|
|
s = hugetlb ? EINA_HUGE_PAGE : EINA_SMALL_PAGE;
|
2011-05-13 03:44:29 -07:00
|
|
|
|
|
|
|
for (i = 0; i < size; i += s)
|
|
|
|
r ^= map[i];
|
|
|
|
|
2016-09-19 14:02:43 -07:00
|
|
|
r ^= map[size - 1];
|
2011-05-13 03:44:29 -07:00
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-09-14 23:56:17 -07:00
|
|
|
static char *
|
|
|
|
_page_aligned_address(const char *map, unsigned long int offset, Eina_Bool hugetlb)
|
|
|
|
{
|
|
|
|
const uintptr_t align = hugetlb ? EINA_HUGE_PAGE : EINA_SMALL_PAGE;
|
|
|
|
uintptr_t pmap = (uintptr_t) map;
|
|
|
|
|
|
|
|
pmap = (pmap + offset) - ((pmap + offset) & (align - 1));
|
|
|
|
|
|
|
|
return (char *) pmap;
|
|
|
|
}
|
|
|
|
|
2011-05-13 03:44:29 -07:00
|
|
|
static int
|
2017-09-14 23:56:17 -07:00
|
|
|
_eina_file_map_rule_apply(Eina_File_Populate rule, const void *map, unsigned long int offset,
|
|
|
|
unsigned long int size, unsigned long long maplen, Eina_Bool hugetlb)
|
2011-04-13 09:15:30 -07:00
|
|
|
{
|
2011-05-13 03:44:29 -07:00
|
|
|
int tmp = 42;
|
|
|
|
int flag = MADV_RANDOM;
|
2017-09-14 23:56:17 -07:00
|
|
|
char *addr;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
|
|
|
switch (rule)
|
|
|
|
{
|
|
|
|
case EINA_FILE_RANDOM: flag = MADV_RANDOM; break;
|
|
|
|
case EINA_FILE_SEQUENTIAL: flag = MADV_SEQUENTIAL; break;
|
2011-05-13 03:44:29 -07:00
|
|
|
case EINA_FILE_POPULATE: flag = MADV_WILLNEED; break;
|
|
|
|
case EINA_FILE_WILLNEED: flag = MADV_WILLNEED; break;
|
2013-07-06 06:01:23 -07:00
|
|
|
case EINA_FILE_DONTNEED: flag = MADV_DONTNEED; break;
|
2013-08-06 00:13:03 -07:00
|
|
|
#ifdef MADV_REMOVE
|
2013-07-06 06:01:23 -07:00
|
|
|
case EINA_FILE_REMOVE: flag = MADV_REMOVE; break;
|
2013-08-06 00:13:03 -07:00
|
|
|
#elif defined (MADV_FREE)
|
|
|
|
case EINA_FILE_REMOVE: flag = MADV_FREE; break;
|
|
|
|
#else
|
|
|
|
# warning "EINA_FILE_REMOVE does not have system support"
|
2020-06-20 02:48:52 -07:00
|
|
|
#endif
|
2013-07-06 06:01:23 -07:00
|
|
|
default: return tmp; break;
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
2017-09-14 23:56:17 -07:00
|
|
|
if (offset >= maplen) return tmp;
|
|
|
|
|
|
|
|
// Align address, clamp size
|
|
|
|
addr = _page_aligned_address(map, offset, hugetlb);
|
|
|
|
if (size > 0)
|
|
|
|
{
|
|
|
|
size += ((char *) map + offset) - addr;
|
|
|
|
offset -= ((char *) map + offset) - addr;
|
|
|
|
if ((offset + size) > maplen)
|
|
|
|
{
|
|
|
|
if (offset > maplen) return tmp;
|
|
|
|
size = maplen - offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
madvise(addr, size, flag);
|
2011-05-13 03:44:29 -07:00
|
|
|
|
|
|
|
#ifndef MAP_POPULATE
|
|
|
|
if (rule == EINA_FILE_POPULATE)
|
2011-10-19 09:09:14 -07:00
|
|
|
tmp ^= _eina_file_map_populate(addr, size, hugetlb);
|
|
|
|
#else
|
|
|
|
(void) hugetlb;
|
2011-05-13 03:44:29 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return tmp;
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
2011-10-03 19:04:40 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_eina_file_timestamp_compare(Eina_File *f, struct stat *st)
|
|
|
|
{
|
|
|
|
if (f->mtime != st->st_mtime) return EINA_FALSE;
|
|
|
|
if (f->length != (unsigned long long) st->st_size) return EINA_FALSE;
|
|
|
|
if (f->inode != st->st_ino) return EINA_FALSE;
|
|
|
|
#ifdef _STAT_VER_LINUX
|
|
|
|
# if (defined __USE_MISC && defined st_mtime)
|
|
|
|
if (f->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec)
|
|
|
|
return EINA_FALSE;
|
|
|
|
# else
|
|
|
|
if (f->mtime_nsec != (unsigned long int)st->st_mtimensec)
|
|
|
|
return EINA_FALSE;
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-10-03 19:33:45 -07:00
|
|
|
static void
|
|
|
|
slprintf(char *str, size_t size, const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, format);
|
|
|
|
|
|
|
|
vsnprintf(str, size, format, ap);
|
|
|
|
str[size - 1] = 0;
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
2012-01-21 00:23:23 -08:00
|
|
|
/**
|
|
|
|
* @endcond
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*============================================================================*
|
|
|
|
* Global *
|
|
|
|
*============================================================================*/
|
|
|
|
|
2013-07-31 01:16:20 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_eina_file_mmap_faulty_one(void *addr, long page_size,
|
|
|
|
Eina_File_Map *m)
|
|
|
|
{
|
|
|
|
if ((unsigned char *) addr < (((unsigned char *)m->map) + m->length) &&
|
|
|
|
(((unsigned char *) addr) + page_size) >= (unsigned char *) m->map)
|
|
|
|
{
|
|
|
|
m->faulty = EINA_TRUE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2017-08-29 20:03:41 -07:00
|
|
|
Eina_Bool
|
2012-03-07 00:58:55 -08:00
|
|
|
eina_file_mmap_faulty(void *addr, long page_size)
|
|
|
|
{
|
|
|
|
Eina_File_Map *m;
|
|
|
|
Eina_File *f;
|
|
|
|
Eina_Iterator *itf;
|
|
|
|
Eina_Iterator *itm;
|
2017-08-29 20:03:41 -07:00
|
|
|
Eina_Bool faulty = EINA_FALSE;
|
2012-03-07 00:58:55 -08:00
|
|
|
|
|
|
|
eina_lock_take(&_eina_file_lock_cache);
|
|
|
|
|
|
|
|
itf = eina_hash_iterator_data_new(_eina_file_cache);
|
|
|
|
EINA_ITERATOR_FOREACH(itf, f)
|
|
|
|
{
|
|
|
|
eina_lock_take(&f->lock);
|
|
|
|
|
2013-08-22 05:13:38 -07:00
|
|
|
if (f->global_map != MAP_FAILED)
|
2012-03-07 00:58:55 -08:00
|
|
|
{
|
2017-08-29 20:03:41 -07:00
|
|
|
if ((unsigned char *)addr <
|
|
|
|
(((unsigned char *)f->global_map) + f->length) &&
|
|
|
|
(((unsigned char *)addr) + page_size) >=
|
|
|
|
(unsigned char *)f->global_map)
|
2012-03-07 00:58:55 -08:00
|
|
|
{
|
|
|
|
f->global_faulty = EINA_TRUE;
|
|
|
|
faulty = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!faulty)
|
|
|
|
{
|
|
|
|
itm = eina_hash_iterator_data_new(f->map);
|
|
|
|
EINA_ITERATOR_FOREACH(itm, m)
|
|
|
|
{
|
2013-07-31 01:16:20 -07:00
|
|
|
faulty = _eina_file_mmap_faulty_one(addr, page_size, m);
|
|
|
|
if (faulty) break;
|
2012-03-07 00:58:55 -08:00
|
|
|
}
|
|
|
|
eina_iterator_free(itm);
|
|
|
|
}
|
|
|
|
|
2013-07-31 01:16:20 -07:00
|
|
|
if (!faulty)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(f->dead_map, l, m)
|
|
|
|
{
|
|
|
|
faulty = _eina_file_mmap_faulty_one(addr, page_size, m);
|
|
|
|
if (faulty) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-07 00:58:55 -08:00
|
|
|
eina_lock_release(&f->lock);
|
|
|
|
|
|
|
|
if (faulty) break;
|
|
|
|
}
|
|
|
|
eina_iterator_free(itf);
|
|
|
|
|
|
|
|
eina_lock_release(&_eina_file_lock_cache);
|
2017-08-29 20:03:41 -07:00
|
|
|
return faulty;
|
2012-03-07 00:58:55 -08:00
|
|
|
}
|
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
/* ================================================================ *
|
|
|
|
* Simplified logic for portability layer with eina_file_common *
|
2020-06-20 02:48:52 -07:00
|
|
|
* ================================================================ */
|
2008-08-08 22:47:15 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
Eina_Bool
|
|
|
|
eina_file_path_relative(const char *path)
|
2011-10-03 19:33:45 -07:00
|
|
|
{
|
2013-03-14 04:49:45 -07:00
|
|
|
if (*path != '/') return EINA_TRUE;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
Eina_Tmpstr *
|
|
|
|
eina_file_current_directory_get(const char *path, size_t len)
|
|
|
|
{
|
|
|
|
char cwd[PATH_MAX];
|
|
|
|
char *tmp = NULL;
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
tmp = getcwd(cwd, PATH_MAX);
|
|
|
|
if (!tmp) return NULL;
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
len += strlen(cwd) + 2;
|
|
|
|
tmp = alloca(sizeof (char) * len);
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
slprintf(tmp, len, "%s/%s", cwd, path);
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
return eina_tmpstr_add_length(tmp, len);
|
|
|
|
}
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
char *
|
|
|
|
eina_file_cleanup(Eina_Tmpstr *path)
|
|
|
|
{
|
|
|
|
char *result;
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
result = strdup(path ? path : "");
|
|
|
|
eina_tmpstr_del(path);
|
2011-10-03 19:33:45 -07:00
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
return result;
|
2011-10-03 19:33:45 -07:00
|
|
|
}
|
|
|
|
|
2013-03-14 04:49:45 -07:00
|
|
|
/*============================================================================*
|
|
|
|
* API *
|
|
|
|
*============================================================================*/
|
|
|
|
|
|
|
|
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Bool
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_file_dir_list(const char *dir,
|
|
|
|
Eina_Bool recursive,
|
|
|
|
Eina_File_Dir_List_Cb cb,
|
|
|
|
void *data)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2011-03-22 09:33:34 -07:00
|
|
|
Eina_File_Direct_Info *info;
|
|
|
|
Eina_Iterator *it;
|
2010-11-06 00:37:52 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE);
|
2009-01-23 08:43:14 -08:00
|
|
|
|
2011-03-22 09:33:34 -07:00
|
|
|
it = eina_file_stat_ls(dir);
|
|
|
|
if (!it)
|
2010-07-27 19:37:05 -07:00
|
|
|
return EINA_FALSE;
|
2008-07-30 05:46:55 -07:00
|
|
|
|
2011-03-22 09:33:34 -07:00
|
|
|
EINA_ITERATOR_FOREACH(it, info)
|
2010-07-27 19:37:05 -07:00
|
|
|
{
|
2011-03-22 09:33:34 -07:00
|
|
|
cb(info->path + info->name_start, dir, data);
|
2008-08-18 01:18:16 -07:00
|
|
|
|
2011-03-22 09:33:34 -07:00
|
|
|
if (recursive == EINA_TRUE && info->type == EINA_FILE_DIR)
|
2010-07-27 19:37:05 -07:00
|
|
|
{
|
2011-03-22 09:33:34 -07:00
|
|
|
eina_file_dir_list(info->path, recursive, cb, data);
|
2010-07-27 19:37:05 -07:00
|
|
|
}
|
|
|
|
}
|
2008-08-18 01:18:16 -07:00
|
|
|
|
2011-03-22 09:33:34 -07:00
|
|
|
eina_iterator_free(it);
|
2008-07-30 05:46:55 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
return EINA_TRUE;
|
2008-08-18 01:18:16 -07:00
|
|
|
}
|
2008-09-01 05:51:50 -07:00
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Array *
|
2008-09-03 07:40:12 -07:00
|
|
|
eina_file_split(char *path)
|
2008-09-01 05:51:50 -07:00
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
Eina_Array *ea;
|
|
|
|
char *current;
|
|
|
|
size_t length;
|
2008-09-03 07:40:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
|
2008-09-03 07:40:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
ea = eina_array_new(16);
|
2008-09-03 07:40:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
if (!ea)
|
|
|
|
return NULL;
|
2008-09-01 05:51:50 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
for (current = strchr(path, PATH_DELIM);
|
2010-08-21 06:52:25 -07:00
|
|
|
current;
|
2010-07-27 19:37:05 -07:00
|
|
|
path = current + 1, current = strchr(path, PATH_DELIM))
|
|
|
|
{
|
|
|
|
length = current - path;
|
2008-09-01 05:51:50 -07:00
|
|
|
|
2017-10-09 16:37:47 -07:00
|
|
|
if (length == 0)
|
2010-07-27 19:37:05 -07:00
|
|
|
continue;
|
2008-09-03 07:40:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_array_push(ea, path);
|
|
|
|
*current = '\0';
|
|
|
|
}
|
2008-09-01 05:51:50 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
if (*path != '\0')
|
|
|
|
eina_array_push(ea, path);
|
2008-09-03 07:40:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
return ea;
|
2008-09-03 07:40:12 -07:00
|
|
|
}
|
2008-09-18 22:22:43 -07:00
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Iterator *
|
2010-07-02 10:23:05 -07:00
|
|
|
eina_file_ls(const char *dir)
|
|
|
|
{
|
2011-12-05 05:57:10 -08:00
|
|
|
#ifdef HAVE_DIRENT_H
|
2010-07-02 10:23:05 -07:00
|
|
|
Eina_File_Iterator *it;
|
|
|
|
size_t length;
|
2012-10-19 02:03:14 -07:00
|
|
|
DIR *dirp;
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2011-09-15 06:57:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
|
2010-07-02 10:23:05 -07:00
|
|
|
|
|
|
|
length = strlen(dir);
|
2010-07-27 19:37:05 -07:00
|
|
|
if (length < 1)
|
|
|
|
return NULL;
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2012-10-19 02:03:14 -07:00
|
|
|
dirp = opendir(dir);
|
|
|
|
if (!dirp)
|
2010-07-27 19:37:05 -07:00
|
|
|
return NULL;
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2012-10-19 02:03:14 -07:00
|
|
|
it = calloc(1, sizeof (Eina_File_Iterator) + length);
|
|
|
|
if (EINA_UNLIKELY(!it))
|
2010-07-02 10:23:05 -07:00
|
|
|
{
|
2012-10-19 02:03:14 -07:00
|
|
|
closedir(dirp);
|
2010-07-27 19:37:05 -07:00
|
|
|
return NULL;
|
2010-07-02 10:23:05 -07:00
|
|
|
}
|
|
|
|
|
2012-10-19 02:03:14 -07:00
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
|
|
|
|
|
|
it->dirp = dirp;
|
|
|
|
|
2010-07-02 10:23:05 -07:00
|
|
|
memcpy(it->dir, dir, length + 1);
|
2010-07-06 08:45:12 -07:00
|
|
|
if (dir[length - 1] != '/')
|
2010-07-27 19:37:05 -07:00
|
|
|
it->length = length;
|
2010-07-06 08:45:12 -07:00
|
|
|
else
|
2010-07-27 19:37:05 -07:00
|
|
|
it->length = length - 1;
|
2010-07-02 10:23:05 -07:00
|
|
|
|
2010-08-19 05:02:28 -07:00
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
2010-07-02 10:23:05 -07:00
|
|
|
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_ls_iterator_next);
|
2010-07-27 19:37:05 -07:00
|
|
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
|
|
|
_eina_file_ls_iterator_container);
|
2010-07-02 10:23:05 -07:00
|
|
|
it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free);
|
|
|
|
|
|
|
|
return &it->iterator;
|
2011-12-05 05:57:10 -08:00
|
|
|
#else
|
|
|
|
(void) dir;
|
|
|
|
return NULL;
|
|
|
|
#endif
|
2010-07-02 10:23:05 -07:00
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Iterator *
|
2010-07-06 08:45:12 -07:00
|
|
|
eina_file_direct_ls(const char *dir)
|
|
|
|
{
|
2011-12-05 05:57:10 -08:00
|
|
|
#ifdef HAVE_DIRENT_H
|
2010-07-06 08:45:12 -07:00
|
|
|
Eina_File_Direct_Iterator *it;
|
|
|
|
size_t length;
|
2012-10-19 02:03:14 -07:00
|
|
|
DIR *dirp;
|
2010-07-06 08:45:12 -07:00
|
|
|
|
2011-09-15 06:57:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
|
2010-07-06 08:45:12 -07:00
|
|
|
|
|
|
|
length = strlen(dir);
|
2010-07-27 19:37:05 -07:00
|
|
|
if (length < 1)
|
|
|
|
return NULL;
|
|
|
|
|
2012-10-19 02:03:14 -07:00
|
|
|
dirp = opendir(dir);
|
|
|
|
if (!dirp)
|
2010-07-27 19:37:05 -07:00
|
|
|
return NULL;
|
2010-07-06 08:45:12 -07:00
|
|
|
|
2012-10-19 02:03:14 -07:00
|
|
|
it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length);
|
|
|
|
if (EINA_UNLIKELY(!it))
|
2010-07-06 08:45:12 -07:00
|
|
|
{
|
2012-10-19 02:03:14 -07:00
|
|
|
closedir(dirp);
|
2010-07-27 19:37:05 -07:00
|
|
|
return NULL;
|
2010-07-06 08:45:12 -07:00
|
|
|
}
|
|
|
|
|
2012-10-19 02:03:14 -07:00
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
|
|
|
|
|
|
it->dirp = dirp;
|
|
|
|
|
2011-09-18 14:56:54 -07:00
|
|
|
if (length + _eina_name_max(it->dirp) + 2 >= EINA_PATH_MAX)
|
|
|
|
{
|
|
|
|
_eina_file_direct_ls_iterator_free(it);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
memcpy(it->dir, dir, length + 1);
|
2010-07-06 08:45:12 -07:00
|
|
|
it->length = length;
|
|
|
|
|
|
|
|
memcpy(it->info.path, dir, length);
|
|
|
|
if (dir[length - 1] == '/')
|
2010-07-27 19:37:05 -07:00
|
|
|
it->info.name_start = length;
|
2010-07-06 08:45:12 -07:00
|
|
|
else
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
it->info.path[length] = '/';
|
|
|
|
it->info.name_start = length + 1;
|
2010-07-06 08:45:12 -07:00
|
|
|
}
|
|
|
|
|
2010-08-19 05:02:28 -07:00
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
2010-07-06 08:45:12 -07:00
|
|
|
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_direct_ls_iterator_next);
|
2010-07-27 19:37:05 -07:00
|
|
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
|
|
|
_eina_file_direct_ls_iterator_container);
|
2010-07-06 08:45:12 -07:00
|
|
|
it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free);
|
|
|
|
|
|
|
|
return &it->iterator;
|
2011-12-05 05:57:10 -08:00
|
|
|
#else
|
|
|
|
(void) dir;
|
|
|
|
return NULL;
|
|
|
|
#endif
|
2010-07-06 08:45:12 -07:00
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Iterator *
|
2010-11-02 10:07:04 -07:00
|
|
|
eina_file_stat_ls(const char *dir)
|
|
|
|
{
|
2011-12-05 05:57:10 -08:00
|
|
|
#ifdef HAVE_DIRENT_H
|
2010-11-02 10:07:04 -07:00
|
|
|
Eina_File_Direct_Iterator *it;
|
|
|
|
size_t length;
|
2012-10-18 02:12:14 -07:00
|
|
|
DIR *dirp;
|
2010-11-02 10:07:04 -07:00
|
|
|
|
2011-09-15 06:57:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
|
2010-11-02 10:07:04 -07:00
|
|
|
|
|
|
|
length = strlen(dir);
|
|
|
|
if (length < 1)
|
|
|
|
return NULL;
|
|
|
|
|
2012-10-18 02:12:14 -07:00
|
|
|
dirp = opendir(dir);
|
|
|
|
if (!dirp)
|
|
|
|
return NULL;
|
|
|
|
|
2010-11-02 10:07:04 -07:00
|
|
|
it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length);
|
2012-10-19 02:03:14 -07:00
|
|
|
if (EINA_UNLIKELY(!it))
|
2012-10-19 01:18:59 -07:00
|
|
|
{
|
|
|
|
closedir(dirp);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-11-02 10:07:04 -07:00
|
|
|
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
|
|
|
2012-10-18 02:12:14 -07:00
|
|
|
it->dirp = dirp;
|
2010-11-02 10:07:04 -07:00
|
|
|
|
2011-09-18 14:56:54 -07:00
|
|
|
if (length + _eina_name_max(it->dirp) + 2 >= EINA_PATH_MAX)
|
|
|
|
{
|
|
|
|
_eina_file_direct_ls_iterator_free(it);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-11-02 10:07:04 -07:00
|
|
|
memcpy(it->dir, dir, length + 1);
|
|
|
|
it->length = length;
|
|
|
|
|
|
|
|
memcpy(it->info.path, dir, length);
|
|
|
|
if (dir[length - 1] == '/')
|
|
|
|
it->info.name_start = length;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
it->info.path[length] = '/';
|
|
|
|
it->info.name_start = length + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
|
|
|
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_stat_ls_iterator_next);
|
|
|
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
|
|
|
_eina_file_direct_ls_iterator_container);
|
|
|
|
it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free);
|
|
|
|
|
|
|
|
return &it->iterator;
|
2011-12-05 05:57:10 -08:00
|
|
|
#else
|
|
|
|
(void) dir;
|
|
|
|
return NULL;
|
|
|
|
#endif
|
2010-11-02 10:07:04 -07:00
|
|
|
}
|
2011-04-13 09:15:30 -07:00
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_File *
|
2011-10-03 19:33:45 -07:00
|
|
|
eina_file_open(const char *path, Eina_Bool shared)
|
2011-04-13 09:15:30 -07:00
|
|
|
{
|
|
|
|
Eina_File *file;
|
|
|
|
Eina_File *n;
|
2017-10-17 16:14:26 -07:00
|
|
|
Eina_Stringshare *filename;
|
2011-04-13 09:15:30 -07:00
|
|
|
struct stat file_stat;
|
2011-10-03 19:33:45 -07:00
|
|
|
int fd = -1;
|
2019-07-28 03:51:15 -07:00
|
|
|
Eina_Statgen statgen;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2011-10-03 19:33:45 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
|
2011-09-15 06:57:27 -07:00
|
|
|
|
2017-10-17 16:14:26 -07:00
|
|
|
filename = eina_file_sanitize(path);
|
2011-10-03 19:33:45 -07:00
|
|
|
if (!filename) return NULL;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2019-07-28 03:51:15 -07:00
|
|
|
statgen = eina_file_statgen_get();
|
|
|
|
eina_lock_take(&_eina_file_lock_cache);
|
|
|
|
file = eina_hash_find(_eina_file_cache, filename);
|
|
|
|
statgen = eina_file_statgen_get();
|
|
|
|
if ((!file) || (file->statgen != statgen) || (statgen == 0))
|
2019-07-26 02:15:47 -07:00
|
|
|
{
|
2019-07-28 03:51:15 -07:00
|
|
|
if (shared)
|
|
|
|
{
|
2012-03-25 04:12:32 -07:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
2019-07-28 03:51:15 -07:00
|
|
|
fd = shm_open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
|
|
if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE)))
|
|
|
|
goto on_error;
|
2011-07-13 01:51:19 -07:00
|
|
|
#else
|
2019-07-28 03:51:15 -07:00
|
|
|
goto on_error;
|
2011-07-13 01:51:19 -07:00
|
|
|
#endif
|
2019-07-28 03:51:15 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-26 02:15:47 -07:00
|
|
|
#ifdef HAVE_OPEN_CLOEXEC
|
2019-07-28 03:51:15 -07:00
|
|
|
fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO | O_CLOEXEC);
|
2019-07-26 02:15:47 -07:00
|
|
|
#else
|
2019-07-28 03:51:15 -07:00
|
|
|
fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
|
|
if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE)))
|
|
|
|
goto on_error;
|
2019-07-26 02:15:47 -07:00
|
|
|
#endif
|
2019-07-28 03:51:15 -07:00
|
|
|
}
|
|
|
|
if (fd < 0) goto on_error;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2019-07-28 03:51:15 -07:00
|
|
|
if (fstat(fd, &file_stat))
|
|
|
|
goto on_error;
|
|
|
|
if (file) file->statgen = statgen;
|
2011-06-06 10:08:06 -07:00
|
|
|
|
2019-07-28 03:51:15 -07:00
|
|
|
if ((file) && !_eina_file_timestamp_compare(file, &file_stat))
|
|
|
|
{
|
|
|
|
file->delete_me = EINA_TRUE;
|
|
|
|
eina_hash_del(_eina_file_cache, file->filename, file);
|
|
|
|
file = NULL;
|
|
|
|
}
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
2011-06-22 05:47:12 -07:00
|
|
|
if (!file)
|
2011-04-13 09:15:30 -07:00
|
|
|
{
|
2017-10-17 16:14:26 -07:00
|
|
|
n = malloc(sizeof(Eina_File));
|
2011-10-03 18:55:41 -07:00
|
|
|
if (!n)
|
2019-08-10 15:27:24 -07:00
|
|
|
goto on_error;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2012-05-22 21:26:24 -07:00
|
|
|
memset(n, 0, sizeof(Eina_File));
|
2017-10-17 16:14:26 -07:00
|
|
|
n->filename = filename;
|
2013-07-30 19:51:51 -07:00
|
|
|
n->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
|
|
|
|
EINA_KEY_CMP(eina_file_map_key_cmp),
|
|
|
|
EINA_KEY_HASH(eina_file_map_key_hash),
|
2011-04-13 09:15:30 -07:00
|
|
|
EINA_FREE_CB(_eina_file_map_close),
|
|
|
|
3);
|
|
|
|
n->rmap = eina_hash_pointer_new(NULL);
|
|
|
|
n->global_map = MAP_FAILED;
|
|
|
|
n->length = file_stat.st_size;
|
|
|
|
n->mtime = file_stat.st_mtime;
|
2011-10-05 13:00:29 -07:00
|
|
|
#ifdef _STAT_VER_LINUX
|
|
|
|
# if (defined __USE_MISC && defined st_mtime)
|
|
|
|
n->mtime_nsec = (unsigned long int)file_stat.st_mtim.tv_nsec;
|
|
|
|
# else
|
|
|
|
n->mtime_nsec = (unsigned long int)file_stat.st_mtimensec;
|
|
|
|
# endif
|
|
|
|
#endif
|
2011-05-17 09:17:28 -07:00
|
|
|
n->inode = file_stat.st_ino;
|
2011-04-13 09:15:30 -07:00
|
|
|
n->fd = fd;
|
|
|
|
n->shared = shared;
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_new(&n->lock);
|
2011-05-17 09:17:28 -07:00
|
|
|
eina_hash_direct_add(_eina_file_cache, n->filename, n);
|
2013-11-20 03:06:50 -08:00
|
|
|
|
|
|
|
EINA_MAGIC_SET(n, EINA_FILE_MAGIC);
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-28 03:51:15 -07:00
|
|
|
if (fd >= 0) close(fd);
|
2011-04-13 09:15:30 -07:00
|
|
|
n = file;
|
|
|
|
}
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_take(&n->lock);
|
2011-04-13 09:15:30 -07:00
|
|
|
n->refcount++;
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_release(&n->lock);
|
|
|
|
|
|
|
|
eina_lock_release(&_eina_file_lock_cache);
|
2011-04-13 09:15:30 -07:00
|
|
|
|
|
|
|
return n;
|
|
|
|
|
|
|
|
on_error:
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_lock_release(&_eina_file_lock_cache);
|
2019-05-29 06:16:30 -07:00
|
|
|
INF("Could not open file [%s].", filename);
|
2017-10-17 16:14:26 -07:00
|
|
|
eina_stringshare_del(filename);
|
2014-02-21 00:13:09 -08:00
|
|
|
|
2011-10-03 19:33:45 -07:00
|
|
|
if (fd >= 0) close(fd);
|
2011-04-13 09:15:30 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Bool
|
2013-07-31 01:16:20 -07:00
|
|
|
eina_file_refresh(Eina_File *file)
|
|
|
|
{
|
|
|
|
struct stat file_stat;
|
|
|
|
Eina_Bool r = EINA_FALSE;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
|
|
|
|
|
|
|
|
if (file->virtual) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (fstat(file->fd, &file_stat))
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
if (file->length != (unsigned long int) file_stat.st_size)
|
|
|
|
{
|
|
|
|
eina_file_flush(file, file_stat.st_size);
|
|
|
|
r = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
file->length = file_stat.st_size;
|
|
|
|
file->mtime = file_stat.st_mtime;
|
|
|
|
#ifdef _STAT_VER_LINUX
|
|
|
|
# if (defined __USE_MISC && defined st_mtime)
|
|
|
|
file->mtime_nsec = (unsigned long int)file_stat.st_mtim.tv_nsec;
|
|
|
|
# else
|
|
|
|
file->mtime_nsec = (unsigned long int)file_stat.st_mtimensec;
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
file->inode = file_stat.st_ino;
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Bool
|
eina_file: add eina_file_unlink
Test Plan: split D4423 - unlink
Reviewers: raster, vtorri, an.kroitor, jpeg, reutskiy.v.v, NikaWhite, cedric
Reviewed By: cedric
Subscribers: artem.popov, cedric, vtorri, jpeg
Tags: #windows, #efl
Differential Revision: https://phab.enlightenment.org/D4485
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
2017-02-07 14:50:32 -08:00
|
|
|
eina_file_unlink(const char *pathname)
|
|
|
|
{
|
|
|
|
if ( unlink(pathname) < 0)
|
|
|
|
{
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API void *
|
2011-04-13 09:15:30 -07:00
|
|
|
eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
|
|
|
|
{
|
|
|
|
int flags = MAP_SHARED;
|
2011-06-06 10:08:06 -07:00
|
|
|
void *ret = NULL;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2011-09-15 06:57:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
|
2013-07-30 19:51:51 -07:00
|
|
|
if (file->virtual) return eina_file_virtual_map_all(file);
|
|
|
|
|
|
|
|
// bsd people will lack this feature
|
2011-05-13 03:44:29 -07:00
|
|
|
#ifdef MAP_POPULATE
|
2011-04-13 09:15:30 -07:00
|
|
|
if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
|
2011-04-21 04:54:16 -07:00
|
|
|
#endif
|
2011-05-13 03:44:29 -07:00
|
|
|
#ifdef MAP_HUGETLB
|
2017-09-14 23:56:17 -07:00
|
|
|
if (file->length >= EINA_HUGE_PAGE_MIN) flags |= MAP_HUGETLB;
|
2011-05-13 03:44:29 -07:00
|
|
|
#endif
|
|
|
|
|
2011-07-04 02:29:59 -07:00
|
|
|
eina_mmap_safety_enabled_set(EINA_TRUE);
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_take(&file->lock);
|
2011-04-13 09:15:30 -07:00
|
|
|
if (file->global_map == MAP_FAILED)
|
|
|
|
file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0);
|
2011-10-19 09:09:14 -07:00
|
|
|
#ifdef MAP_HUGETLB
|
|
|
|
if ((file->global_map == MAP_FAILED) && (flags & MAP_HUGETLB))
|
|
|
|
{
|
|
|
|
flags &= ~MAP_HUGETLB;
|
|
|
|
file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0);
|
|
|
|
}
|
|
|
|
#endif
|
2011-04-13 09:15:30 -07:00
|
|
|
|
|
|
|
if (file->global_map != MAP_FAILED)
|
|
|
|
{
|
2011-10-19 09:09:14 -07:00
|
|
|
Eina_Bool hugetlb = EINA_FALSE;
|
|
|
|
|
|
|
|
#ifdef MAP_HUGETLB
|
|
|
|
hugetlb = !!(flags & MAP_HUGETLB);
|
|
|
|
#endif
|
2017-09-14 22:38:29 -07:00
|
|
|
if (!file->global_refcount)
|
|
|
|
file->global_hugetlb = hugetlb;
|
|
|
|
else
|
|
|
|
hugetlb = file->global_hugetlb;
|
|
|
|
|
2017-09-14 23:56:17 -07:00
|
|
|
_eina_file_map_rule_apply(rule, file->global_map, 0, file->length, file->length, hugetlb);
|
2011-04-13 09:15:30 -07:00
|
|
|
file->global_refcount++;
|
2011-06-06 10:08:06 -07:00
|
|
|
ret = file->global_map;
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
2011-06-06 10:08:06 -07:00
|
|
|
|
|
|
|
eina_lock_release(&file->lock);
|
|
|
|
return ret;
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API void *
|
2011-04-13 09:15:30 -07:00
|
|
|
eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
|
|
|
unsigned long int offset, unsigned long int length)
|
|
|
|
{
|
|
|
|
Eina_File_Map *map;
|
|
|
|
unsigned long int key[2];
|
|
|
|
|
2011-08-10 15:42:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
if (offset > file->length)
|
|
|
|
return NULL;
|
|
|
|
if (offset + length > file->length)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (offset == 0 && length == file->length)
|
|
|
|
return eina_file_map_all(file, rule);
|
|
|
|
|
2013-07-30 19:51:51 -07:00
|
|
|
if (file->virtual)
|
|
|
|
return eina_file_virtual_map_new(file, offset, length);
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
key[0] = offset;
|
|
|
|
key[1] = length;
|
|
|
|
|
2011-07-04 02:29:59 -07:00
|
|
|
eina_mmap_safety_enabled_set(EINA_TRUE);
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_take(&file->lock);
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
map = eina_hash_find(file->map, &key);
|
|
|
|
if (!map)
|
|
|
|
{
|
|
|
|
int flags = MAP_SHARED;
|
|
|
|
|
2011-04-21 04:54:16 -07:00
|
|
|
// bsd people will lack this feature
|
2011-05-13 03:44:29 -07:00
|
|
|
#ifdef MAP_POPULATE
|
2011-04-13 09:15:30 -07:00
|
|
|
if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
|
2011-04-21 04:54:16 -07:00
|
|
|
#endif
|
2011-05-13 03:44:29 -07:00
|
|
|
#ifdef MAP_HUGETLB
|
2017-09-14 23:56:17 -07:00
|
|
|
if (length >= EINA_HUGE_PAGE_MIN) flags |= MAP_HUGETLB;
|
2011-05-13 03:44:29 -07:00
|
|
|
#endif
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
map = malloc(sizeof (Eina_File_Map));
|
2011-06-06 10:08:06 -07:00
|
|
|
if (!map) goto on_error;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
|
|
|
map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset);
|
2011-10-19 09:09:14 -07:00
|
|
|
#ifdef MAP_HUGETLB
|
|
|
|
if (map->map == MAP_FAILED && (flags & MAP_HUGETLB))
|
|
|
|
{
|
|
|
|
flags &= ~MAP_HUGETLB;
|
|
|
|
map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
map->hugetlb = !!(flags & MAP_HUGETLB);
|
|
|
|
#else
|
|
|
|
map->hugetlb = EINA_FALSE;
|
|
|
|
#endif
|
2011-04-13 09:15:30 -07:00
|
|
|
map->offset = offset;
|
|
|
|
map->length = length;
|
|
|
|
map->refcount = 0;
|
|
|
|
|
2011-06-06 10:08:06 -07:00
|
|
|
if (map->map == MAP_FAILED) goto on_error;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
|
|
|
eina_hash_add(file->map, &key, map);
|
2013-02-06 01:28:00 -08:00
|
|
|
eina_hash_direct_add(file->rmap, &map->map, map);
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
map->refcount++;
|
|
|
|
|
2017-09-14 23:56:17 -07:00
|
|
|
_eina_file_map_rule_apply(rule, map->map, 0, length, map->length, map->hugetlb);
|
2011-04-13 09:15:30 -07:00
|
|
|
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_release(&file->lock);
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
return map->map;
|
2011-06-06 10:08:06 -07:00
|
|
|
|
|
|
|
on_error:
|
|
|
|
free(map);
|
|
|
|
eina_lock_release(&file->lock);
|
|
|
|
|
|
|
|
return NULL;
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API void
|
2011-04-13 09:15:30 -07:00
|
|
|
eina_file_map_free(Eina_File *file, void *map)
|
|
|
|
{
|
2011-09-15 06:57:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(file);
|
|
|
|
|
2013-07-30 19:51:51 -07:00
|
|
|
if (file->virtual)
|
2014-07-13 03:44:34 -07:00
|
|
|
{
|
|
|
|
eina_file_virtual_map_free(file, map);
|
|
|
|
return;
|
|
|
|
}
|
2013-07-30 19:51:51 -07:00
|
|
|
|
2011-06-06 10:08:06 -07:00
|
|
|
eina_lock_take(&file->lock);
|
|
|
|
|
2011-04-13 09:15:30 -07:00
|
|
|
if (file->global_map == map)
|
|
|
|
{
|
|
|
|
file->global_refcount--;
|
|
|
|
|
2011-06-06 10:08:06 -07:00
|
|
|
if (file->global_refcount > 0) goto on_exit;
|
2011-04-13 09:15:30 -07:00
|
|
|
|
|
|
|
munmap(file->global_map, file->length);
|
|
|
|
file->global_map = MAP_FAILED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-31 01:16:20 -07:00
|
|
|
eina_file_common_map_free(file, map, _eina_file_map_close);
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
2011-06-06 10:08:06 -07:00
|
|
|
|
|
|
|
on_exit:
|
|
|
|
eina_lock_release(&file->lock);
|
2011-04-13 09:15:30 -07:00
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API void
|
2013-10-28 02:26:10 -07:00
|
|
|
eina_file_map_populate(Eina_File *file, Eina_File_Populate rule, const void *map,
|
2013-07-06 06:01:23 -07:00
|
|
|
unsigned long int offset, unsigned long int length)
|
|
|
|
{
|
2017-09-14 23:56:17 -07:00
|
|
|
Eina_File_Map *em;
|
|
|
|
|
2013-07-06 06:01:23 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(file);
|
|
|
|
eina_lock_take(&file->lock);
|
2017-09-14 22:38:29 -07:00
|
|
|
if (map == file->global_map)
|
2017-09-14 23:56:17 -07:00
|
|
|
_eina_file_map_rule_apply(rule, map, offset, length, file->length, file->global_hugetlb);
|
|
|
|
else if ((em = eina_hash_find(file->rmap, &map)) != NULL)
|
|
|
|
_eina_file_map_rule_apply(rule, map, offset, length, em->length, em->hugetlb);
|
2013-07-06 06:01:23 -07:00
|
|
|
eina_lock_release(&file->lock);
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Bool
|
2012-01-03 06:59:07 -08:00
|
|
|
eina_file_map_faulted(Eina_File *file, void *map)
|
|
|
|
{
|
2012-03-14 08:35:12 -07:00
|
|
|
Eina_Bool r = EINA_FALSE;
|
2012-01-03 06:59:07 -08:00
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
|
|
|
|
|
2013-07-30 19:51:51 -07:00
|
|
|
if (file->virtual) return EINA_FALSE;
|
|
|
|
|
2012-01-03 06:59:07 -08:00
|
|
|
eina_lock_take(&file->lock);
|
|
|
|
|
2012-03-14 08:35:12 -07:00
|
|
|
if (file->global_map == map)
|
|
|
|
{
|
|
|
|
r = file->global_faulty;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-31 01:16:20 -07:00
|
|
|
Eina_File_Map *em;
|
|
|
|
|
2012-03-14 08:35:12 -07:00
|
|
|
em = eina_hash_find(file->rmap, &map);
|
2013-07-31 01:16:20 -07:00
|
|
|
if (em)
|
|
|
|
{
|
|
|
|
r = em->faulty;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(file->dead_map, l, em)
|
|
|
|
if (em->map == map)
|
|
|
|
{
|
|
|
|
r = em->faulty;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-03-14 08:35:12 -07:00
|
|
|
}
|
2012-01-03 06:59:07 -08:00
|
|
|
|
2012-03-14 08:35:12 -07:00
|
|
|
eina_lock_release(&file->lock);
|
2012-01-03 06:59:07 -08:00
|
|
|
|
2012-03-14 08:35:12 -07:00
|
|
|
return r;
|
2012-01-03 06:59:07 -08:00
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Iterator *
|
2012-01-03 06:59:07 -08:00
|
|
|
eina_file_xattr_get(Eina_File *file)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
|
2013-07-30 19:51:51 -07:00
|
|
|
if (file->virtual) return NULL;
|
|
|
|
|
2012-01-03 06:59:07 -08:00
|
|
|
return eina_xattr_fd_ls(file->fd);
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Iterator *
|
2012-01-03 06:59:07 -08:00
|
|
|
eina_file_xattr_value_get(Eina_File *file)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
|
2013-07-30 19:51:51 -07:00
|
|
|
if (file->virtual) return NULL;
|
|
|
|
|
2012-01-03 06:59:07 -08:00
|
|
|
return eina_xattr_value_fd_ls(file->fd);
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API int
|
2012-02-23 03:45:25 -08:00
|
|
|
eina_file_statat(void *container, Eina_File_Direct_Info *info, Eina_Stat *st)
|
2012-02-22 02:24:11 -08:00
|
|
|
{
|
2012-02-23 03:45:25 -08:00
|
|
|
struct stat buf;
|
2012-12-06 13:15:30 -08:00
|
|
|
#ifdef HAVE_ATFILE_SOURCE
|
2012-02-22 02:24:11 -08:00
|
|
|
int fd;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(info, -1);
|
2012-02-23 03:45:25 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(st, -1);
|
2012-02-22 02:24:11 -08:00
|
|
|
|
2012-12-06 13:15:30 -08:00
|
|
|
#ifdef HAVE_ATFILE_SOURCE
|
2012-03-13 04:25:56 -07:00
|
|
|
fd = dirfd((DIR*) container);
|
2012-02-23 03:45:25 -08:00
|
|
|
if (fstatat(fd, info->path + info->name_start, &buf, 0))
|
2012-02-22 02:24:11 -08:00
|
|
|
#else
|
2012-03-07 11:52:21 -08:00
|
|
|
(void)container;
|
2012-02-23 03:45:25 -08:00
|
|
|
if (stat(info->path, &buf))
|
2012-02-22 02:24:11 -08:00
|
|
|
#endif
|
2012-02-22 03:50:29 -08:00
|
|
|
{
|
|
|
|
if (info->type != EINA_FILE_LNK)
|
|
|
|
info->type = EINA_FILE_UNKNOWN;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info->type == EINA_FILE_UNKNOWN)
|
|
|
|
{
|
2012-02-23 03:45:25 -08:00
|
|
|
if (S_ISREG(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_REG;
|
2012-02-23 03:45:25 -08:00
|
|
|
else if (S_ISDIR(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_DIR;
|
2012-02-23 03:45:25 -08:00
|
|
|
else if (S_ISCHR(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_CHR;
|
2012-02-23 03:45:25 -08:00
|
|
|
else if (S_ISBLK(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_BLK;
|
2012-02-23 03:45:25 -08:00
|
|
|
else if (S_ISFIFO(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_FIFO;
|
2012-02-23 03:45:25 -08:00
|
|
|
else if (S_ISLNK(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_LNK;
|
2012-02-23 03:45:25 -08:00
|
|
|
else if (S_ISSOCK(buf.st_mode))
|
2012-02-22 03:50:29 -08:00
|
|
|
info->type = EINA_FILE_SOCK;
|
|
|
|
else
|
|
|
|
info->type = EINA_FILE_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2012-02-23 03:45:25 -08:00
|
|
|
st->dev = buf.st_dev;
|
|
|
|
st->ino = buf.st_ino;
|
|
|
|
st->mode = buf.st_mode;
|
|
|
|
st->nlink = buf.st_nlink;
|
|
|
|
st->uid = buf.st_uid;
|
|
|
|
st->gid = buf.st_gid;
|
|
|
|
st->rdev = buf.st_rdev;
|
|
|
|
st->size = buf.st_size;
|
|
|
|
st->blksize = buf.st_blksize;
|
|
|
|
st->blocks = buf.st_blocks;
|
|
|
|
st->atime = buf.st_atime;
|
|
|
|
st->mtime = buf.st_mtime;
|
|
|
|
st->ctime = buf.st_ctime;
|
|
|
|
#ifdef _STAT_VER_LINUX
|
|
|
|
# if (defined __USE_MISC && defined st_mtime)
|
|
|
|
st->atimensec = buf.st_atim.tv_nsec;
|
|
|
|
st->mtimensec = buf.st_mtim.tv_nsec;
|
|
|
|
st->ctimensec = buf.st_ctim.tv_nsec;
|
|
|
|
# else
|
|
|
|
st->atimensec = buf.st_atimensec;
|
|
|
|
st->mtimensec = buf.st_mtimensec;
|
|
|
|
st->ctimensec = buf.st_ctimensec;
|
|
|
|
# endif
|
|
|
|
#else
|
|
|
|
st->atimensec = 0;
|
|
|
|
st->mtimensec = 0;
|
|
|
|
st->ctimensec = 0;
|
|
|
|
#endif
|
2012-02-22 03:50:29 -08:00
|
|
|
return 0;
|
2012-02-22 02:24:11 -08:00
|
|
|
}
|
2012-12-31 15:17:18 -08:00
|
|
|
|
2020-08-14 07:22:17 -07:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// this below is funky avoiding opendir to avoid heap allocations thus
|
|
|
|
// getdents and all the os specific stuff as this is intendedf for use
|
|
|
|
// between fork and exec normally ... this is important
|
|
|
|
#if defined(__FreeBSD__)
|
|
|
|
# define do_getdents(fd, buf, size) getdents(fd, buf, size)
|
|
|
|
typedef struct
|
|
|
|
{
|
2020-08-24 12:07:56 -07:00
|
|
|
#if __FreeBSD__ > 11
|
2020-08-14 07:22:17 -07:00
|
|
|
ino_t d_ino;
|
|
|
|
off_t d_off;
|
|
|
|
unsigned short d_reclen;
|
|
|
|
unsigned char d_type;
|
|
|
|
unsigned char ____pad0;
|
|
|
|
unsigned short d_namlen;
|
|
|
|
unsigned short ____pad1;
|
|
|
|
char d_name[4096];
|
2020-08-24 12:07:56 -07:00
|
|
|
#else
|
|
|
|
__uint32_t d_fileno;
|
|
|
|
__uint16_t d_reclen;
|
|
|
|
__uint8_t d_type;
|
|
|
|
__uint8_t d_namlen;
|
|
|
|
char d_name[4096];
|
|
|
|
#endif
|
2020-08-14 07:22:17 -07:00
|
|
|
} Dirent;
|
|
|
|
#elif defined(__OpenBSD__)
|
|
|
|
# define do_getdents(fd, buf, size) getdents(fd, buf, size)
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
__ino_t d_ino;
|
|
|
|
__off_t d_off;
|
|
|
|
unsigned short d_reclen;
|
|
|
|
unsigned char d_type;
|
|
|
|
unsigned char d_namlen;
|
|
|
|
unsigned char ____pad[4];
|
|
|
|
char d_name[4096];
|
|
|
|
} Dirent;
|
|
|
|
#elif defined(__linux__)
|
2020-08-21 04:48:32 -07:00
|
|
|
# define do_getdents(fd, buf, size) syscall(SYS_getdents64, fd, buf, size)
|
|
|
|
// getdents64 added un glibc 2.30 ... so use raw syscall - will work
|
|
|
|
// from some linux 2.4 on... so ... i think that's ok. :)
|
|
|
|
//# define do_getdents(fd, buf, size) getdents64(fd, buf, size)
|
2020-08-14 07:22:17 -07:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
ino64_t d_ino;
|
|
|
|
off64_t d_off;
|
|
|
|
unsigned short d_reclen;
|
|
|
|
unsigned char d_type;
|
|
|
|
char d_name[4096];
|
|
|
|
} Dirent;
|
|
|
|
#endif
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API void
|
2019-11-20 00:43:26 -08:00
|
|
|
eina_file_close_from(int fd, int *except_fd)
|
|
|
|
{
|
|
|
|
#if defined(_WIN32)
|
|
|
|
// XXX: what do to here? anything?
|
|
|
|
#else
|
|
|
|
#ifdef HAVE_DIRENT_H
|
2020-08-14 07:22:17 -07:00
|
|
|
//# if 0
|
|
|
|
# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__)
|
|
|
|
int dirfd;
|
|
|
|
Dirent *d;
|
|
|
|
char buf[4096];
|
|
|
|
int *closes = NULL;
|
|
|
|
int num_closes = 0, i, j, clo, num;
|
|
|
|
const char *fname;
|
|
|
|
ssize_t pos, ret;
|
|
|
|
Eina_Bool do_read;
|
|
|
|
|
2020-08-21 00:50:05 -07:00
|
|
|
// note - this api is EXPECTED to be called in between a fork() and exec()
|
|
|
|
// when no threads are running. if you use this outside that context then
|
|
|
|
// it may not work as intended and may miss some fd's etc.
|
2020-08-14 07:22:17 -07:00
|
|
|
dirfd = open("/proc/self/fd", O_RDONLY | O_DIRECTORY);
|
|
|
|
if (dirfd < 0) dirfd = open("/dev/fd", O_RDONLY | O_DIRECTORY);
|
|
|
|
if (dirfd >= 0)
|
|
|
|
{
|
|
|
|
// count # of closes - the dir list should/will not change as its
|
|
|
|
// the fd's we have open so we can read it twice with no changes
|
|
|
|
// to it
|
|
|
|
do_read = EINA_TRUE;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
skip:
|
|
|
|
if (do_read)
|
|
|
|
{
|
|
|
|
pos = 0;
|
|
|
|
ret = do_getdents(dirfd, buf, sizeof(buf));
|
|
|
|
if (ret <= 0) break;
|
|
|
|
do_read = EINA_FALSE;
|
|
|
|
}
|
|
|
|
d = (Dirent *)(buf + pos);
|
|
|
|
fname = d->d_name;
|
|
|
|
pos += d->d_reclen;
|
|
|
|
if (pos >= ret) do_read = EINA_TRUE;
|
|
|
|
if (!((fname[0] >= '0') && (fname[0] <= '9'))) continue;
|
|
|
|
num = atoi(fname);
|
|
|
|
if (num < fd) continue;
|
|
|
|
if (except_fd)
|
|
|
|
{
|
|
|
|
for (j = 0; except_fd[j] >= 0; j++)
|
|
|
|
{
|
|
|
|
if (except_fd[j] == num) goto skip;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
num_closes++;
|
|
|
|
}
|
|
|
|
// alloc closes list and walk again to fill it - on stack to avoid
|
|
|
|
// heap allocs
|
|
|
|
closes = alloca(num_closes * sizeof(int));
|
|
|
|
if ((closes) && (num_closes > 0))
|
|
|
|
{
|
|
|
|
clo = 0;
|
|
|
|
lseek(dirfd, 0, SEEK_SET);
|
|
|
|
do_read = EINA_TRUE;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
skip2:
|
|
|
|
if (do_read)
|
|
|
|
{
|
|
|
|
pos = 0;
|
|
|
|
ret = do_getdents(dirfd, buf, sizeof(buf));
|
|
|
|
if (ret <= 0) break;
|
|
|
|
do_read = EINA_FALSE;
|
|
|
|
}
|
|
|
|
d = (Dirent *)(buf + pos);
|
|
|
|
fname = d->d_name;
|
|
|
|
pos += d->d_reclen;
|
|
|
|
if (pos >= ret) do_read = EINA_TRUE;
|
|
|
|
if (!((fname[0] >= '0') && (fname[0] <= '9'))) continue;
|
|
|
|
num = atoi(fname);
|
|
|
|
if (num < fd) continue;
|
|
|
|
if (except_fd)
|
|
|
|
{
|
|
|
|
for (j = 0; except_fd[j] >= 0; j++)
|
|
|
|
{
|
|
|
|
if (except_fd[j] == num) goto skip2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (clo < num_closes) closes[clo] = num;
|
|
|
|
clo++;
|
|
|
|
}
|
2020-08-21 00:50:05 -07:00
|
|
|
// in case we somehow don't fill up all of closes in 2nd pass
|
|
|
|
// (this shouldn't happen as no threads are running and we
|
|
|
|
// do nothing to modify the fd set between 2st and 2nd pass).
|
|
|
|
// set rest num_closes to clo so we don't close invalid values
|
|
|
|
num_closes = clo;
|
2020-08-14 07:22:17 -07:00
|
|
|
}
|
|
|
|
close(dirfd);
|
|
|
|
// now go close all those fd's - some may be invalide like the dir
|
|
|
|
// reading fd above... that's ok.
|
|
|
|
for (i = 0; i < num_closes; i++)
|
|
|
|
{
|
|
|
|
close(closes[i]);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
# else
|
2019-11-20 00:43:26 -08:00
|
|
|
DIR *dir;
|
2020-08-14 07:22:17 -07:00
|
|
|
int *closes = NULL;
|
|
|
|
int num_closes = 0, i, j, clo, num;
|
|
|
|
struct dirent *dp;
|
|
|
|
const char *fname;
|
2019-11-20 00:43:26 -08:00
|
|
|
|
2020-03-16 00:24:24 -07:00
|
|
|
dir = opendir("/proc/self/fd");
|
2019-11-20 00:43:26 -08:00
|
|
|
if (!dir) dir = opendir("/dev/fd");
|
|
|
|
if (dir)
|
|
|
|
{
|
2020-08-14 07:22:17 -07:00
|
|
|
// count # of closes - the dir list should/will not change as its
|
|
|
|
// the fd's we have open so we can read it twice with no changes
|
|
|
|
// to it
|
2019-11-20 00:43:26 -08:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
skip:
|
2020-08-14 07:22:17 -07:00
|
|
|
if (!(dp = readdir(dir))) break;
|
2019-11-20 00:43:26 -08:00
|
|
|
fname = dp->d_name;
|
2020-08-14 07:22:17 -07:00
|
|
|
if (!((fname[0] >= '0') && (fname[0] <= '9'))) continue;
|
|
|
|
num = atoi(fname);
|
|
|
|
if (num < fd) continue;
|
|
|
|
if (except_fd)
|
2019-11-20 00:43:26 -08:00
|
|
|
{
|
2020-08-14 07:22:17 -07:00
|
|
|
for (j = 0; except_fd[j] >= 0; j++)
|
2019-11-20 00:43:26 -08:00
|
|
|
{
|
2020-08-14 07:22:17 -07:00
|
|
|
if (except_fd[j] == num) goto skip;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
num_closes++;
|
|
|
|
}
|
|
|
|
// alloc closes list and walk again to fill it - on stack to avoid
|
|
|
|
// heap allocs
|
|
|
|
closes = alloca(num_closes * sizeof(int));
|
|
|
|
if ((closes) && (num_closes > 0))
|
|
|
|
{
|
|
|
|
clo = 0;
|
|
|
|
seekdir(dir, 0);
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
skip2:
|
|
|
|
if (!(dp = readdir(dir))) break;
|
|
|
|
fname = dp->d_name;
|
|
|
|
if (!((fname[0] >= '0') && (fname[0] <= '9'))) continue;
|
|
|
|
num = atoi(fname);
|
|
|
|
if (num < fd) continue;
|
|
|
|
if (except_fd)
|
|
|
|
{
|
|
|
|
for (j = 0; except_fd[j] >= 0; j++)
|
2019-11-20 00:43:26 -08:00
|
|
|
{
|
2020-08-14 07:22:17 -07:00
|
|
|
if (except_fd[j] == num) goto skip2;
|
2019-11-20 00:43:26 -08:00
|
|
|
}
|
|
|
|
}
|
2020-08-14 07:22:17 -07:00
|
|
|
if (clo < num_closes) closes[clo] = num;
|
|
|
|
clo++;
|
2019-11-20 00:43:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(dir);
|
2020-08-14 07:22:17 -07:00
|
|
|
// now go close all those fd's - some may be invalide like the dir
|
|
|
|
// reading fd above... that's ok.
|
|
|
|
for (i = 0; i < num_closes; i++)
|
|
|
|
{
|
|
|
|
close(closes[i]);
|
|
|
|
}
|
2019-11-20 00:43:26 -08:00
|
|
|
return;
|
|
|
|
}
|
2020-08-14 07:22:17 -07:00
|
|
|
# endif
|
2019-11-20 00:43:26 -08:00
|
|
|
#endif
|
2020-08-14 07:22:17 -07:00
|
|
|
int max = 1024;
|
2019-11-20 00:43:26 -08:00
|
|
|
|
2020-08-14 07:22:17 -07:00
|
|
|
#ifdef HAVE_SYS_RESOURCE_H
|
2019-11-20 00:43:26 -08:00
|
|
|
struct rlimit lim;
|
|
|
|
if (getrlimit(RLIMIT_NOFILE, &lim) < 0) return;
|
|
|
|
max = lim.rlim_max;
|
2020-08-14 07:22:17 -07:00
|
|
|
#endif
|
2019-11-20 00:43:26 -08:00
|
|
|
for (i = fd; i < max;)
|
|
|
|
{
|
|
|
|
if (except_fd)
|
|
|
|
{
|
|
|
|
int j;
|
|
|
|
|
|
|
|
for (j = 0; except_fd[j] >= 0; j++)
|
|
|
|
{
|
2020-08-14 07:22:17 -07:00
|
|
|
if (except_fd[j] == i) goto skip3;
|
2019-11-20 00:43:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
close(i);
|
2020-08-14 07:22:17 -07:00
|
|
|
skip3:
|
2019-11-20 00:43:26 -08:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2020-10-08 03:58:11 -07:00
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API int
|
2020-10-08 03:58:11 -07:00
|
|
|
eina_file_mkstemp(const char *templatename, Eina_Tmpstr **path)
|
|
|
|
{
|
|
|
|
char buffer[PATH_MAX];
|
|
|
|
const char *XXXXXX = NULL, *sep;
|
|
|
|
int fd, len;
|
|
|
|
mode_t old_umask;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(templatename, -1);
|
|
|
|
|
|
|
|
sep = strchr(templatename, '/');
|
|
|
|
if (sep)
|
|
|
|
{
|
|
|
|
len = eina_strlcpy(buffer, templatename, sizeof(buffer));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
len = eina_file_path_join(buffer, sizeof(buffer),
|
|
|
|
eina_environment_tmp_get(), templatename);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unix:
|
|
|
|
* Make sure temp file is created with secure permissions,
|
|
|
|
* http://man7.org/linux/man-pages/man3/mkstemp.3.html#NOTES
|
|
|
|
*/
|
|
|
|
old_umask = umask(S_IRWXG|S_IRWXO);
|
|
|
|
if ((XXXXXX = strstr(buffer, "XXXXXX.")) != NULL)
|
|
|
|
{
|
|
|
|
int suffixlen = buffer + len - XXXXXX - 6;
|
|
|
|
fd = mkstemps(buffer, suffixlen);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fd = mkstemp(buffer);
|
|
|
|
umask(old_umask);
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
{
|
|
|
|
if (path) *path = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path) *path = eina_tmpstr_add(buffer);
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
eina: Rename EAPI macro to EINA_API in Eina library
Summary:
Patch from a series of patches to rename EAPI symbols to specific
library DSOs.
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: jptiz, lucas, woohyun, vtorri, raster
Reviewed By: jptiz, lucas, vtorri
Subscribers: ProhtMeyhet, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
|
|
|
EINA_API Eina_Bool
|
2020-10-08 03:58:11 -07:00
|
|
|
eina_file_mkdtemp(const char *templatename, Eina_Tmpstr **path)
|
|
|
|
{
|
|
|
|
char buffer[PATH_MAX];
|
|
|
|
char *tmpdirname, *sep;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(templatename, EINA_FALSE);
|
|
|
|
|
|
|
|
sep = strchr(templatename, '/');
|
|
|
|
if (sep)
|
|
|
|
{
|
|
|
|
eina_strlcpy(buffer, templatename, sizeof(buffer));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eina_file_path_join(buffer, sizeof(buffer),
|
|
|
|
eina_environment_tmp_get(), templatename);
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpdirname = mkdtemp(buffer);
|
|
|
|
if (tmpdirname == NULL)
|
|
|
|
{
|
|
|
|
if (path) *path = NULL;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path) *path = eina_tmpstr_add(tmpdirname);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|