Eina: DOS2UNIX eina_file_win32.c

Eina: DOS2UNIX eina_file_win32.c

git-svn-id: a6113611d365f0fc061992be0d1d0b451b434026@67445 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

--- src/lib/eina_file_win32.c
+++ src/lib/eina_file_win32.c
@@ -1,1153 +1,1153 @@
-/* EINA - EFL data type library
- * Copyright (C) 2010 Vincent Torri
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#elif defined __GNUC__
-# define alloca __builtin_alloca
-#elif defined _AIX
-# define alloca __alloca
-#elif defined _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-#else
-# include <stddef.h>
-# ifdef  __cplusplus
-extern "C"
-# endif
-void *alloca (size_t);
-#endif
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-#include <Evil.h>
-
-#include "eina_config.h"
-#include "eina_private.h"
-
-/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
-#include "eina_safety_checks.h"
-#include "eina_file.h"
-#include "eina_stringshare.h"
-#include "eina_hash.h"
-#include "eina_list.h"
-#include "eina_lock.h"
-#include "eina_log.h"
-
-/*============================================================================*
- *                                  Local                                     *
- *============================================================================*/
-
-/**
- * @cond LOCAL
- */
-
-#ifndef EINA_LOG_COLOR_DEFAULT
-#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN
-#endif
-
-#ifdef ERR
-#undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
-
-#ifdef WRN
-#undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__)
-
-#ifdef DBG
-#undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
-
-#ifdef MAP_FAILED
-# undef MAP_FAILED
-#endif
-#define MAP_FAILED ((void *)-1)
-
-typedef struct _Eina_File_Iterator        Eina_File_Iterator;
-typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
-typedef struct _Eina_File_Map             Eina_File_Map;
-
-struct _Eina_File_Iterator
-{
-   Eina_Iterator   iterator;
-
-   WIN32_FIND_DATA data;
-   HANDLE          handle;
-   size_t          length;
-   Eina_Bool       is_last : 1;
-
-   char            dir[1];
-};
-
-struct _Eina_File_Direct_Iterator
-{
-   Eina_Iterator         iterator;
-
-   WIN32_FIND_DATA       data;
-   HANDLE                handle;
-   size_t                length;
-   Eina_Bool             is_last : 1;
-
-   Eina_File_Direct_Info info;
-
-   char                  dir[1];
-};
-
-struct _Eina_File
-{
-   const char *filename;
-
-   Eina_Hash *map;
-   Eina_Hash *rmap;
-   void *global_map;
-
-   Eina_Lock lock;
-
-   ULONGLONG length;
-   ULONGLONG mtime;
-
-   int refcount;
-   int global_refcount;
-
-   HANDLE handle;
-   HANDLE fm;
-
-   Eina_Bool shared : 1;
-   Eina_Bool delete_me : 1;
-};
-
-struct _Eina_File_Map
-{
-   void *map;
-
-   unsigned long int offset;
-   unsigned long int length;
-
-   int refcount;
-};
-
-static Eina_Hash *_eina_file_cache = NULL;
-static Eina_Lock _eina_file_lock_cache;
-
-static int _eina_file_log_dom = -1;
-
-static void
-_eina_file_win32_backslash_change(char *dir)
-{
-   char *tmp;
-
-   tmp = dir;
-   while (*tmp)
-     {
-        if (*tmp == '/') *tmp = '\\';
-        tmp++;
-     }
-}
-
-static Eina_Bool
-_eina_file_win32_is_dir(const char *dir)
-{
-#ifdef UNICODE
-   wchar_t *wdir = NULL;
-#endif
-   DWORD    attr;
-
-   /* check if it's a directory */
-#ifdef UNICODE
-   wdir = evil_char_to_wchar(dir);
-   if (!wdir)
-     return EINA_FALSE;
-
-   attr = GetFileAttributes(wdir);
-   free(wdir);
-#else
-   attr = GetFileAttributes(dir);
-#endif
-
-   if (attr == 0xFFFFFFFF)
-     return EINA_FALSE;
-
-   if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
-     return EINA_FALSE;
-
-   return EINA_TRUE;
-}
-
-static char *
-_eina_file_win32_dir_new(const char *dir)
-{
-   char *new_dir;
-   size_t length;
-
-   length = strlen(dir);
-
-   new_dir = (char *)malloc(sizeof(char) * length + 5);
-   if (!new_dir)
-     return NULL;
-
-   memcpy(new_dir, dir, length);
-   memcpy(new_dir + length, "\\*.*", 5);
-   _eina_file_win32_backslash_change(new_dir);
-
-   return new_dir;
-}
-
-static HANDLE
-_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd)
-{
-  HANDLE h;
-#ifdef UNICODE
-   wchar_t *wdir = NULL;
-
-   wdir = evil_char_to_wchar(dir);
-   if (!wdir)
-     return NULL;
-
-   h = FindFirstFile(wdir, fd);
-   free(wdir);
-#else
-   h = FindFirstFile(dir, fd);
-#endif
-
-   if (!h)
-     return NULL;
-
-   while ((fd->cFileName[0] == '.') &&
-          ((fd->cFileName[1] == '\0') ||
-           ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0'))))
-     {
-        if (!FindNextFile(h, fd))
-          return NULL;
-     }
-
-   return h;
-}
-
-static Eina_Bool
-_eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data)
-{
-#ifdef UNICODE
-   wchar_t  *old_name;
-#else
-   char     *old_name;
-#endif
-   char     *name;
-   char     *cname;
-   size_t    length;
-   Eina_Bool is_last;
-   Eina_Bool res = EINA_TRUE;
-
-   if (it->handle == INVALID_HANDLE_VALUE)
-     return EINA_FALSE;
-
-   is_last = it->is_last;
-#ifdef UNICODE
-   old_name = _wcsdup(it->data.cFileName);
-#else
-   old_name = _strdup(it->data.cFileName);
-#endif
-   if (!old_name)
-     return EINA_FALSE;
-
-   do {
-      if (!FindNextFile(it->handle, &it->data))
-        {
-           if (GetLastError() == ERROR_NO_MORE_FILES)
-             it->is_last = EINA_TRUE;
-           else
-             res = EINA_FALSE;
-        }
-   } while ((it->data.cFileName[0] == '.') &&
-            ((it->data.cFileName[1] == '\0') ||
-             ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
-
-#ifdef UNICODE
-   cname = evil_wchar_to_char(old_name);
-   if (!cname)
-     return EINA_FALSE;
-#else
-     cname = old_name;
-#endif
-
-   length = strlen(cname);
-   name = alloca(length + 2 + it->length);
-
-   memcpy(name,                  it->dir, it->length);
-   memcpy(name + it->length,     "\\",    1);
-   memcpy(name + it->length + 1, cname,   length + 1);
-
-   *data = (char *)eina_stringshare_add(name);
-
-#ifdef UNICODE
-   free(cname);
-#endif
-   free(old_name);
-
-   if (is_last)
-     res = EINA_FALSE;
-
-   return res;
-}
-
-static HANDLE
-_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it)
-{
-   return it->handle;
-}
-
-static void
-_eina_file_win32_ls_iterator_free(Eina_File_Iterator *it)
-{
-   if (it->handle != INVALID_HANDLE_VALUE)
-     FindClose(it->handle);
-
-   EINA_MAGIC_SET(&it->iterator, 0);
-   free(it);
-}
-
-static Eina_Bool
-_eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
-{
-#ifdef UNICODE
-   wchar_t  *old_name;
-#else
-   char     *old_name;
-#endif
-   char     *cname;
-   size_t    length;
-   DWORD     attr;
-   Eina_Bool is_last;
-   Eina_Bool res = EINA_TRUE;
-
-   if (it->handle == INVALID_HANDLE_VALUE)
-     return EINA_FALSE;
-
-   attr = it->data.dwFileAttributes;
-   is_last = it->is_last;
-#ifdef UNICODE
-   old_name = _wcsdup(it->data.cFileName);
-#else
-   old_name = _strdup(it->data.cFileName);
-#endif
-   if (!old_name)
-     return EINA_FALSE;
-
-   do {
-      if (!FindNextFile(it->handle, &it->data))
-        {
-           if (GetLastError() == ERROR_NO_MORE_FILES)
-             it->is_last = EINA_TRUE;
-           else
-             res = EINA_FALSE;
-        }
-
-#ifdef UNICODE
-     length = wcslen(old_name);
-#else
-     length = strlen(old_name);
-#endif
-     if (it->info.name_start + length + 1 >= PATH_MAX)
-       {
-          free(old_name);
-#ifdef UNICODE
-          old_name = _wcsdup(it->data.cFileName);
-#else
-          old_name = _strdup(it->data.cFileName);
-#endif
-          continue;
-       }
-
-   } while ((it->data.cFileName[0] == '.') &&
-            ((it->data.cFileName[1] == '\0') ||
-             ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
-
-#ifdef UNICODE
-   cname = evil_wchar_to_char(old_name);
-   if (!cname)
-     return EINA_FALSE;
-#else
-     cname = old_name;
-#endif
-
-   memcpy(it->info.path + it->info.name_start, cname, length);
-   it->info.name_length = length;
-   it->info.path_length = it->info.name_start + length;
-   it->info.path[it->info.path_length] = '\0';
-
-   if (attr & FILE_ATTRIBUTE_DIRECTORY)
-     it->info.type = EINA_FILE_DIR;
-   else if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
-     it->info.type = EINA_FILE_LNK;
-   else if (attr & (FILE_ATTRIBUTE_ARCHIVE |
-                    FILE_ATTRIBUTE_COMPRESSED |
-                    FILE_ATTRIBUTE_COMPRESSED |
-                    FILE_ATTRIBUTE_HIDDEN |
-                    FILE_ATTRIBUTE_NORMAL |
-                    FILE_ATTRIBUTE_SPARSE_FILE |
-                    FILE_ATTRIBUTE_TEMPORARY))
-     it->info.type = EINA_FILE_REG;
-   else
-     it->info.type = EINA_FILE_UNKNOWN;
-
-   *data = &it->info;
-
-#ifdef UNICODE
-   free(cname);
-#endif
-
-   free(old_name);
-
-   if (is_last)
-     res = EINA_FALSE;
-
-   return res;
-}
-
-static HANDLE
-_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
-{
-   return it->handle;
-}
-
-static void
-_eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
-{
-   if (it->handle != INVALID_HANDLE_VALUE)
-     FindClose(it->handle);
-
-   EINA_MAGIC_SET(&it->iterator, 0);
-   free(it);
-}
-
-static void
-_eina_file_real_close(Eina_File *file)
-{
-   eina_hash_free(file->rmap);
-   eina_hash_free(file->map);
-
-   if (file->global_map != MAP_FAILED)
-     UnmapViewOfFile(file->global_map);
-
-   CloseHandle(file->fm);
-   CloseHandle(file->handle);
-
-   eina_stringshare_del(file->filename);
-
-   free(file);
-}
-
-static void
-_eina_file_map_close(Eina_File_Map *map)
-{
-   if (map->map != MAP_FAILED)
-     UnmapViewOfFile(map->map);
-   free(map);
-}
-
-static unsigned int
-_eina_file_map_key_length(const void *key __UNUSED__)
-{
-   return sizeof (unsigned long int) * 2;
-}
-
-static int
-_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__,
-                       const unsigned long int *key2, int key2_length __UNUSED__)
-{
-   if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
-   return key1[0] - key2[0];
-}
-
-static int
-_eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__)
-{
-   return eina_hash_int64(&key[0], sizeof (unsigned long int))
-     ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
-}
-
-static char *
-_eina_file_win32_escape(const char *path, size_t *length)
-{
-   char *result = strdup(path ? path : "");
-   char *p = result;
-   char *q = result;
-   size_t len;
-
-   if (!result)
-     return NULL;
-
-   if (length) len = *length;
-   else len = strlen(result);
-
-   while ((p = strchr(p, '/')))
-     {
-        // remove double `/'
-        if (p[1] == '/')
-          {
-             memmove(p, p + 1, --len - (p - result));
-             result[len] = '\0';
-          }
-        else
-          if (p[1] == '.'
-              && p[2] == '.')
-            {
-               // remove `/../'
-               if (p[3] == '/')
-                 {
-                    char tmp;
-
-                    len -= p + 3 - q;
-                    memmove(q, p + 3, len - (q - result));
-                    result[len] = '\0';
-                    p = q;
-
-                    /* Update q correctly. */
-                    tmp = *p;
-                    *p = '\0';
-                    q = strrchr(result, '/');
-                    if (!q) q = result;
-                    *p = tmp;
-                 }
-               else
-                 // remove '/..$'
-                 if (p[3] == '\0')
-                   {
-                      len -= p + 2 - q;
-                      result[len] = '\0';
-                      q = p;
-                      ++p;
-                   }
-                 else
-                   {
-                      q = p;
-                      ++p;
-                   }
-            }
-          else
-            {
-               q = p;
-               ++p;
-            }
-     }
-
-   if (length)
-     *length = len;
-
-   return result;
-}
-
-
-/**
- * @endcond
- */
-
-/*============================================================================*
- *                                 Global                                     *
- *============================================================================*/
-
-Eina_Bool
-eina_file_init(void)
-{
-   _eina_file_log_dom = eina_log_domain_register("eina_file",
-                                                 EINA_LOG_COLOR_DEFAULT);
-   if (_eina_file_log_dom < 0)
-     {
-        EINA_LOG_ERR("Could not register log domain: eina_file");
-        return EINA_FALSE;
-     }
-
-   _eina_file_cache = eina_hash_string_djb2_new(NULL);
-   if (!_eina_file_cache)
-     {
-        ERR("Could not create cache.");
-        eina_log_domain_unregister(_eina_file_log_dom);
-        _eina_file_log_dom = -1;
-        return EINA_FALSE;
-     }
-
-   eina_lock_new(&_eina_file_lock_cache);
-
-   return EINA_TRUE;
-}
-
-Eina_Bool
-eina_file_shutdown(void)
-{
-   if (eina_hash_population(_eina_file_cache) > 0)
-     {
-        Eina_Iterator *it;
-        const char *key;
-
-        it = eina_hash_iterator_key_new(_eina_file_cache);
-        EINA_ITERATOR_FOREACH(it, key)
-          ERR("File [%s] still open !", key);
-        eina_iterator_free(it);
-     }
-
-   eina_hash_free(_eina_file_cache);
-
-   eina_lock_free(&_eina_file_lock_cache);
-
-   eina_log_domain_unregister(_eina_file_log_dom);
-   _eina_file_log_dom = -1;
-   return EINA_TRUE;
-}
-
-/*============================================================================*
- *                                   API                                      *
- *============================================================================*/
-
-
-EAPI char *
-eina_file_path_sanitize(const char *path)
-{
-   char *result = NULL;
-   size_t len;
-
-   if (!path) return NULL;
-
-   len = strlen(path);
-   if (len < 3) return NULL;
-
-   if (!evil_path_is_absolute(path))
-     {
-        DWORD l;
-
-        l = GetCurrentDirectory(0, NULL);
-        if (l > 0)
-          {
-             char *cwd;
-             DWORD l2;
-
-             cwd = alloca(sizeof(char) * (l + 1));
-             l2 = GetCurrentDirectory(l + 1, cwd);
-             if (l2 == l)
-               {
-                  char *tmp;
-
-                  len += l + 2;
-                  tmp = alloca(sizeof (char) * len);
-                  snprintf(tmp, len, "%s/%s", cwd, path);
-                  tmp[len - 1] = '\0';
-                  result = tmp;
-               }
-          }
-     }
-
-   return _eina_file_win32_escape(result ? result : path, &len);
-}
-
-EAPI Eina_Bool
-eina_file_dir_list(const char *dir,
-                   Eina_Bool recursive,
-                   Eina_File_Dir_List_Cb cb,
-                   void *data)
-{
-   WIN32_FIND_DATA file;
-   HANDLE h;
-   char *new_dir;
-
-   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);
-
-   if (!_eina_file_win32_is_dir(dir))
-     return EINA_FALSE;
-
-   new_dir = _eina_file_win32_dir_new(dir);
-   if (!new_dir)
-      return EINA_FALSE;
-
-   h = _eina_file_win32_first_file(new_dir, &file);
-
-   if (h == INVALID_HANDLE_VALUE)
-      return EINA_FALSE;
-
-   do
-     {
-        char *filename;
-
-# ifdef UNICODE
-        filename = evil_wchar_to_char(file.cFileName);
-# else
-        filename = file.cFileName;
-# endif /* ! UNICODE */
-        if (!strcmp(filename, ".") || !strcmp(filename, ".."))
-           continue;
-
-        cb(filename, dir, data);
-
-        if (recursive == EINA_TRUE)
-          {
-             char *path;
-
-             path = alloca(strlen(dir) + strlen(filename) + 2);
-             strcpy(path, dir);
-             strcat(path, "/");
-             strcat(path, filename);
-
-             if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
-                continue;
-
-             eina_file_dir_list(path, recursive, cb, data);
-          }
-
-# ifdef UNICODE
-        free(filename);
-# endif /* UNICODE */
-
-     } while (FindNextFile(h, &file));
-   FindClose(h);
-
-   return EINA_TRUE;
-}
-
-EAPI Eina_Array *
-eina_file_split(char *path)
-{
-   Eina_Array *ea;
-   char *current;
-   size_t length;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
-
-   ea = eina_array_new(16);
-
-   if (!ea)
-      return NULL;
-
-   for (current = strchr(path, '\\');
-        current;
-        path = current + 1, current = strchr(path, '\\'))
-     {
-        length = current - path;
-
-        if (length <= 0)
-           continue;
-
-        eina_array_push(ea, path);
-        *current = '\0';
-     }
-
-   if (*path != '\0')
-        eina_array_push(ea, path);
-
-   return ea;
-}
-
-EAPI Eina_Iterator *
-eina_file_ls(const char *dir)
-{
-   Eina_File_Iterator *it;
-   char               *new_dir;
-   size_t              length;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-
-   if (!dir || !*dir)
-      return NULL;
-
-   if (!_eina_file_win32_is_dir(dir))
-     return NULL;
-
-   length = strlen(dir);
-
-   it = calloc(1, sizeof (Eina_File_Iterator) + length);
-   if (!it)
-      return NULL;
-
-   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
-
-   new_dir = _eina_file_win32_dir_new(dir);
-   if (!new_dir)
-      goto free_it;
-
-   it->handle = _eina_file_win32_first_file(new_dir, &it->data);
-   free(new_dir);
-   if (it->handle == INVALID_HANDLE_VALUE)
-     goto free_it;
-
-   memcpy(it->dir, dir, length + 1);
-   if (dir[length - 1] != '\\')
-      it->length = length;
-   else
-      it->length = length - 1;
-   _eina_file_win32_backslash_change(it->dir);
-
-   it->iterator.version = EINA_ITERATOR_VERSION;
-   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next);
-   it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container);
-   it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free);
-
-   return &it->iterator;
-
- free_it:
-   free(it);
-
-   return NULL;
-}
-
-EAPI Eina_Iterator *
-eina_file_direct_ls(const char *dir)
-{
-   Eina_File_Direct_Iterator *it;
-   char                      *new_dir;
-   size_t                     length;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-
-   if (!dir || !*dir)
-      return NULL;
-
-   length = strlen(dir);
-
-   if (length + 12 + 2 >= MAX_PATH)
-      return NULL;
-
-   it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length);
-   if (!it)
-      return NULL;
-
-   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
-
-   new_dir = _eina_file_win32_dir_new(dir);
-   if (!new_dir)
-      goto free_it;
-
-   it->handle = _eina_file_win32_first_file(new_dir, &it->data);
-   free(new_dir);
-   if (it->handle == INVALID_HANDLE_VALUE)
-     goto free_it;
-
-   memcpy(it->dir, dir, length + 1);
-   it->length = length;
-   _eina_file_win32_backslash_change(it->dir);
-
-   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;
-     }
-   _eina_file_win32_backslash_change(it->info.path);
-
-   it->iterator.version = EINA_ITERATOR_VERSION;
-   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next);
-   it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container);
-   it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free);
-
-   return &it->iterator;
-
- free_it:
-   free(it);
-
-   return NULL;
-}
-
-EAPI Eina_Iterator *
-eina_file_stat_ls(const char *dir)
-{
-   return eina_file_direct_ls(dir);
-}
-
-EAPI Eina_File *
-eina_file_open(const char *path, Eina_Bool shared)
-{
-   Eina_File *file;
-   Eina_File *n;
-   char *filename;
-   HANDLE handle;
-   HANDLE fm;
-   WIN32_FILE_ATTRIBUTE_DATA fad;
-   ULARGE_INTEGER length;
-   ULARGE_INTEGER mtime;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
-
-   filename = eina_file_path_sanitize(path);
-   if (!filename) return NULL;
-
-   /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */
-#if 0
-   if (shared)
-     handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
-                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
-                         NULL);
-   else
-#endif
-     handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
-                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
-                         NULL);
-
-   if (handle == INVALID_HANDLE_VALUE)
-     return NULL;
-
-   fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL);
-   if (!fm)
-     goto close_handle;
-
-   if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad))
-     goto close_fm;
-
-   length.u.LowPart = fad.nFileSizeLow;
-   length.u.HighPart = fad.nFileSizeHigh;
-   mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime;
-   mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime;
-
-   eina_lock_take(&_eina_file_lock_cache);
-
-   file = eina_hash_find(_eina_file_cache, filename);
-   if (file &&
-       (file->mtime == mtime.QuadPart && file->length == length.QuadPart))
-     {
-        file->delete_me = EINA_TRUE;
-        eina_hash_del(_eina_file_cache, file->filename, file);
-        _eina_file_real_close(file);
-        file = NULL;
-     }
-
-   if (!file)
-     {
-        n = malloc(sizeof (Eina_File) + strlen(filename) + 1);
-        if (!n)
-          {
-             eina_lock_release(&_eina_file_lock_cache);
-             goto close_fm;
-          }
-
-        n->filename = (char*) (n + 1);
-        strcpy((char*) n->filename, filename);
-        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),
-                               EINA_FREE_CB(_eina_file_map_close),
-                               3);
-        n->rmap = eina_hash_pointer_new(NULL);
-        n->global_map = MAP_FAILED;
-        n->global_refcount = 0;
-        n->length = length.QuadPart;
-        n->mtime = mtime.QuadPart;
-        n->refcount = 0;
-        n->handle = handle;
-        n->fm = fm;
-        n->shared = shared;
-        n->delete_me = EINA_FALSE;
-        eina_lock_new(&n->lock);
-        eina_hash_direct_add(_eina_file_cache, n->filename, n);
-     }
-   else
-     {
-        CloseHandle(fm);
-        CloseHandle(handle);
-
-        n = file;
-     }
-   eina_lock_take(&n->lock);
-   n->refcount++;
-   eina_lock_release(&n->lock);
-
-   eina_lock_release(&_eina_file_lock_cache);
-
-   free(filename);
-
-   return n;
-
- close_fm:
-   CloseHandle(fm);
- close_handle:
-   CloseHandle(handle);
-
-   return NULL;
-}
-
-EAPI void
-eina_file_close(Eina_File *file)
-{
-   EINA_SAFETY_ON_NULL_RETURN(file);
-
-   eina_lock_take(&file->lock);
-   file->refcount--;
-   eina_lock_release(&file->lock);
-
-   if (file->refcount != 0) return ;
-   eina_lock_take(&_eina_file_lock_cache);
-
-   eina_hash_del(_eina_file_cache, file->filename, file);
-   _eina_file_real_close(file);
-
-   eina_lock_release(&_eina_file_lock_cache);
-}
-
-EAPI size_t
-eina_file_size_get(Eina_File *file)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
-   return file->length;
-}
-
-EAPI time_t
-eina_file_mtime_get(Eina_File *file)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
-  return file->mtime;
-}
-
-EAPI const char *
-eina_file_filename_get(Eina_File *file)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
-   return file->filename;
-}
-
-EAPI void *
-eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
-
-   eina_lock_take(&file->lock);
-   if (file->global_map == MAP_FAILED)
-     {
-        void  *data;
-
-        data = MapViewOfFile(file->fm, FILE_MAP_READ,
-                             0, 0, file->length);
-        if (!data)
-          file->global_map = MAP_FAILED;
-        else
-          file->global_map = data;
-     }
-
-   if (file->global_map != MAP_FAILED)
-     {
-        file->global_refcount++;
-        return file->global_map;
-     }
-
-   eina_lock_release(&file->lock);
-   return NULL;
-}
-
-EAPI void *
-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];
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
-
-   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);
-
-   key[0] = offset;
-   key[1] = length;
-
-   eina_lock_take(&file->lock);
-
-   map = eina_hash_find(file->map, &key);
-   if (!map)
-     {
-        void  *data;
-
-        map = malloc(sizeof (Eina_File_Map));
-        if (!map) return NULL;
-
-        data = MapViewOfFile(file->fm, FILE_MAP_READ,
-                             offset & 0xffff0000,
-                             offset & 0x0000ffff,
-                             length);
-        if (!data)
-          map->map = MAP_FAILED;
-        else
-          map->map = data;
-
-        map->offset = offset;
-        map->length = length;
-        map->refcount = 0;
-
-        if (map->map == MAP_FAILED)
-          {
-             free(map);
-             return NULL;
-          }
-
-        eina_hash_add(file->map, &key, map);
-        eina_hash_direct_add(file->rmap, map->map, map);
-     }
-
-   map->refcount++;
-
-   eina_lock_release(&file->lock);
-
-   return map->map;
-}
-
-EAPI void
-eina_file_map_free(Eina_File *file, void *map)
-{
-   EINA_SAFETY_ON_NULL_RETURN(file);
-
-   eina_lock_take(&file->lock);
-
-   if (file->global_map == map)
-     {
-        file->global_refcount--;
-
-        if (file->global_refcount > 0) goto on_exit;
-
-        UnmapViewOfFile(file->global_map);
-        file->global_map = MAP_FAILED;
-     }
-   else
-     {
-        Eina_File_Map *em;
-        unsigned long int key[2];
-
-        em = eina_hash_find(file->rmap, &map);
-        if (!em) return ;
-
-        em->refcount--;
-
-        if (em->refcount > 0) goto on_exit;
-
-        key[0] = em->offset;
-        key[1] = em->length;
-
-        eina_hash_del(file->rmap, &map, em);
-        eina_hash_del(file->map, &key, em);
-     }
-
- on_exit:
-   eina_lock_release(&file->lock);
-}
+/* EINA - EFL data type library
+ * Copyright (C) 2010 Vincent Torri
+ *
+ * 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+# define alloca __builtin_alloca
+#elif defined _AIX
+# define alloca __alloca
+#elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#else
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <Evil.h>
+
+#include "eina_config.h"
+#include "eina_private.h"
+
+/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
+#include "eina_safety_checks.h"
+#include "eina_file.h"
+#include "eina_stringshare.h"
+#include "eina_hash.h"
+#include "eina_list.h"
+#include "eina_lock.h"
+#include "eina_log.h"
+
+/*============================================================================*
+ *                                  Local                                     *
+ *============================================================================*/
+
+/**
+ * @cond LOCAL
+ */
+
+#ifndef EINA_LOG_COLOR_DEFAULT
+#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN
+#endif
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
+
+#ifdef MAP_FAILED
+# undef MAP_FAILED
+#endif
+#define MAP_FAILED ((void *)-1)
+
+typedef struct _Eina_File_Iterator        Eina_File_Iterator;
+typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
+typedef struct _Eina_File_Map             Eina_File_Map;
+
+struct _Eina_File_Iterator
+{
+   Eina_Iterator   iterator;
+
+   WIN32_FIND_DATA data;
+   HANDLE          handle;
+   size_t          length;
+   Eina_Bool       is_last : 1;
+
+   char            dir[1];
+};
+
+struct _Eina_File_Direct_Iterator
+{
+   Eina_Iterator         iterator;
+
+   WIN32_FIND_DATA       data;
+   HANDLE                handle;
+   size_t                length;
+   Eina_Bool             is_last : 1;
+
+   Eina_File_Direct_Info info;
+
+   char                  dir[1];
+};
+
+struct _Eina_File
+{
+   const char *filename;
+
+   Eina_Hash *map;
+   Eina_Hash *rmap;
+   void *global_map;
+
+   Eina_Lock lock;
+
+   ULONGLONG length;
+   ULONGLONG mtime;
+
+   int refcount;
+   int global_refcount;
+
+   HANDLE handle;
+   HANDLE fm;
+
+   Eina_Bool shared : 1;
+   Eina_Bool delete_me : 1;
+};
+
+struct _Eina_File_Map
+{
+   void *map;
+
+   unsigned long int offset;
+   unsigned long int length;
+
+   int refcount;
+};
+
+static Eina_Hash *_eina_file_cache = NULL;
+static Eina_Lock _eina_file_lock_cache;
+
+static int _eina_file_log_dom = -1;
+
+static void
+_eina_file_win32_backslash_change(char *dir)
+{
+   char *tmp;
+
+   tmp = dir;
+   while (*tmp)
+     {
+        if (*tmp == '/') *tmp = '\\';
+        tmp++;
+     }
+}
+
+static Eina_Bool
+_eina_file_win32_is_dir(const char *dir)
+{
+#ifdef UNICODE
+   wchar_t *wdir = NULL;
+#endif
+   DWORD    attr;
+
+   /* check if it's a directory */
+#ifdef UNICODE
+   wdir = evil_char_to_wchar(dir);
+   if (!wdir)
+     return EINA_FALSE;
+
+   attr = GetFileAttributes(wdir);
+   free(wdir);
+#else
+   attr = GetFileAttributes(dir);
+#endif
+
+   if (attr == 0xFFFFFFFF)
+     return EINA_FALSE;
+
+   if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
+     return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static char *
+_eina_file_win32_dir_new(const char *dir)
+{
+   char *new_dir;
+   size_t length;
+
+   length = strlen(dir);
+
+   new_dir = (char *)malloc(sizeof(char) * length + 5);
+   if (!new_dir)
+     return NULL;
+
+   memcpy(new_dir, dir, length);
+   memcpy(new_dir + length, "\\*.*", 5);
+   _eina_file_win32_backslash_change(new_dir);
+
+   return new_dir;
+}
+
+static HANDLE
+_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd)
+{
+  HANDLE h;
+#ifdef UNICODE
+   wchar_t *wdir = NULL;
+
+   wdir = evil_char_to_wchar(dir);
+   if (!wdir)
+     return NULL;
+
+   h = FindFirstFile(wdir, fd);
+   free(wdir);
+#else
+   h = FindFirstFile(dir, fd);
+#endif
+
+   if (!h)
+     return NULL;
+
+   while ((fd->cFileName[0] == '.') &&
+          ((fd->cFileName[1] == '\0') ||
+           ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0'))))
+     {
+        if (!FindNextFile(h, fd))
+          return NULL;
+     }
+
+   return h;
+}
+
+static Eina_Bool
+_eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data)
+{
+#ifdef UNICODE
+   wchar_t  *old_name;
+#else
+   char     *old_name;
+#endif
+   char     *name;
+   char     *cname;
+   size_t    length;
+   Eina_Bool is_last;
+   Eina_Bool res = EINA_TRUE;
+
+   if (it->handle == INVALID_HANDLE_VALUE)
+     return EINA_FALSE;
+
+   is_last = it->is_last;
+#ifdef UNICODE
+   old_name = _wcsdup(it->data.cFileName);
+#else
+   old_name = _strdup(it->data.cFileName);
+#endif
+   if (!old_name)
+     return EINA_FALSE;
+
+   do {
+      if (!FindNextFile(it->handle, &it->data))
+        {
+           if (GetLastError() == ERROR_NO_MORE_FILES)
+             it->is_last = EINA_TRUE;
+           else
+             res = EINA_FALSE;
+        }
+   } while ((it->data.cFileName[0] == '.') &&
+            ((it->data.cFileName[1] == '\0') ||
+             ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
+
+#ifdef UNICODE
+   cname = evil_wchar_to_char(old_name);
+   if (!cname)
+     return EINA_FALSE;
+#else
+     cname = old_name;
+#endif
+
+   length = strlen(cname);
+   name = alloca(length + 2 + it->length);
+
+   memcpy(name,                  it->dir, it->length);
+   memcpy(name + it->length,     "\\",    1);
+   memcpy(name + it->length + 1, cname,   length + 1);
+
+   *data = (char *)eina_stringshare_add(name);
+
+#ifdef UNICODE
+   free(cname);
+#endif
+   free(old_name);
+
+   if (is_last)
+     res = EINA_FALSE;
+
+   return res;
+}
+
+static HANDLE
+_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it)
+{
+   return it->handle;
+}
+
+static void
+_eina_file_win32_ls_iterator_free(Eina_File_Iterator *it)
+{
+   if (it->handle != INVALID_HANDLE_VALUE)
+     FindClose(it->handle);
+
+   EINA_MAGIC_SET(&it->iterator, 0);
+   free(it);
+}
+
+static Eina_Bool
+_eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
+{
+#ifdef UNICODE
+   wchar_t  *old_name;
+#else
+   char     *old_name;
+#endif
+   char     *cname;
+   size_t    length;
+   DWORD     attr;
+   Eina_Bool is_last;
+   Eina_Bool res = EINA_TRUE;
+
+   if (it->handle == INVALID_HANDLE_VALUE)
+     return EINA_FALSE;
+
+   attr = it->data.dwFileAttributes;
+   is_last = it->is_last;
+#ifdef UNICODE
+   old_name = _wcsdup(it->data.cFileName);
+#else
+   old_name = _strdup(it->data.cFileName);
+#endif
+   if (!old_name)
+     return EINA_FALSE;
+
+   do {
+      if (!FindNextFile(it->handle, &it->data))
+        {
+           if (GetLastError() == ERROR_NO_MORE_FILES)
+             it->is_last = EINA_TRUE;
+           else
+             res = EINA_FALSE;
+        }
+
+#ifdef UNICODE
+     length = wcslen(old_name);
+#else
+     length = strlen(old_name);
+#endif
+     if (it->info.name_start + length + 1 >= PATH_MAX)
+       {
+          free(old_name);
+#ifdef UNICODE
+          old_name = _wcsdup(it->data.cFileName);
+#else
+          old_name = _strdup(it->data.cFileName);
+#endif
+          continue;
+       }
+
+   } while ((it->data.cFileName[0] == '.') &&
+            ((it->data.cFileName[1] == '\0') ||
+             ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
+
+#ifdef UNICODE
+   cname = evil_wchar_to_char(old_name);
+   if (!cname)
+     return EINA_FALSE;
+#else
+     cname = old_name;
+#endif
+
+   memcpy(it->info.path + it->info.name_start, cname, length);
+   it->info.name_length = length;
+   it->info.path_length = it->info.name_start + length;
+   it->info.path[it->info.path_length] = '\0';
+
+   if (attr & FILE_ATTRIBUTE_DIRECTORY)
+     it->info.type = EINA_FILE_DIR;
+   else if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
+     it->info.type = EINA_FILE_LNK;
+   else if (attr & (FILE_ATTRIBUTE_ARCHIVE |
+                    FILE_ATTRIBUTE_COMPRESSED |
+                    FILE_ATTRIBUTE_COMPRESSED |
+                    FILE_ATTRIBUTE_HIDDEN |
+                    FILE_ATTRIBUTE_NORMAL |
+                    FILE_ATTRIBUTE_SPARSE_FILE |
+                    FILE_ATTRIBUTE_TEMPORARY))
+     it->info.type = EINA_FILE_REG;
+   else
+     it->info.type = EINA_FILE_UNKNOWN;
+
+   *data = &it->info;
+
+#ifdef UNICODE
+   free(cname);
+#endif
+
+   free(old_name);
+
+   if (is_last)
+     res = EINA_FALSE;
+
+   return res;
+}
+
+static HANDLE
+_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
+{
+   return it->handle;
+}
+
+static void
+_eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
+{
+   if (it->handle != INVALID_HANDLE_VALUE)
+     FindClose(it->handle);
+
+   EINA_MAGIC_SET(&it->iterator, 0);
+   free(it);
+}
+
+static void
+_eina_file_real_close(Eina_File *file)
+{
+   eina_hash_free(file->rmap);
+   eina_hash_free(file->map);
+
+   if (file->global_map != MAP_FAILED)
+     UnmapViewOfFile(file->global_map);
+
+   CloseHandle(file->fm);
+   CloseHandle(file->handle);
+
+   eina_stringshare_del(file->filename);
+
+   free(file);
+}
+
+static void
+_eina_file_map_close(Eina_File_Map *map)
+{
+   if (map->map != MAP_FAILED)
+     UnmapViewOfFile(map->map);
+   free(map);
+}
+
+static unsigned int
+_eina_file_map_key_length(const void *key __UNUSED__)
+{
+   return sizeof (unsigned long int) * 2;
+}
+
+static int
+_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__,
+                       const unsigned long int *key2, int key2_length __UNUSED__)
+{
+   if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
+   return key1[0] - key2[0];
+}
+
+static int
+_eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__)
+{
+   return eina_hash_int64(&key[0], sizeof (unsigned long int))
+     ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
+}
+
+static char *
+_eina_file_win32_escape(const char *path, size_t *length)
+{
+   char *result = strdup(path ? path : "");
+   char *p = result;
+   char *q = result;
+   size_t len;
+
+   if (!result)
+     return NULL;
+
+   if (length) len = *length;
+   else len = strlen(result);
+
+   while ((p = strchr(p, '/')))
+     {
+        // remove double `/'
+        if (p[1] == '/')
+          {
+             memmove(p, p + 1, --len - (p - result));
+             result[len] = '\0';
+          }
+        else
+          if (p[1] == '.'
+              && p[2] == '.')
+            {
+               // remove `/../'
+               if (p[3] == '/')
+                 {
+                    char tmp;
+
+                    len -= p + 3 - q;
+                    memmove(q, p + 3, len - (q - result));
+                    result[len] = '\0';
+                    p = q;
+
+                    /* Update q correctly. */
+                    tmp = *p;
+                    *p = '\0';
+                    q = strrchr(result, '/');
+                    if (!q) q = result;
+                    *p = tmp;
+                 }
+               else
+                 // remove '/..$'
+                 if (p[3] == '\0')
+                   {
+                      len -= p + 2 - q;
+                      result[len] = '\0';
+                      q = p;
+                      ++p;
+                   }
+                 else
+                   {
+                      q = p;
+                      ++p;
+                   }
+            }
+          else
+            {
+               q = p;
+               ++p;
+            }
+     }
+
+   if (length)
+     *length = len;
+
+   return result;
+}
+
+
+/**
+ * @endcond
+ */
+
+/*============================================================================*
+ *                                 Global                                     *
+ *============================================================================*/
+
+Eina_Bool
+eina_file_init(void)
+{
+   _eina_file_log_dom = eina_log_domain_register("eina_file",
+                                                 EINA_LOG_COLOR_DEFAULT);
+   if (_eina_file_log_dom < 0)
+     {
+        EINA_LOG_ERR("Could not register log domain: eina_file");
+        return EINA_FALSE;
+     }
+
+   _eina_file_cache = eina_hash_string_djb2_new(NULL);
+   if (!_eina_file_cache)
+     {
+        ERR("Could not create cache.");
+        eina_log_domain_unregister(_eina_file_log_dom);
+        _eina_file_log_dom = -1;
+        return EINA_FALSE;
+     }
+
+   eina_lock_new(&_eina_file_lock_cache);
+
+   return EINA_TRUE;
+}
+
+Eina_Bool
+eina_file_shutdown(void)
+{
+   if (eina_hash_population(_eina_file_cache) > 0)
+     {
+        Eina_Iterator *it;
+        const char *key;
+
+        it = eina_hash_iterator_key_new(_eina_file_cache);
+        EINA_ITERATOR_FOREACH(it, key)
+          ERR("File [%s] still open !", key);
+        eina_iterator_free(it);
+     }
+
+   eina_hash_free(_eina_file_cache);
+
+   eina_lock_free(&_eina_file_lock_cache);
+
+   eina_log_domain_unregister(_eina_file_log_dom);
+   _eina_file_log_dom = -1;
+   return EINA_TRUE;
+}
+
+/*============================================================================*
+ *                                   API                                      *
+ *============================================================================*/
+
+
+EAPI char *
+eina_file_path_sanitize(const char *path)
+{
+   char *result = NULL;
+   size_t len;
+
+   if (!path) return NULL;
+
+   len = strlen(path);
+   if (len < 3) return NULL;
+
+   if (!evil_path_is_absolute(path))
+     {
+        DWORD l;
+
+        l = GetCurrentDirectory(0, NULL);
+        if (l > 0)
+          {
+             char *cwd;
+             DWORD l2;
+
+             cwd = alloca(sizeof(char) * (l + 1));
+             l2 = GetCurrentDirectory(l + 1, cwd);
+             if (l2 == l)
+               {
+                  char *tmp;
+
+                  len += l + 2;
+                  tmp = alloca(sizeof (char) * len);
+                  snprintf(tmp, len, "%s/%s", cwd, path);
+                  tmp[len - 1] = '\0';
+                  result = tmp;
+               }
+          }
+     }
+
+   return _eina_file_win32_escape(result ? result : path, &len);
+}
+
+EAPI Eina_Bool
+eina_file_dir_list(const char *dir,
+                   Eina_Bool recursive,
+                   Eina_File_Dir_List_Cb cb,
+                   void *data)
+{
+   WIN32_FIND_DATA file;
+   HANDLE h;
+   char *new_dir;
+
+   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);
+
+   if (!_eina_file_win32_is_dir(dir))
+     return EINA_FALSE;
+
+   new_dir = _eina_file_win32_dir_new(dir);
+   if (!new_dir)
+      return EINA_FALSE;
+
+   h = _eina_file_win32_first_file(new_dir, &file);
+
+   if (h == INVALID_HANDLE_VALUE)
+      return EINA_FALSE;
+
+   do
+     {
+        char *filename;
+
+# ifdef UNICODE
+        filename = evil_wchar_to_char(file.cFileName);
+# else
+        filename = file.cFileName;
+# endif /* ! UNICODE */
+        if (!strcmp(filename, ".") || !strcmp(filename, ".."))
+           continue;
+
+        cb(filename, dir, data);
+
+        if (recursive == EINA_TRUE)
+          {
+             char *path;
+
+             path = alloca(strlen(dir) + strlen(filename) + 2);
+             strcpy(path, dir);
+             strcat(path, "/");
+             strcat(path, filename);
+
+             if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+                continue;
+
+             eina_file_dir_list(path, recursive, cb, data);
+          }
+
+# ifdef UNICODE
+        free(filename);
+# endif /* UNICODE */
+
+     } while (FindNextFile(h, &file));
+   FindClose(h);
+
+   return EINA_TRUE;
+}
+
+EAPI Eina_Array *
+eina_file_split(char *path)
+{
+   Eina_Array *ea;
+   char *current;
+   size_t length;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+
+   ea = eina_array_new(16);
+
+   if (!ea)
+      return NULL;
+
+   for (current = strchr(path, '\\');
+        current;
+        path = current + 1, current = strchr(path, '\\'))
+     {
+        length = current - path;
+
+        if (length <= 0)
+           continue;
+
+        eina_array_push(ea, path);
+        *current = '\0';
+     }
+
+   if (*path != '\0')
+        eina_array_push(ea, path);
+
+   return ea;
+}
+
+EAPI Eina_Iterator *
+eina_file_ls(const char *dir)
+{
+   Eina_File_Iterator *it;
+   char               *new_dir;
+   size_t              length;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
+
+   if (!dir || !*dir)
+      return NULL;
+
+   if (!_eina_file_win32_is_dir(dir))
+     return NULL;
+
+   length = strlen(dir);
+
+   it = calloc(1, sizeof (Eina_File_Iterator) + length);
+   if (!it)
+      return NULL;
+
+   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+
+   new_dir = _eina_file_win32_dir_new(dir);
+   if (!new_dir)
+      goto free_it;
+
+   it->handle = _eina_file_win32_first_file(new_dir, &it->data);
+   free(new_dir);
+   if (it->handle == INVALID_HANDLE_VALUE)
+     goto free_it;
+
+   memcpy(it->dir, dir, length + 1);
+   if (dir[length - 1] != '\\')
+      it->length = length;
+   else
+      it->length = length - 1;
+   _eina_file_win32_backslash_change(it->dir);
+
+   it->iterator.version = EINA_ITERATOR_VERSION;
+   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next);
+   it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free);
+
+   return &it->iterator;
+
+ free_it:
+   free(it);
+
+   return NULL;
+}
+
+EAPI Eina_Iterator *
+eina_file_direct_ls(const char *dir)
+{
+   Eina_File_Direct_Iterator *it;
+   char                      *new_dir;
+   size_t                     length;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
+
+   if (!dir || !*dir)
+      return NULL;
+
+   length = strlen(dir);
+
+   if (length + 12 + 2 >= MAX_PATH)
+      return NULL;
+
+   it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length);
+   if (!it)
+      return NULL;
+
+   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+
+   new_dir = _eina_file_win32_dir_new(dir);
+   if (!new_dir)
+      goto free_it;
+
+   it->handle = _eina_file_win32_first_file(new_dir, &it->data);
+   free(new_dir);
+   if (it->handle == INVALID_HANDLE_VALUE)
+     goto free_it;
+
+   memcpy(it->dir, dir, length + 1);
+   it->length = length;
+   _eina_file_win32_backslash_change(it->dir);
+
+   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;
+     }
+   _eina_file_win32_backslash_change(it->info.path);
+
+   it->iterator.version = EINA_ITERATOR_VERSION;
+   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next);
+   it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free);
+
+   return &it->iterator;
+
+ free_it:
+   free(it);
+
+   return NULL;
+}
+
+EAPI Eina_Iterator *
+eina_file_stat_ls(const char *dir)
+{
+   return eina_file_direct_ls(dir);
+}
+
+EAPI Eina_File *
+eina_file_open(const char *path, Eina_Bool shared)
+{
+   Eina_File *file;
+   Eina_File *n;
+   char *filename;
+   HANDLE handle;
+   HANDLE fm;
+   WIN32_FILE_ATTRIBUTE_DATA fad;
+   ULARGE_INTEGER length;
+   ULARGE_INTEGER mtime;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+
+   filename = eina_file_path_sanitize(path);
+   if (!filename) return NULL;
+
+   /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */
+#if 0
+   if (shared)
+     handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
+                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
+                         NULL);
+   else
+#endif
+     handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
+                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
+                         NULL);
+
+   if (handle == INVALID_HANDLE_VALUE)
+     return NULL;
+
+   fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL);
+   if (!fm)
+     goto close_handle;
+
+   if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad))
+     goto close_fm;
+
+   length.u.LowPart = fad.nFileSizeLow;
+   length.u.HighPart = fad.nFileSizeHigh;
+   mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime;
+   mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime;
+
+   eina_lock_take(&_eina_file_lock_cache);
+
+   file = eina_hash_find(_eina_file_cache, filename);
+   if (file &&
+       (file->mtime == mtime.QuadPart && file->length == length.QuadPart))
+     {
+        file->delete_me = EINA_TRUE;
+        eina_hash_del(_eina_file_cache, file->filename, file);
+        _eina_file_real_close(file);
+        file = NULL;
+     }
+
+   if (!file)
+     {
+        n = malloc(sizeof (Eina_File) + strlen(filename) + 1);
+        if (!n)
+          {
+             eina_lock_release(&_eina_file_lock_cache);
+             goto close_fm;
+          }
+
+        n->filename = (char*) (n + 1);
+        strcpy((char*) n->filename, filename);
+        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),
+                               EINA_FREE_CB(_eina_file_map_close),
+                               3);
+        n->rmap = eina_hash_pointer_new(NULL);
+        n->global_map = MAP_FAILED;
+        n->global_refcount = 0;
+        n->length = length.QuadPart;
+        n->mtime = mtime.QuadPart;
+        n->refcount = 0;
+        n->handle = handle;
+        n->fm = fm;
+        n->shared = shared;
+        n->delete_me = EINA_FALSE;
+        eina_lock_new(&n->lock);
+        eina_hash_direct_add(_eina_file_cache, n->filename, n);
+     }
+   else
+     {
+        CloseHandle(fm);
+        CloseHandle(handle);
+
+        n = file;
+     }
+   eina_lock_take(&n->lock);
+   n->refcount++;
+   eina_lock_release(&n->lock);
+
+   eina_lock_release(&_eina_file_lock_cache);
+
+   free(filename);
+
+   return n;
+
+ close_fm:
+   CloseHandle(fm);
+ close_handle:
+   CloseHandle(handle);
+
+   return NULL;
+}
+
+EAPI void
+eina_file_close(Eina_File *file)
+{
+   EINA_SAFETY_ON_NULL_RETURN(file);
+
+   eina_lock_take(&file->lock);
+   file->refcount--;
+   eina_lock_release(&file->lock);
+
+   if (file->refcount != 0) return ;
+   eina_lock_take(&_eina_file_lock_cache);
+
+   eina_hash_del(_eina_file_cache, file->filename, file);
+   _eina_file_real_close(file);
+
+   eina_lock_release(&_eina_file_lock_cache);
+}
+
+EAPI size_t
+eina_file_size_get(Eina_File *file)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
+   return file->length;
+}
+
+EAPI time_t
+eina_file_mtime_get(Eina_File *file)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
+  return file->mtime;
+}
+
+EAPI const char *
+eina_file_filename_get(Eina_File *file)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
+   return file->filename;
+}
+
+EAPI void *
+eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
+
+   eina_lock_take(&file->lock);
+   if (file->global_map == MAP_FAILED)
+     {
+        void  *data;
+
+        data = MapViewOfFile(file->fm, FILE_MAP_READ,
+                             0, 0, file->length);
+        if (!data)
+          file->global_map = MAP_FAILED;
+        else
+          file->global_map = data;
+     }
+
+   if (file->global_map != MAP_FAILED)
+     {
+        file->global_refcount++;
+        return file->global_map;
+     }
+
+   eina_lock_release(&file->lock);
+   return NULL;
+}
+
+EAPI void *
+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];
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
+
+   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);
+
+   key[0] = offset;
+   key[1] = length;
+
+   eina_lock_take(&file->lock);
+
+   map = eina_hash_find(file->map, &key);
+   if (!map)
+     {
+        void  *data;
+
+        map = malloc(sizeof (Eina_File_Map));
+        if (!map) return NULL;
+
+        data = MapViewOfFile(file->fm, FILE_MAP_READ,
+                             offset & 0xffff0000,
+                             offset & 0x0000ffff,
+                             length);
+        if (!data)
+          map->map = MAP_FAILED;
+        else
+          map->map = data;
+
+        map->offset = offset;
+        map->length = length;
+        map->refcount = 0;
+
+        if (map->map == MAP_FAILED)
+          {
+             free(map);
+             return NULL;
+          }
+
+        eina_hash_add(file->map, &key, map);
+        eina_hash_direct_add(file->rmap, map->map, map);
+     }
+
+   map->refcount++;
+
+   eina_lock_release(&file->lock);
+
+   return map->map;
+}
+
+EAPI void
+eina_file_map_free(Eina_File *file, void *map)
+{
+   EINA_SAFETY_ON_NULL_RETURN(file);
+
+   eina_lock_take(&file->lock);
+
+   if (file->global_map == map)
+     {
+        file->global_refcount--;
+
+        if (file->global_refcount > 0) goto on_exit;
+
+        UnmapViewOfFile(file->global_map);
+        file->global_map = MAP_FAILED;
+     }
+   else
+     {
+        Eina_File_Map *em;
+        unsigned long int key[2];
+
+        em = eina_hash_find(file->rmap, &map);
+        if (!em) return ;
+
+        em->refcount--;
+
+        if (em->refcount > 0) goto on_exit;
+
+        key[0] = em->offset;
+        key[1] = em->length;
+
+        eina_hash_del(file->rmap, &map, em);
+        eina_hash_del(file->map, &key, em);
+     }
+
+ on_exit:
+   eina_lock_release(&file->lock);
+}


Make libconfuse config, opts, static; fix warning

--- src/cfgfile.c
+++ src/cfgfile.c
@@ -367,7 +367,7 @@
     const char *resource_name = cfg_title(sec);

     cfg_t *resource;
-    int i = 0;
+    unsigned int i = 0;
     while ((resource = cfg_getnsec(toplevel_cfg, "file-resource", i)) != NULL) {
         if (strcmp(cfg_title(resource), resource_name) == 0)
             return 0;
@@ -510,7 +510,7 @@
     CFG_IGNORE_UNKNOWN
     CFG_END()
 };
-cfg_opt_t opts[] = {
+static cfg_opt_t opts[] = {
     CFG_STR("meta-product", 0, CFGF_NONE),
     CFG_STR("meta-description", 0, CFGF_NONE),
     CFG_STR("meta-version", 0, CFGF_NONE),


app: Missing newline

app: Missing newline

--- app/main.c
+++ app/main.c
@@ -108,7 +108,7 @@
     remote = one_video_remote_peer_new (local, remotes[index]);
     one_video_local_peer_add_remote (local, remote);

-    g_print ("Created and added remote peer %s", remote->addr_s);
+    g_print ("Created and added remote peer %s\n", remote->addr_s);
   }

   one_video_local_peer_negotiate_async (local, NULL, on_negotiate_done, NULL);


drivers: clock_control: stm32f0/f3: streamline PREDIV handling

We should not set PLLSRC bits here. It is done by
LL_PLL_ConfigSystemClock_* functions which are called later.
Also, PREDIV1 setting should not be restricted to HSE only.

Signed-off-by: Ilya Tagunov <02c7836785d92ca00f3c30970df9a16046e29b0e@gmail.com>

--- drivers/clock_control/clock_stm32f0_f3.c
+++ drivers/clock_control/clock_stm32f0_f3.c
@@ -30,37 +30,24 @@
 	 */
 	pllinit->PLLMul = ((CONFIG_CLOCK_STM32_PLL_MULTIPLIER - 2)
 					<< RCC_CFGR_PLLMUL_Pos);
-#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
-	/* PREDIV support is a specific RCC configuration present on */
-	/* following SoCs: STM32F070x6, STM32F070xB and STM32F030xC */
-	/* cf Reference manual for more details */
-#if defined(CONFIG_CLOCK_STM32_PLL_SRC_HSI)
-	pllinit->PLLDiv = LL_RCC_PLLSOURCE_HSI;
-#else

-#if defined(CONFIG_CLOCK_STM32_PLL_PREDIV1)
 	/*
-	 * PLL DIV
-	 * 1  -> LL_RCC_PLLSOURCE_HSE_DIV_1  -> 0x00010000
-	 * 2  -> LL_RCC_PLLSOURCE_HSE_DIV_2  -> 0x00010001
-	 * 3  -> LL_RCC_PLLSOURCE_HSE_DIV_3  -> 0x00010002
-	 * ...
-	 * 16 -> LL_RCC_PLLSOURCE_HSE_DIV_16 -> 0x0001000F
-	 */
-	pllinit->PLLDiv = (RCC_CFGR_PLLSRC_HSE_PREDIV |
-					(CONFIG_CLOCK_STM32_PLL_PREDIV1 - 1));
-#endif /* CONFIG_CLOCK_STM32_PLL_PREDIV1 */
-
-#endif /* CONFIG_CLOCK_STM32_PLL_SRC_HSI */
-#else
-	/*
-	 * PLL Prediv
+	 * PLL PREDIV
 	 * 1  -> LL_RCC_PREDIV_DIV_1  -> 0x00000000
 	 * 2  -> LL_RCC_PREDIV_DIV_2  -> 0x00000001
 	 * 3  -> LL_RCC_PREDIV_DIV_3  -> 0x00000002
 	 * ...
 	 * 16 -> LL_RCC_PREDIV_DIV_16 -> 0x0000000F
 	 */
+#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
+	/*
+	 * PREDIV1 support is a specific RCC configuration present on
+	 * following SoCs: STM32F04xx, STM32F07xx, STM32F09xx,
+	 * STM32F030xC, STM32F302xE, STM32F303xE and STM32F39xx
+	 * cf Reference manual for more details
+	 */
+	pllinit->PLLDiv = CONFIG_CLOCK_STM32_PLL_PREDIV1 - 1;
+#else
 	pllinit->Prediv = CONFIG_CLOCK_STM32_PLL_PREDIV - 1;
 #endif /* RCC_PLLSRC_PREDIV1_SUPPORT */
 }


drm/amdkfd: Remove unessary void pointer cast

kmalloc() returns a void pointer - no need to cast it in
drivers/gpu/drm/amd/amdkfd/kfd_process.c::kfd_process_destroy_delayed()

Signed-off-by: Firo Yang <827495a222d0086ae863c74ccd3d093f23b2b6f6@gmail.com>
Signed-off-by: Oded Gabbay <c2fce4493a16d94b58efb315151c29911fc5d347@amd.com>

--- drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -203,8 +203,7 @@

 	mmdrop(p->mm);

-	work = (struct kfd_process_release_work *)
-		kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC);
+	work = kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC);

 	if (work) {
 		INIT_WORK((struct work_struct *) work, kfd_process_wq_release);


drm/exynos: pass the correct pipe number

Instead of giving -1 to as arg to  drm_send_vblank_event() pass the
correct pipe number to it.

Signed-off-by: Gustavo Padovan <029a69b25713d0799b81c0a39685b4c040fa1425@collabora.co.uk>
Reviewed-by: Joonyoung Shim <b2207686f8c5343cf0f505ae1d5720ecb0c3202a@samsung.com>
Signed-off-by: Inki Dae <bae4a7a27bbc965064e97edd6e179ac4979db440@samsung.com>

--- drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -205,7 +205,7 @@
 	spin_lock_irqsave(&dev->event_lock, flags);
 	if (exynos_crtc->event) {

-		drm_send_vblank_event(dev, -1, exynos_crtc->event);
+		drm_send_vblank_event(dev, pipe, exynos_crtc->event);
 		drm_vblank_put(dev, pipe);
 		wake_up(&exynos_crtc->pending_flip_queue);


drm/exynos/fimd: don't initialize 'ret' variable in fimd_probe()

We  set it in the beginning of the function, thus no need to set it at
initialization.

Signed-off-by: Gustavo Padovan <029a69b25713d0799b81c0a39685b4c040fa1425@collabora.co.uk>
Signed-off-by: Inki Dae <bae4a7a27bbc965064e97edd6e179ac4979db440@samsung.com>

--- drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1108,7 +1108,7 @@
 	struct fimd_context *ctx;
 	struct device_node *i80_if_timings;
 	struct resource *res;
-	int ret = -EINVAL;
+	int ret;

 	if (!dev->of_node)
 		return -ENODEV;


drm/exynos/vidi: remove useless ops->commit()

vidi_commit does nothing, remove it and its callers.

Signed-off-by: Gustavo Padovan <029a69b25713d0799b81c0a39685b4c040fa1425@collabora.co.uk>
Signed-off-by: Inki Dae <bae4a7a27bbc965064e97edd6e179ac4979db440@samsung.com>

--- drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -115,17 +115,6 @@
 		if (win_data->enabled && (mgr_ops && mgr_ops->win_commit))
 			mgr_ops->win_commit(mgr, i);
 	}
-
-	if (mgr_ops && mgr_ops->commit)
-		mgr_ops->commit(mgr);
-}
-
-static void vidi_commit(struct exynos_drm_manager *mgr)
-{
-	struct vidi_context *ctx = manager_to_vidi(mgr);
-
-	if (ctx->suspended)
-		return;
 }

 static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
@@ -320,7 +309,6 @@

 static struct exynos_drm_manager_ops vidi_manager_ops = {
 	.dpms = vidi_dpms,
-	.commit = vidi_commit,
 	.enable_vblank = vidi_enable_vblank,
 	.disable_vblank = vidi_disable_vblank,
 	.win_mode_set = vidi_win_mode_set,


ARC: Accommodate TLS fix in Binutils

ARC: Accommodate TLS fix in Binutils

[1] fixes clash of TLS variables on ARC and since LD now calculates relocations
a bit different now we need to update dynamic loader as well otherwise relocs
will be calculated improperly.

Note this is an ABI change and should go in-line with corresponding ARC tools.
That said either arc-2018.09 (to be released in few weeks) or the next version of upstream
Binutils (2.32) are required for normal TLS work on ARC.

Testcase:
----------------------------------8<-------------------------------
#include <stdio.h>
int foo3(void);
int foo1(void);

#ifdef _SHARED
int foo1(){
	static __thread int val3=1;
	val3 += 2;
	return val3;
}

#elif _SHARED2
int foo3(){
	static __thread int val2=0;
	val2 += 2;
	return val2;
}
#else
int main(){
	printf("foo1 = %d \n", foo1());
	printf("foo3 = %d \n", foo3());
	return 0;
}
#endif
--------------------------------->8---------------------------------------

The result shoud be:
----8<----
foo1 = 3
foo3 = 2
---->8----

Commands to build artefacts:
----------------------------------------8<-------------------------------
arc-linux-gcc -fPIE -ffunction-sections  -fdata-sections  -pthread  -Os \
	 -fPIC -o testtls.o -D_SHARED -c tst.c
arc-linux-gcc -fPIE -ffunction-sections  -fdata-sections  -pthread  -Os \
	 -fPIC -o testtls2.o -D_SHARED2 -c tst.c
arc-linux-gcc  -shared -o libtesttls.so  testtls.o testtls2.o -lm -Os
arc-linux-gcc tst.c  -o tst.out -L./ -ltesttls -Os -fPIE
--------------------------------->8---------------------------------------

Add path to libtesttls.so file to LD_LIBRARY_PATH before runnig
tst.out application.

[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=714e9a954a2e4123dcb26bb8da850e1344de4f5f

Signed-off-by: Alexey Brodkin <1fa739873496c8c0c1b521f2061ee5fa4a0306e8@synopsys.com>
Signed-off-by: Evgeniy Didin <5435af8d1d1b65d63b9ec68a39e143f1f5881d59@synopsys.com>
CC: Cupertino Miranda <414c547048e5fe717c89ee06d956a0229f7d5eb5@synopsys.com>
CC: Vineet Gupta <af669d95a4c0de051445d4cafdbb2c5c4a2838be@synopsys.com>
CC: Waldemar Brodkorb <9eafb392c2f563112237e0f5b2d5b6a33ad4e183@uclibc-ng.org>

--- ldso/ldso/arc/elfinterp.c
+++ ldso/ldso/arc/elfinterp.c
@@ -165,7 +165,7 @@
 		*reloc_addr = tls_tpnt->l_tls_modid;
 		break;
 	case R_ARC_TLS_DTPOFF:
-		*reloc_addr = symbol_addr;
+		*reloc_addr += symbol_addr;
 		break;
 	case R_ARC_TLS_TPOFF:
 		CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);


Fix the handling of \324 for computing the length

\324 means REX.W is mandatory, but that doesn't mean add a byte to the
output!  Instead, force REX.W set, and let the REX logic deal with the
length.

--- assemble.c
+++ assemble.c
@@ -695,9 +695,9 @@
     int32_t length = 0;
     uint8_t c;
     int t;
-    ins->rex = 0;               /* Ensure REX is reset */
     int rex_mask = 0xFF;
     int lock_is_rex_r = 0;
+    ins->rex = 0;               /* Ensure REX is reset */

     (void)segment;              /* Don't warn that this parameter is unused */
     (void)offset;               /* Don't warn that this parameter is unused */
@@ -860,8 +860,8 @@
             rex_mask = 0x07;
             break;
         case 0324:
-            length++;
-            break;
+	    ins->rex |= 0xF8;
+            break;
         case 0330:
             codes++, length++;
             break;
@@ -919,10 +919,12 @@
     ins->rex &= rex_mask;
     if (ins->rex) {
 	if (bits == 64 ||
-	    (lock_is_rex_r && ins->rex == 0xf4 && cpu >= IF_X86_64))
+	    (lock_is_rex_r && ins->rex == 0xf4 && cpu >= IF_X86_64)) {
 	    length++;
-	else
-	    errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
+	} else {
+	  errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
+	  return -1;
+	}
     }

     return length;


drm/radeon/dpm: fix atom vram table parsing

Parsing the table in incorrectly led to problems with
certain asics with mclk switching.

Signed-off-by: Alex Deucher <08dc22c6156113f2deff178e35e3ed9b24d6af9e@amd.com>

--- drivers/gpu/drm/radeon/radeon_atombios.c
+++ drivers/gpu/drm/radeon/radeon_atombios.c
@@ -3513,7 +3513,6 @@
 	u8 frev, crev, i;
 	u16 data_offset, size;
 	union vram_info *vram_info;
-	u8 *p;

 	memset(mem_info, 0, sizeof(struct atom_memory_info));

@@ -3529,13 +3528,12 @@
 				if (module_index < vram_info->v1_3.ucNumOfVRAMModule) {
 					ATOM_VRAM_MODULE_V3 *vram_module =
 						(ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo;
-					p = (u8 *)vram_info->v1_3.aVramInfo;

 					for (i = 0; i < module_index; i++) {
-						vram_module = (ATOM_VRAM_MODULE_V3 *)p;
 						if (le16_to_cpu(vram_module->usSize) == 0)
 							return -EINVAL;
-						p += le16_to_cpu(vram_module->usSize);
+						vram_module = (ATOM_VRAM_MODULE_V3 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usSize));
 					}
 					mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf;
 					mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0;
@@ -3547,13 +3545,12 @@
 				if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
 					ATOM_VRAM_MODULE_V4 *vram_module =
 						(ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
-					p = (u8 *)vram_info->v1_4.aVramInfo;

 					for (i = 0; i < module_index; i++) {
-						vram_module = (ATOM_VRAM_MODULE_V4 *)p;
 						if (le16_to_cpu(vram_module->usModuleSize) == 0)
 							return -EINVAL;
-						p += le16_to_cpu(vram_module->usModuleSize);
+						vram_module = (ATOM_VRAM_MODULE_V4 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
 					}
 					mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
 					mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
@@ -3572,13 +3569,12 @@
 				if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
 					ATOM_VRAM_MODULE_V7 *vram_module =
 						(ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo;
-					p = (u8 *)vram_info->v2_1.aVramInfo;

 					for (i = 0; i < module_index; i++) {
-						vram_module = (ATOM_VRAM_MODULE_V7 *)p;
 						if (le16_to_cpu(vram_module->usModuleSize) == 0)
 							return -EINVAL;
-						p += le16_to_cpu(vram_module->usModuleSize);
+						vram_module = (ATOM_VRAM_MODULE_V7 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
 					}
 					mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
 					mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
@@ -3628,21 +3624,19 @@
 				if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
 					ATOM_VRAM_MODULE_V4 *vram_module =
 						(ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
-					ATOM_MEMORY_TIMING_FORMAT *format;
-					p = (u8 *)vram_info->v1_4.aVramInfo;

 					for (i = 0; i < module_index; i++) {
-						vram_module = (ATOM_VRAM_MODULE_V4 *)p;
 						if (le16_to_cpu(vram_module->usModuleSize) == 0)
 							return -EINVAL;
-						p += le16_to_cpu(vram_module->usModuleSize);
+						vram_module = (ATOM_VRAM_MODULE_V4 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
 					}
 					mclk_range_table->num_entries = (u8)
 						((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) /
 						 mem_timing_size);
-					p = (u8 *)vram_module->asMemTiming;
+					p = (u8 *)&vram_module->asMemTiming[0];
 					for (i = 0; i < mclk_range_table->num_entries; i++) {
-						format = (ATOM_MEMORY_TIMING_FORMAT *)p;
+						ATOM_MEMORY_TIMING_FORMAT *format = (ATOM_MEMORY_TIMING_FORMAT *)p;
 						mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);
 						p += mem_timing_size;
 					}


Drop unused 'type' from gencode

Drop unused 'type' from gencode

Signed-off-by: Cyrill Gorcunov <7a1ea01eee6961eb1e372e3508c2670446d086f4@gmail.com>

--- assemble.c
+++ assemble.c
@@ -1788,7 +1788,6 @@
                 opflags_t rflags;
                 uint8_t *p;
                 int32_t s;
-                enum out_type type;
                 struct operand *opy = &ins->oprs[op2];

                 if (c <= 0177) {
@@ -1849,7 +1848,6 @@
                             signed_bits(opy->offset, ea_data.bytes * 8))
                             warn_overflow(ERR_PASS2, ea_data.bytes);

-                        type = OUT_ADDRESS;
                         out(offset, segment, &data, OUT_ADDRESS,
                             ea_data.bytes, opy->segment, opy->wrt);
                     }


APPS/cmp: Simplify read_write_req_resp() - 'req' arg must not be NULL anyway

Reviewed-by: Paul Dale <ddec78389666b4f7c9b4d110380c848489a3e4aa@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17251)

--- apps/cmp.c
+++ apps/cmp.c
@@ -789,8 +789,7 @@
     OSSL_CMP_PKIHEADER *hdr;
     const char *prev_opt_rspin = opt_rspin;

-    if (req != NULL && opt_reqout != NULL
-            && !write_PKIMESSAGE(req, &opt_reqout))
+    if (opt_reqout != NULL && !write_PKIMESSAGE(req, &opt_reqout))
         goto err;
     if (opt_reqin != NULL && opt_rspin == NULL) {
         if ((req_new = read_PKIMESSAGE(&opt_reqin)) == NULL)


RDMA/ocrdma: Always resolve destination mac from GRH for UD QPs

For user applications that use UD QPs, always resolve destination MAC
from the GRH.  This is to avoid failure due to any garbage value in
the attr->dmac.

Signed-off-by: Selvin Xavier <be5a419d60e6c52df4f7ab8e6b65ac3b9455f961@emulex.com>
Signed-off-by: Devesh Sharma <16cc9eb711a83f850aacd9fc3ca2bd5f5ba2a6c6@emulex.com>
Signed-off-by: Roland Dreier <0d270388f2f92757a5de0f4bd891d3b392c44c4f@purestorage.com>


Don't draw on input_only windows

Don't draw on input_only windows

--- gdk/gdkwindow.c
+++ gdk/gdkwindow.c
@@ -5302,7 +5302,7 @@
     {
       if (GDK_WINDOW_IS_MAPPED (window))
 	{
-	  expose = TRUE;
+	  expose = !private->input_only;
 	  old_region = gdk_region_copy (private->clip_region);
 	  /* Adjust region to parent window coords */
 	  gdk_region_offset (old_region, private->x, private->y);
@@ -5314,7 +5314,7 @@
     {
       if (GDK_WINDOW_IS_MAPPED (window))
 	{
-	  expose = TRUE;
+	  expose = !private->input_only;
 	  old_region = gdk_region_copy (private->clip_region);
 	  /* Adjust region to parent window coords */
 	  gdk_region_offset (old_region, private->x, private->y);


multiudpsink: typo fix (bytes send -> bytes sent)

--- gst/udp/gstmultiudpsink.c
+++ gst/udp/gstmultiudpsink.c
@@ -298,7 +298,7 @@
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BYTES_SERVED,
       g_param_spec_uint64 ("bytes-served", "Bytes served",
-          "Total number of bytes send to all clients", 0, G_MAXUINT64, 0,
+          "Total number of bytes sent to all clients", 0, G_MAXUINT64, 0,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_SOCKFD,
       g_param_spec_int ("sockfd", "Socket Handle",


Delete @latexonly part.

Delete @latexonly part.

--- src/charset.c
+++ src/charset.c
@@ -747,8 +747,7 @@
     The symbol #Mcharset_binary has name <tt>"binary"</tt> and
     represents the fake charset which the decoding functions put to an
     M-text as a text property when they encounter an invalid byte
-    (sequence).  See @ref m17nConv @latexonly
-    (P.\pageref{group__m17nConv}) @endlatexonly for more details.  */
+    (sequence).  See @ref m17nConv for more details.  */

 /***ja
     @brief ǥɤǤʤʸʸåȤɽ륷ܥ.
@@ -757,8 +756,7 @@
      (fake) ʸåȤɽ롣ǥɴؿϡM-text Υƥ
     ȥץѥƥȤơ̵ʥХȡʥ󥹡ˤ֤ղä롣

-     ܺ٤ @ref m17nConv @latexonly
-    (P.\pageref{group__m17nConv}) @endlatexonly ȤΤȡ */
+     ܺ٤ @ref m17nConv ȤΤȡ */

 MSymbol Mcharset_binary;


apps/cmp.c: Use enhanced OSSL_HTTP_parse_url(), removing parse_addr() and atoint()

Reviewed-by: Shane Lontis <452ce16516ceed26291fe7de3f8b53540d83864e@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12786)

--- apps/cmp.c
+++ apps/cmp.c
@@ -74,8 +74,7 @@

 /* message transfer */
 static char *opt_server = NULL;
-static char server_port_s[32] = { '\0' };
-static int server_port = 0;
+static char server_port[32] = { '\0' };
 static char *opt_proxy = NULL;
 static char *opt_no_proxy = NULL;
 static char *opt_path = "/";
@@ -889,49 +888,6 @@
     return res;
 }

-/*
- * parse string as integer value, not allowing trailing garbage, see also
- * https://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html
- *
- * returns integer value, or INT_MIN on error
- */
-static int atoint(const char *str)
-{
-    char *tailptr;
-    long res = strtol(str, &tailptr, 10);
-
-    if  ((*tailptr != '\0') || (res < INT_MIN) || (res > INT_MAX))
-        return INT_MIN;
-    else
-        return (int)res;
-}
-
-static int parse_addr(char **opt_string, int port, const char *name)
-{
-    char *port_string;
-
-    if (strncasecmp(*opt_string, OSSL_HTTP_PREFIX,
-                    strlen(OSSL_HTTP_PREFIX)) == 0) {
-        *opt_string += strlen(OSSL_HTTP_PREFIX);
-    } else if (strncasecmp(*opt_string, OSSL_HTTPS_PREFIX,
-                           strlen(OSSL_HTTPS_PREFIX)) == 0) {
-        *opt_string += strlen(OSSL_HTTPS_PREFIX);
-        if (port == 0)
-            port = 443; /* == integer value of OSSL_HTTPS_PORT */
-    }
-
-    if ((port_string = strrchr(*opt_string, ':')) == NULL)
-        return port; /* using default */
-    *(port_string++) = '\0';
-    port = atoint(port_string);
-    if ((port <= 0) || (port > 65535)) {
-        CMP_err2("invalid %s port '%s' given, sane range 1-65535",
-                 name, port_string);
-        return -1;
-    }
-    return port;
-}
-
 static int set1_store_parameters(X509_STORE *ts)
 {
     if (ts == NULL)
@@ -1896,6 +1852,8 @@
 static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
 {
     int ret = 0;
+    char *server = NULL, *port = NULL, *path = NULL;
+    int portnum, ssl;
     char server_buf[200] = { '\0' };
     char proxy_buf[200] = { '\0' };
     char *proxy_host = NULL;
@@ -1904,24 +1862,24 @@
     if (opt_server == NULL) {
         CMP_err("missing server address[:port]");
         goto err;
-    } else if ((server_port =
-                parse_addr(&opt_server, server_port, "server")) < 0) {
-        goto err;
-    }
-    if (server_port != 0)
-        BIO_snprintf(server_port_s, sizeof(server_port_s), "%d", server_port);
-    if (!OSSL_CMP_CTX_set1_server(ctx, opt_server)
-            || !OSSL_CMP_CTX_set_serverPort(ctx, server_port)
+    }
+    if (!OSSL_HTTP_parse_url(opt_server, &server, &port, &portnum, &path, &ssl))
+        goto err;
+    if (ssl && !opt_tls_used) {
+        CMP_err("missing -tls_used option since -server URL indicates https");
+        goto err;
+    }
+    strncpy(server_port, port, sizeof(server_port));
+    if (!OSSL_CMP_CTX_set1_server(ctx, server)
+            || !OSSL_CMP_CTX_set_serverPort(ctx, portnum)
             || !OSSL_CMP_CTX_set1_serverPath(ctx, opt_path))
         goto oom;
     if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy))
         goto oom;
     if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy))
         goto oom;
-    (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s%s%s/%s",
-                       opt_tls_used ? "s" : "", opt_server,
-                       server_port == 0 ? "" : ":", server_port_s,
-                       opt_path == NULL ? "" :
+    (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s:%s/%s",
+                       opt_tls_used ? "s" : "", server, port,
                        opt_path[0] == '/' ? opt_path + 1 : opt_path);

     if (opt_proxy != NULL)
@@ -2023,7 +1981,7 @@
         (void)OSSL_CMP_CTX_set_http_cb_arg(ctx, info);
         /* info will be freed along with CMP ctx */
         info->server = opt_server;
-        info->port = server_port_s;
+        info->port = server_port;
         info->use_proxy = opt_proxy != NULL;
         info->timeout = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT);
         info->ssl_ctx = setup_ssl_ctx(ctx, engine);
@@ -2053,6 +2011,9 @@
     ret = 1;

  err:
+    OPENSSL_free(server);
+    OPENSSL_free(port);
+    OPENSSL_free(path);
     OPENSSL_free(proxy_host);
     OPENSSL_free(proxy_port_str);
     return ret;


input: atmel_mxt_ts: amend finger status check

Touch screen driver checks finger status when releasing unwanted touch
events. Current status check does not cover an unwanted finger status.
This introduces extraneous events when device goes to suspend.

CRs-Fixed: 595019
Change-Id: I3c230cb98d5866edf2bc2f433765f787e518ac93
Signed-off-by: Chun Zhang <1e12ee79693810757a2db1249ffbd23bcb76a0f1@codeaurora.org>

--- drivers/input/touchscreen/atmel_mxt_ts.c
+++ drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -908,7 +908,7 @@
 		status = MXT_RELEASE;
 	}

-	if (status != MXT_RELEASE) {
+	if ((status != MXT_RELEASE) && status) {
 		input_report_abs(input_dev, ABS_X, finger[single_id].x);
 		input_report_abs(input_dev, ABS_Y, finger[single_id].y);
 		input_report_abs(input_dev,


Bitmap BytesPerRow must always be even!

Bitmap BytesPerRow must always be even!

--- a500/sys/gfx.c
+++ a500/sys/gfx.c
@@ -7,12 +7,12 @@
   bitmap->width = width;
   bitmap->height = height;
   bitmap->depth = depth;
-  bitmap->bytesPerRow = (width + 7) / 8;
+  bitmap->bytesPerRow = ((width + 15) & ~15) / 8;
   bitmap->bplSize = bitmap->bytesPerRow * height;
   bitmap->flags = donor->flags;
   bitmap->palette = donor->palette;

-  ITER(i, 0, depth - 1, bitmap->planes[i] = donor->planes[i]);
+  BitmapSetPointers(bitmap, donor->planes[0]);
 }

 __regargs void BitmapSetPointers(BitmapT *bitmap, APTR planes) {
@@ -31,13 +31,13 @@
                                    UBYTE flags)
 {
   BitmapT *bitmap = MemAlloc(sizeof(BitmapT), MEMF_PUBLIC|MEMF_CLEAR);
-  UWORD bytesPerRow = (width + 7) / 8;
+  UWORD bytesPerRow = ((width + 15) & ~15) / 8;

   bitmap->width = width;
   bitmap->height = height;
   bitmap->bytesPerRow = bytesPerRow;
   /* Let's make it aligned to WORD boundary. */
-  bitmap->bplSize = (bytesPerRow * height + 1) & ~1;
+  bitmap->bplSize = bytesPerRow * height;
   bitmap->depth = depth;
   bitmap->flags = flags & BM_FLAGMASK;


Don't destroy NULL region

Don't destroy NULL region

--- gdk/gdkwindow.c
+++ gdk/gdkwindow.c
@@ -6311,7 +6311,8 @@
 				   region,
 				   x, y);

-  gdk_region_destroy (region);
+  if (region)
+    gdk_region_destroy (region);
 }

 /**


* fix for a rare crash; fixes NB#80616.

* fix for a rare crash; fixes NB#80616.

it's debatable whether this bug was not  already fixed by the send-queue fixes done before; but as this crash was seen with W06, there *might* still be a problem.
so, fixing the symptom here. not sure what led to the crash, but it should not happen anymore.

pmo-trunk-r4173

--- src/modest-tny-account-store.c
+++ src/modest-tny-account-store.c
@@ -1348,8 +1348,8 @@
 }

 TnyAccount*
-modest_tny_account_store_get_smtp_specific_transport_account_for_open_connection (ModestTnyAccountStore *self,
-										  const gchar *account_name)
+modest_tny_account_store_get_smtp_specific_transport_account_for_open_connection (
+	ModestTnyAccountStore *self, const gchar *account_name)
 {
 	TnyDevice *device;

@@ -1358,7 +1358,12 @@

 	/* Get the current connection: */
 	device = modest_runtime_get_device ();
-
+
+	if (!device) {
+		g_warning ("%s: could not get device", __FUNCTION__);
+		return NULL;
+	}
+
 	if (!tny_device_is_online (device))
 		return NULL;


docs: upd -> udp and voila it shows up in the docs

--- gst/udp/gstmultiudpsink.c
+++ gst/udp/gstmultiudpsink.c
@@ -19,7 +19,7 @@
  */

 /**
- * SECTION:element-multiupdsink
+ * SECTION:element-multiudpsink
  * @see_also: udpsink, multifdsink
  *
  * multiudpsink is a network sink that sends UDP packets to multiple


fixed type

fixed type


etnaviv: Optimize gem_submit to avoid using heap

--- src/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ src/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -36,27 +36,19 @@

 static struct etnaviv_gem_submit *submit_create(struct drm_device *dev,
 		struct etnaviv_gpu *gpu, size_t nr) {
-	struct etnaviv_gem_submit *submit;
-	size_t sz = size_vstruct(nr, sizeof(submit->bos[0]), sizeof(*submit));
-
-	submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
-	if (submit) {
-		submit->dev = dev;
-		submit->gpu = gpu;
-
-		/* initially, until copy_from_user() and bo lookup succeeds: */
-		submit->nr_bos = 0;
-	} else {
-		log_error("failed to kmalloc()");
-	}
-
-	return submit;
+	/* In current implementation we process single gem_submit
+	 * at any time, so just return static structure instead of malloc */
+	static struct etnaviv_gem_submit submit;
+	memset(&submit, 0, sizeof(submit));
+	submit.dev = dev;
+	submit.gpu = gpu;
+
+	return &submit;
 }

 static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
 	struct drm_file *file, struct drm_etnaviv_gem_submit_bo *submit_bos,
-	unsigned nr_bos)
-{
+	unsigned nr_bos) {
 	struct drm_etnaviv_gem_submit_bo *bo;
 	unsigned i;
 	int ret = 0;


Some refactoring

Some refactoring

--- arch/pic.c
+++ arch/pic.c
@@ -3,18 +3,28 @@
 #include "logger.h"
 #include "asm.h"

+#define PIC_MASTER_COMMAND 0x20
+#define PIC_MASTER_DATA    0x21
+
+#define PIC_SLAVE_COMMAND 0xA0
+#define PIC_SLAVE_DATA    0xA1
+
 void pic_initialize()
 {
     logger_info_from("pic", "Remap the IRQ table.");

-    outportb(0x20, 0x11);
-    outportb(0xA0, 0x11);
-    outportb(0x21, 0x20);
-    outportb(0xA1, 0x28);
-    outportb(0x21, 0x04);
-    outportb(0xA1, 0x02);
-    outportb(0x21, 0x01);
-    outportb(0xA1, 0x01);
-    outportb(0x21, 0x00);
-    outportb(0xA1, 0x00);
+    outportb(PIC_MASTER_COMMAND, 0x11);
+    outportb(PIC_SLAVE_COMMAND,  0x11);
+
+    outportb(PIC_MASTER_DATA, 0x20);
+    outportb(PIC_SLAVE_DATA,  0x28);
+
+    outportb(PIC_MASTER_DATA, 0x04);
+    outportb(PIC_SLAVE_DATA,  0x02);
+
+    outportb(PIC_MASTER_DATA, 0x01);
+    outportb(PIC_SLAVE_DATA,  0x01);
+
+    outportb(PIC_MASTER_DATA, 0x00);
+    outportb(PIC_SLAVE_DATA,  0x00);
 }


Input: atmel_mxt_ts - use snprintf for sysfs attribute show method

Sysfs attribute show methods are always passed a buffer of length
PAGE_SIZE.  To keep from overwriting this buffer and causing havoc, use
snprintf() to guarantee we never write more than the buffer can hold.

In addition, at least for my touchscreen, the number and size of objects
was far too big to fit in a single 4K page.  Therefore, this patch also
trims some redundant framing text to leave more room for actual data.

Signed-off-by: Daniel Kurtz <31914e832df1cd8e5daa417106c0c6f5297b27d7@chromium.org>
Acked-by: Nick Dyer <c8f0c1d5fcda9220e27043f45924e42042c4e015@itdev.co.uk>
Signed-off-by: Dmitry Torokhov <10a8c465cefc9bdd6c925e26964d23c90f1141cc@mail.ru>

--- drivers/input/touchscreen/atmel_mxt_ts.c
+++ drivers/input/touchscreen/atmel_mxt_ts.c
@@ -910,12 +910,17 @@
 	for (i = 0; i < data->info.object_num; i++) {
 		object = data->object_table + i;

-		count += sprintf(buf + count,
-				"Object Table Element %d(Type %d)\n",
+		count += snprintf(buf + count, PAGE_SIZE - count,
+				"Object[%d] (Type %d)\n",
 				i + 1, object->type);
+		if (count >= PAGE_SIZE)
+			return PAGE_SIZE - 1;

 		if (!mxt_object_readable(object->type)) {
-			count += sprintf(buf + count, "\n");
+			count += snprintf(buf + count, PAGE_SIZE - count,
+					"\n");
+			if (count >= PAGE_SIZE)
+				return PAGE_SIZE - 1;
 			continue;
 		}

@@ -925,11 +930,15 @@
 			if (error)
 				return error;

-			count += sprintf(buf + count,
-					"  Byte %d: 0x%x (%d)\n", j, val, val);
+			count += snprintf(buf + count, PAGE_SIZE - count,
+					"\t[%2d]: %02x (%d)\n", j, val, val);
+			if (count >= PAGE_SIZE)
+				return PAGE_SIZE - 1;
 		}

-		count += sprintf(buf + count, "\n");
+		count += snprintf(buf + count, PAGE_SIZE - count, "\n");
+		if (count >= PAGE_SIZE)
+			return PAGE_SIZE - 1;
 	}

 	return count;


Changed CATCHUP_COMMIT_GRANULARITY.

Changed CATCHUP_COMMIT_GRANULARITY.

--- src/Application/ShardServer/ShardCatchupReader.h
+++ src/Application/ShardServer/ShardCatchupReader.h
@@ -6,7 +6,7 @@

 class ShardQuorumProcessor;

-#define CATCHUP_COMMIT_GRANULARITY      64*KB
+#define CATCHUP_COMMIT_GRANULARITY      16*MiB
 #define SHARD_CATCHUP_READER_DELAY      10*1000 // msec


Use better error messages for setgroups() failures.

--HG--
branch : HEAD

--- src/lib/restrict-access.c
+++ src/lib/restrict-access.c
@@ -82,8 +82,10 @@

 	if (used != gid_count) {
 		/* it did contain restricted groups, remove it */
-		if (setgroups(used, gid_list) < 0)
-			i_fatal("setgroups() failed: %m");
+		if (setgroups(used, gid_list) < 0) {
+			i_fatal("Couldn't drop restricted groups: "
+				"setgroups() failed: %m");
+		}
 	}
 	t_pop();
 }
@@ -119,8 +121,10 @@
 		gid_list[gid_count++] = get_group_id(*tmp);
 	}

-	if (setgroups(gid_count, gid_list) < 0)
-		i_fatal("setgroups() failed: %m");
+	if (setgroups(gid_count, gid_list) < 0) {
+		i_fatal("Couldn't set mail_extra_groups: "
+			"setgroups(%s) failed: %m", groups);
+	}

 	t_pop();
 }


Actually report x/y_root against the root window

--- gdk/gdkwindow.c
+++ gdk/gdkwindow.c
@@ -6837,6 +6837,7 @@
   GdkWindow *a;
   GdkWindow *b;
   GdkWindow *event_win;
+  GdkWindowObject *toplevel;

   /* TODO: Don't send events to toplevel, as we get those from the windowing system */

@@ -6844,12 +6845,14 @@
   b = dest;
   if (a == b)
     return; /* No crossings generated between src and dest */
-
+
   c = find_common_ancestor (a, b);
   non_linear = (c != a) && (c != b);

   if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
     {
+      toplevel = (GdkWindowObject *)gdk_window_get_toplevel (a);
+
       /* Traverse up from a to (excluding) c sending leave events */

       event_win = get_target_window_for_pointer_event (display, a, GDK_LEAVE_NOTIFY, mask);
@@ -6861,8 +6864,8 @@
 	  convert_toplevel_coords_to_window (event_win,
 					     toplevel_x, toplevel_y,
 					     &event->crossing.x, &event->crossing.y);
-	  event->crossing.x_root = toplevel_x;
-	  event->crossing.y_root = toplevel_y;
+	  event->crossing.x_root = toplevel_x + toplevel->x;
+	  event->crossing.y_root = toplevel_y + toplevel->y;
 	  event->crossing.mode = mode;
 	  if (non_linear)
 	    event->crossing.detail = GDK_NOTIFY_NONLINEAR;
@@ -6889,8 +6892,8 @@
 		  convert_toplevel_coords_to_window (event_win,
 						     toplevel_x, toplevel_y,
 						     &event->crossing.x, &event->crossing.y);
-		  event->crossing.x_root = toplevel_x;
-		  event->crossing.y_root = toplevel_y;
+		  event->crossing.x_root = toplevel_x + toplevel->x;
+		  event->crossing.y_root = toplevel_y + toplevel->y;
 		  event->crossing.mode = mode;
 		  if (non_linear)
 		    event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
@@ -6907,6 +6910,8 @@

   if (b) /* Might not be a dest, e.g. if we're moving out of the window */
     {
+      toplevel = (GdkWindowObject *)gdk_window_get_toplevel (b);
+
       /* Traverse down from c to b */
       if (c != b)
 	{
@@ -6937,8 +6942,8 @@
 		  convert_toplevel_coords_to_window (event_win,
 						     toplevel_x, toplevel_y,
 						     &event->crossing.x, &event->crossing.y);
-		  event->crossing.x_root = toplevel_x;
-		  event->crossing.y_root = toplevel_y;
+		  event->crossing.x_root = toplevel_x + toplevel->x;
+		  event->crossing.y_root = toplevel_y + toplevel->y;
 		  event->crossing.mode = mode;
 		  if (non_linear)
 		    event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
@@ -6960,8 +6965,8 @@
 	  convert_toplevel_coords_to_window (event_win,
 					     toplevel_x, toplevel_y,
 					     &event->crossing.x, &event->crossing.y);
-	  event->crossing.x_root = toplevel_x;
-	  event->crossing.y_root = toplevel_y;
+	  event->crossing.x_root = toplevel_x + toplevel->x;
+	  event->crossing.y_root = toplevel_y + toplevel->y;
 	  event->crossing.mode = mode;
 	  if (non_linear)
 	    event->crossing.detail = GDK_NOTIFY_NONLINEAR;
@@ -7136,8 +7141,8 @@
 	  convert_toplevel_coords_to_window (event_win,
 					     toplevel_x, toplevel_y,
 					     &event->motion.x, &event->motion.y);
-	  event->motion.x_root = toplevel_x; /* TODO: right? */
-	  event->motion.y_root = toplevel_y;
+	  event->motion.x_root = source_event->motion.x_root;
+	  event->motion.y_root = source_event->motion.y_root;;
 	  event->motion.state = state;
 	  event->motion.is_hint = FALSE;
 	  event->motion.device = NULL;
@@ -7214,8 +7219,8 @@
 	  convert_toplevel_coords_to_window (event_win,
 					     toplevel_x, toplevel_y,
 					     &event->button.x, &event->button.y);
-          event->button.x_root = toplevel_x;
-          event->button.y_root = toplevel_y;
+          event->button.x_root = source_event->button.x_root;
+          event->button.y_root = source_event->button.y_root;
           event->button.state = state;
           event->button.device = source_event->button.device;

@@ -7228,8 +7233,8 @@
 	  convert_toplevel_coords_to_window (event_win,
 					     toplevel_x, toplevel_y,
 					     &event->scroll.x, &event->scroll.y);
-          event->scroll.x_root = toplevel_x;
-          event->scroll.y_root = toplevel_y;
+          event->scroll.x_root = source_event->scroll.x_root;
+          event->scroll.y_root = source_event->scroll.y_root;
           event->scroll.state = state;
           event->scroll.device = source_event->scroll.device;
           return TRUE;


* Fixes NB#91837, fixes a memory leak

	* Fixes NB#91837, fixes a memory leak

pmo-trunk-r6236

--- src/modest-tny-account-store.c
+++ src/modest-tny-account-store.c
@@ -1973,6 +1973,12 @@
 	return TNY_TRANSPORT_ACCOUNT (tny_account);
 }

+static void
+foreach_free_string(gpointer data,
+		    gpointer user_data)
+{
+	g_free (data);
+}

 static void
 add_connection_specific_transport_accounts (ModestTnyAccountStore *self)
@@ -1989,6 +1995,7 @@
 	if (err) {
 		g_error_free (err);
 		g_return_if_reached ();
+		return;
 	}

 	/* Look at each connection-specific transport account for the
@@ -2007,6 +2014,10 @@
 		}
 		iter = g_slist_next (iter);
 	}
+
+	/* Free the list */
+	g_slist_foreach (list_specifics, foreach_free_string, NULL);
+	g_slist_free (list_specifics);
 }

 static void
@@ -2025,6 +2036,7 @@
 	if (err) {
 		g_error_free (err);
 		g_return_if_reached ();
+		return;
 	}

 	/* Look at each connection-specific transport account for the
@@ -2046,6 +2058,10 @@
 		}
 		iter = g_slist_next (iter);
 	}
+
+	/* Free the list */
+	g_slist_foreach (list_specifics, foreach_free_string, NULL);
+	g_slist_free (list_specifics);
 }


dbus: remove priv->dbus_conn

dbus: remove priv->dbus_conn

It's only needed once, and it is better to group with rest of dbus-glib
code.

--- gtk/desktop-integration.c
+++ gtk/desktop-integration.c
@@ -42,7 +42,6 @@

 struct _SpiceDesktopIntegrationPrivate {
 #ifdef USE_DBUS_GLIB
-    DBusGConnection *dbus_conn;
     DBusGProxy *gnome_session_proxy;
     guint gnome_automount_inhibit_cookie;
 #else
@@ -73,18 +72,21 @@
 {
     SpiceDesktopIntegrationPrivate *priv = self->priv;
     GError *error = NULL;
-
-    if (!priv->dbus_conn)
-        return FALSE;
+    DBusGConnection *conn;
+
+    conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+    if (!conn)
+        goto end;

     /* We use for_name_owner, to resolve the name now, as we may not be
        running under gnome-session manager at all! */
     priv->gnome_session_proxy = dbus_g_proxy_new_for_name_owner(
-                                            priv->dbus_conn,
+                                            conn,
                                             "org.gnome.SessionManager",
                                             "/org/gnome/SessionManager",
                                             "org.gnome.SessionManager",
                                             &error);
+end:
     if (error) {
         g_debug("Could not create org.gnome.SessionManager dbus proxy: %s",
                 error->message);
@@ -155,19 +157,11 @@
 static void spice_desktop_integration_init(SpiceDesktopIntegration *self)
 {
     SpiceDesktopIntegrationPrivate *priv;
-#ifdef USE_DBUS_GLIB
-    GError *error = NULL;
-#endif

     priv = SPICE_DESKTOP_INTEGRATION_GET_PRIVATE(self);
     self->priv = priv;

 #ifdef USE_DBUS_GLIB
-    priv->dbus_conn = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-    if (!priv->dbus_conn) {
-       g_warning("Error connecting to session dbus: %s", error->message);
-       g_clear_error(&error);
-    }
     if (!gnome_integration_init(self))
 #endif
        g_warning("Warning no automount-inhibiting implementation available");


[media] mem2mem_testdev: Use pr_err instead of printk

printk(KERN_ERR...) is replaced with pr_err to silence checkpatch
warning.
WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ...
then pr_err(...  to printk(KERN_ERR ...

Signed-off-by: Sachin Kamat <1c3b1584a6008857f36c03c58f657c0fc16fc09e@linaro.org>
Signed-off-by: Mauro Carvalho Chehab <ad86ba2154032c9f55743a190faa2459a9d61d42@redhat.com>

--- drivers/media/platform/mem2mem_testdev.c
+++ drivers/media/platform/mem2mem_testdev.c
@@ -397,8 +397,7 @@
 	curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);

 	if (NULL == curr_ctx) {
-		printk(KERN_ERR
-			"Instance released before the end of transaction\n");
+		pr_err("Instance released before the end of transaction\n");
 		return;
 	}


service fixed: uses fileno

service fixed: uses fileno

--- src/lib/service/service.c
+++ src/lib/service/service.c
@@ -183,7 +183,7 @@
 	curr += service_set_starting_line(curr, srv_data->http_status);
 	/* 2. set options */
 	assert(srv_file->fd != NULL);
-	fstat(srv_file->fd->fd, &stat); /* TODO bad bad bad!! */
+	fstat(fileno(srv_file->fd), &stat);
 	curr += service_set_ops(curr, stat.st_size, srv_data->request.connection,
 			content_type);
 	/* 3. set message bode and send response */


Changes to sre.c after the application of patch #726869 have increased
stack usage on FreeBSD, requiring the recursion limit to be lowered
further.  Building with gcc 2.95 (the standard compiler on FreeBSD 4.x)
is now also affected.

The underlying issue is that FreeBSD's pthreads implementation has a
hard-coded 1MB stack size for the initial (or "primary") thread, which
can not be changed without rebuilding libc_r.  Exhausting this stack
results in a bus error.

Building without pthreads (configure --without-threads), or linking
with the port of the Linux pthreads library (aka Linuxthreads) instead
of libc_r, avoids this limitation.

On OS/2, only gcc 3.2 is affected and the stack size is controllable,
so the special handling has been removed.

--- Modules/_sre.c
+++ Modules/_sre.c
@@ -72,13 +72,19 @@
 /* FIXME: maybe the limit should be 40000 / sizeof(void*) ? */
 #define USE_RECURSION_LIMIT 7500
 #else
-#if defined(__GNUC__) && (__GNUC__ > 2) && \
-    (defined(__FreeBSD__) || defined(PYOS_OS2))
-/* gcc 3.x, on FreeBSD and OS/2+EMX and at optimisation levels of
- * -O3 (autoconf default) and -O2 (EMX port default), generates code
- * for _sre that fails for the default recursion limit.
+
+#if defined(__GNUC__) && defined(WITH_THREAD) && defined(__FreeBSD__)
+/* the pthreads library on FreeBSD has a fixed 1MB stack size for the
+ * initial (or "primary") thread, which is insufficient for the default
+ * recursion limit.  gcc 3.x at the default optimisation
+ * level (-O3) uses stack space more aggressively than gcc 2.95.
  */
+#if (__GNUC__ > 2)
+#define USE_RECURSION_LIMIT 6500
+#else
 #define USE_RECURSION_LIMIT 7500
+#endif
+
 #else
 #define USE_RECURSION_LIMIT 10000
 #endif


minor cleanup

minor cleanup

Signed-off-by: Jens Nyberg <7200009990a46d4bb36e24284136c70d739d75fd@gmail.com>

--- src/modules/arch/x86/ps2/bus.c
+++ src/modules/arch/x86/ps2/bus.c
@@ -155,6 +155,9 @@

     unsigned char control = io_inb(REGISTERCONTROL);

+    if (!(control & STATUSOFULL))
+        return 0;
+
     if ((control & STATUSTIMEOUT))
         return 0;

@@ -165,7 +168,7 @@
     {

         case PS2_KEYBOARD:
-            return (control & 0x01);
+            return !(control & 0x20);

         case PS2_MOUSE:
             return (control & 0x20);


Only warn once if inhibit-related dbus calls fail

No need to spam about it.

https://bugzilla.gnome.org/show_bug.cgi?id=734140

--- gtk/gtkapplication-dbus.c
+++ gtk/gtkapplication-dbus.c
@@ -334,6 +334,7 @@
   GVariant *res;
   GError *error = NULL;
   guint cookie;
+  static gboolean warned = FALSE;

   if (dbus->sm_proxy == NULL)
     return 0;
@@ -352,7 +353,11 @@

  if (error)
     {
-      g_warning ("Calling Inhibit failed: %s", error->message);
+      if (!warned)
+        {
+          g_warning ("Calling Inhibit failed: %s", error->message);
+          warned = TRUE;
+        }
       g_error_free (error);
       return 0;
     }
@@ -390,6 +395,7 @@
   GVariant *res;
   GError *error = NULL;
   gboolean inhibited;
+  static gboolean warned = FALSE;

   if (dbus->sm_proxy == NULL)
     return FALSE;
@@ -403,7 +409,11 @@
                                 &error);
   if (error)
     {
-      g_warning ("Calling IsInhibited failed: %s", error->message);
+      if (!warned)
+        {
+          g_warning ("Calling IsInhibited failed: %s", error->message);
+          warned = TRUE;
+        }
       g_error_free (error);
       return FALSE;
     }