• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 /**************************************************************************************************
3  * IOWOW library
4  *
5  * MIT License
6  *
7  * Copyright (c) 2012-2020 Softmotions Ltd <info@softmotions.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  *  copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in all
17  * copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  *************************************************************************************************/
27 
28 
29 #include "log/iwlog.h"
30 #include "platform/iwp.h"
31 #include "utils/iwutils.h"
32 #include "utils/iwuuid.h"
33 #include <stdio.h>
34 
35 #if (defined(_WIN32) || defined(__WIN32__))
36 #include <direct.h>
37 #endif
38 
39 unsigned int iwcpuflags = 0;
40 static iwrc _iwp_init_impl(void);
41 
42 #if defined(__linux) || defined(__unix) || defined(__APPLE__)
43 #include "unix/unix.c"
44 #elif defined(_WIN32)
45 #include "win32/win32.c"
46 #else
47 #error Unsupported platform
48 #endif
49 
50 // Thanks to https://attractivechaos.wordpress.com/2017/09/04/on-cpu-dispatch
x86_simd(void)51 static unsigned int x86_simd(void) {
52 
53 #if defined(__i386__) || defined(__amd64__)
54   unsigned int eax, ebx, ecx, edx, flag = 0;
55 # ifdef _MSC_VER
56   int cpuid[4];
57   __cpuid(cpuid, 1);
58   eax = cpuid[0], ebx = cpuid[1], ecx = cpuid[2], edx = cpuid[3];
59 # else
60   __asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1));
61 # endif
62   if (edx >> 25 & 1) flag |= IWCPU_SSE;
63   if (edx >> 26 & 1) flag |= IWCPU_SSE2;
64   if (ecx >> 0 & 1) flag |= IWCPU_SSE3;
65   if (ecx >> 19 & 1) flag |= IWCPU_SSE4_1;
66   if (ecx >> 20 & 1) flag |= IWCPU_SSE4_2;
67   if (ecx >> 28 & 1) flag |= IWCPU_AVX;
68   if (ebx >> 5 & 1) flag |= IWCPU_AVX2;
69   if (ebx >> 16 & 1) flag |= IWCPU_AVX512F;
70   return flag;
71 #else
72   return 0;
73 #endif
74 }
75 
iwp_copy_bytes(HANDLE fh,off_t off,size_t siz,off_t noff)76 iwrc iwp_copy_bytes(HANDLE fh, off_t off, size_t siz, off_t noff) {
77   if (INVALIDHANDLE(fh)) {
78     return IW_ERROR_INVALID_HANDLE;
79   }
80   int overlap = IW_RANGES_OVERLAP(off, off + siz, noff, noff + siz);
81   size_t sp, sp2;
82   iwrc rc = 0;
83   off_t pos = 0;
84   uint8_t buf[4096];
85   if (overlap && noff > off) {
86     // todo resolve it!!
87     return IW_ERROR_OVERFLOW;
88   }
89 #if !defined(__APPLE__) && !defined(_WIN32)
90   if (siz > sizeof(buf)) {
91     posix_fadvise(fh, off, siz, POSIX_FADV_SEQUENTIAL);
92   }
93 #endif
94   while (pos < siz) {
95     rc = iwp_pread(fh, off + pos, buf, MIN(sizeof(buf), (siz - pos)), &sp);
96     if (rc || !sp) {
97       break;
98     } else {
99       rc = iwp_pwrite(fh, noff + pos, buf, sp, &sp2);
100       pos += sp;
101       if (rc) {
102         break;
103       }
104       if (sp != sp2) {
105         rc = IW_ERROR_INVALID_STATE;
106         break;
107       }
108     }
109   }
110 #if !defined(__APPLE__) && !defined(_WIN32)
111   if (siz > sizeof(buf)) {
112     posix_fadvise(fh, off, siz, POSIX_FADV_NORMAL);
113   }
114 #endif
115   return rc;
116 }
117 
iwp_allocate_tmpfile_path(const char * prefix)118 char *iwp_allocate_tmpfile_path(const char *prefix) {
119   size_t plen = prefix ? strlen(prefix) : 0;
120   char tmpdir[PATH_MAX + 1];
121   size_t tlen = iwp_tmpdir(tmpdir, sizeof(tmpdir));
122   if (!tlen) return 0;
123   char *res = malloc(tlen + sizeof(IW_PATH_STR) - 1 + plen + IW_UUID_STR_LEN + 1 /*NULL*/);
124   if (!res) return 0;
125   char *wp = res;
126   memcpy(wp, tmpdir, tlen);
127   wp += tlen;
128   memcpy(wp, IW_PATH_STR, sizeof(IW_PATH_STR) - 1);
129   wp += sizeof(IW_PATH_STR) - 1;
130   if (plen && prefix) {
131     memcpy(wp, prefix, plen);
132     wp += plen;
133   }
134   iwu_uuid4_fill(wp);
135   wp += IW_UUID_STR_LEN;
136   *wp = 0;
137   return res;
138 }
139 
iwp_mkdirs(const char * path)140 iwrc iwp_mkdirs(const char *path) {
141   /* Adapted from http://stackoverflow.com/a/2336245/119527 */
142   const size_t len = strlen(path);
143   char _path[PATH_MAX];
144   char *p;
145 
146   errno = 0;
147   /* Copy string so its mutable */
148   if (len > sizeof(_path) - 1) {
149     errno = ENAMETOOLONG;
150     return iwrc_set_errno(IW_ERROR_ERRNO, errno);
151   }
152   strcpy(_path, path);
153 
154   /* Iterate the string */
155   for (p = _path + 1; *p; p++) {
156     if (*p == '/') {
157       /* Temporarily truncate */
158       *p = '\0';
159       #if (defined(_WIN32) || defined(__WIN32__))
160       if (_mkdir(_path) != 0) {
161       #else
162       if (mkdir(_path, S_IRWXU) != 0) {
163       #endif
164         if (errno != EEXIST) {
165           return iwrc_set_errno(IW_ERROR_ERRNO, errno);
166         }
167       }
168       *p = '/';
169     }
170   }
171   #if (defined(_WIN32) || defined(__WIN32__))
172     if (_mkdir(_path) != 0) {
173   #else
174     if (mkdir(_path, S_IRWXU) != 0) {
175   #endif
176     if (errno != EEXIST) {
177       return iwrc_set_errno(IW_ERROR_ERRNO, errno);
178     }
179   }
180   return 0;
181 }
182 
183 iwrc iwp_init(void) {
184   iwcpuflags = x86_simd();
185   _iwp_init_impl();
186   return 0;
187 }
188