1 /*
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifdef _WIN32
31 #ifndef _CRT_SECURE_NO_WARNINGS
32 #define _CRT_SECURE_NO_WARNINGS
33 #endif// _CRT_SECURE_NO_WARNINGS
34
35 #pragma warning( disable : 4996 )
36 #define strtok_r strtok_s
37 #define S_ISDIR(mode) (mode & S_IFDIR)
38 #endif //_WIN32
39
40 #ifndef VERIFY_PRINT_ERROR
41 #define VERIFY_PRINT_ERROR
42 #endif //VERIFY_PRINT_ERROR
43 #define FARF_ERROR 1
44
45 #include <stdlib.h>
46 #include <errno.h>
47 #include <string.h>
48 #include <pthread.h>
49 #include <dlfcn.h>
50 #include <dirent.h>
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <stdio.h>
54 #include "remote.h"
55 #include "verify.h"
56 #include "apps_std.h"
57 #include "AEEstd.h"
58 #include "AEEStdErr.h"
59 #include "AEEatomic.h"
60 #include "AEEQList.h"
61 #include "platform_libs.h"
62 #include "fastrpc_apps_user.h"
63 #include "HAP_farf.h"
64 #include "rpcmem.h"
65
66 #ifndef _WIN32
67 #include <unistd.h>
68 #endif // _WiN32
69
70 #ifndef C_ASSERT
71 #define C_ASSERT(test) \
72 switch(0) {\
73 case 0:\
74 case test:;\
75 }
76 #endif //C_ASSERT
77
78 #define APPS_FD_BASE 100
79 #define ERRNO (errno == 0 ? -1 : errno)
80 #define APPS_STD_STREAM_FILE 1
81 #define APPS_STD_STREAM_BUF 2
82
83 #define ION_HEAP_ID_QSEECOM 27
84
85 #define FREEIF(pv) \
86 do {\
87 if(pv) { \
88 void* tmp = (void*)pv;\
89 pv = 0;\
90 free(tmp);\
91 tmp = 0;\
92 } \
93 } while(0)
94
95 extern int get_domain_id();
96
97 struct apps_std_buf_info {
98 char* fbuf;
99 int flen;
100 int pos;
101 };
102
103 struct apps_std_info {
104 QNode qn;
105 int type;
106 union {
107 FILE* stream;
108 struct apps_std_buf_info binfo;
109 } u;
110 apps_std_FILE fd;
111 };
112
113 static QList apps_std_qlst;
114 static pthread_mutex_t apps_std_mt;
115
116 int setenv(const char *name, const char *value, int overwrite);
117 int unsetenv(const char *name);
118
apps_std_init(void)119 int apps_std_init(void) {
120 QList_Ctor(&apps_std_qlst);
121 pthread_mutex_init(&apps_std_mt, 0);
122 return AEE_SUCCESS;
123 }
124
apps_std_deinit(void)125 void apps_std_deinit(void) {
126 pthread_mutex_destroy(&apps_std_mt);
127 }
128
129 PL_DEFINE(apps_std, apps_std_init, apps_std_deinit);
130
apps_std_FILE_free(struct apps_std_info * sfree)131 static int apps_std_FILE_free(struct apps_std_info* sfree) {
132 int nErr = AEE_SUCCESS;
133
134 pthread_mutex_lock(&apps_std_mt);
135 QNode_Dequeue(&sfree->qn);
136 pthread_mutex_unlock(&apps_std_mt);
137
138 free(sfree);
139 sfree = NULL;
140 return nErr;
141 }
142
apps_std_FILE_alloc(FILE * stream,apps_std_FILE * fd)143 static int apps_std_FILE_alloc(FILE *stream, apps_std_FILE *fd) {
144 struct apps_std_info *sinfo = 0, *info;
145 QNode *pn = 0;
146 apps_std_FILE prevfd = APPS_FD_BASE - 1;
147 int nErr = AEE_SUCCESS;
148
149 VERIFYC(0 != (sinfo = calloc(1, sizeof(*sinfo))), AEE_ENOMEMORY);
150 QNode_CtorZ(&sinfo->qn);
151 sinfo->type = APPS_STD_STREAM_FILE;
152 pthread_mutex_lock(&apps_std_mt);
153 pn = QList_GetFirst(&apps_std_qlst);
154 if(pn) {
155 info = STD_RECOVER_REC(struct apps_std_info, qn, pn);
156 prevfd = info->fd;
157 QLIST_FOR_REST(&apps_std_qlst, pn) {
158 info = STD_RECOVER_REC(struct apps_std_info, qn, pn);
159 if (info->fd != prevfd + 1) {
160 sinfo->fd = prevfd + 1;
161 QNode_InsPrev(pn, &sinfo->qn);
162 break;
163 }
164 prevfd = info->fd;
165 }
166 }
167 if(!QNode_IsQueuedZ(&sinfo->qn)) {
168 sinfo->fd = prevfd + 1;
169 QList_AppendNode(&apps_std_qlst, &sinfo->qn);
170 }
171 pthread_mutex_unlock(&apps_std_mt);
172
173 sinfo->u.stream = stream;
174 *fd = sinfo->fd;
175
176 bail:
177 if(nErr) {
178 FREEIF(sinfo);
179 VERIFY_EPRINTF("Error %x: apps_std_FILE_alloc failed\n", nErr);
180 }
181 return nErr;
182 }
183
apps_std_FILE_get(apps_std_FILE fd,struct apps_std_info ** info)184 static int apps_std_FILE_get(apps_std_FILE fd, struct apps_std_info** info) {
185 struct apps_std_info *sinfo = 0;
186 QNode *pn, *pnn;
187 FILE* stream = NULL;
188 int nErr = AEE_ENOSUCHSTREAM;
189
190 pthread_mutex_lock(&apps_std_mt);
191 QLIST_NEXTSAFE_FOR_ALL(&apps_std_qlst, pn, pnn) {
192 sinfo = STD_RECOVER_REC(struct apps_std_info, qn, pn);
193 if(sinfo->fd == fd) {
194 *info = sinfo;
195 nErr = AEE_SUCCESS;
196 break;
197 }
198 }
199 pthread_mutex_unlock(&apps_std_mt);
200
201 return nErr;
202 }
203
apps_std_FILE_set_buffer_stream(struct apps_std_info * sinfo,char * fbuf,int flen,int pos)204 static void apps_std_FILE_set_buffer_stream(struct apps_std_info* sinfo, char* fbuf, int flen, int pos) {
205 pthread_mutex_lock(&apps_std_mt);
206 fclose(sinfo->u.stream);
207 sinfo->type = APPS_STD_STREAM_BUF;
208 sinfo->u.binfo.fbuf = fbuf;
209 sinfo->u.binfo.flen = flen;
210 sinfo->u.binfo.pos = pos;
211 pthread_mutex_unlock(&apps_std_mt);
212 }
213
__QAIC_IMPL(apps_std_fopen)214 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen)(const char* name, const char* mode, apps_std_FILE* psout) __QAIC_IMPL_ATTRIBUTE {
215 int nErr = AEE_SUCCESS;
216 FILE* stream = fopen(name, mode);
217 if(stream) {
218 return apps_std_FILE_alloc(stream, psout);
219 } else {
220 nErr = AEE_ENOSUCHFILE;
221 }
222 if(nErr != AEE_SUCCESS) {
223 // Ignoring this error, as fopen happens on all ADSP_LIBRARY_PATHs
224 VERIFY_IPRINTF("Error %x: fopen for %s failed. errno: %s\n", nErr, name, strerror(ERRNO));
225 }
226 return nErr;
227 }
228
__QAIC_IMPL(apps_std_freopen)229 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_freopen)(apps_std_FILE sin, const char* name, const char* mode, apps_std_FILE* psout) __QAIC_IMPL_ATTRIBUTE {
230 int nErr = AEE_SUCCESS;
231 struct apps_std_info* sinfo = 0;
232 FILE* stream;
233
234 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
235 VERIFY(sinfo->type == APPS_STD_STREAM_FILE);
236 stream = freopen(name, mode, sinfo->u.stream);
237 if(stream) {
238 FARF(HIGH, "freopen success: %s %x\n", name, stream);
239 return apps_std_FILE_alloc(stream, psout);
240 } else {
241 nErr = AEE_EFOPEN;
242 }
243 bail:
244 if(nErr != AEE_SUCCESS) {
245 VERIFY_EPRINTF("Error %x: freopen for %s failed. errno: %s\n", nErr, name, strerror(ERRNO));
246 }
247 return nErr;
248 }
249
__QAIC_IMPL(apps_std_fflush)250 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fflush)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE {
251 int nErr = AEE_SUCCESS;
252 struct apps_std_info* sinfo = 0;
253
254 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
255 if(sinfo->type == APPS_STD_STREAM_FILE) {
256 VERIFYC(0 == fflush(sinfo->u.stream), AEE_EFFLUSH);
257 }
258 bail:
259 if(nErr != AEE_SUCCESS) {
260 VERIFY_EPRINTF("Error %x: fflush for %x failed. errno: %s\n", nErr, sin, strerror(ERRNO));
261 }
262 return nErr;
263 }
264
__QAIC_IMPL(apps_std_fclose)265 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fclose)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE {
266 int nErr = AEE_SUCCESS;
267 struct apps_std_info* sinfo = 0;
268
269 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
270 if(sinfo->type == APPS_STD_STREAM_FILE) {
271 VERIFYC(0 == fclose(sinfo->u.stream), AEE_EFCLOSE);
272 } else {
273 if(sinfo->u.binfo.fbuf) {
274 rpcmem_free_internal(sinfo->u.binfo.fbuf);
275 sinfo->u.binfo.fbuf = NULL;
276 }
277 }
278 apps_std_FILE_free(sinfo);
279 bail:
280 if(nErr != AEE_SUCCESS) {
281 VERIFY_EPRINTF("Error %x: freopen for %x failed. errno: %s\n", nErr, sin, strerror(ERRNO));
282 }
283 return nErr;
284 }
285
__QAIC_IMPL(apps_std_fread)286 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fread)(apps_std_FILE sin, byte* buf, int bufLen, int* bytesRead, int* bEOF) __QAIC_IMPL_ATTRIBUTE {
287 int out = 0, nErr = AEE_SUCCESS;
288 struct apps_std_info* sinfo = 0;
289
290 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
291 if(sinfo->type == APPS_STD_STREAM_FILE) {
292 out = fread(buf, 1, bufLen, sinfo->u.stream);
293 *bEOF = FALSE;
294 if(out <= bufLen) {
295 int err;
296 if(0 == out && (0 != (err = ferror(sinfo->u.stream)))) {
297 nErr = AEE_EFREAD;
298 VERIFY_EPRINTF("Error %x: fread returning %d bytes, requested was %d bytes, errno is %x\n", nErr, out, bufLen, err);
299 return nErr;
300 }
301 *bEOF = feof(sinfo->u.stream);
302 }
303 *bytesRead = out;
304 } else {
305 *bytesRead = std_memscpy(buf, bufLen, sinfo->u.binfo.fbuf + sinfo->u.binfo.pos,
306 sinfo->u.binfo.flen - sinfo->u.binfo.pos);
307 sinfo->u.binfo.pos += *bytesRead;
308 *bEOF = sinfo->u.binfo.pos == sinfo->u.binfo.flen ? TRUE : FALSE;
309 }
310 FARF(HIGH, "fread returning %d %d 0", out, bufLen);
311 bail:
312 return nErr;
313 }
314
__QAIC_IMPL(apps_std_fwrite)315 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fwrite)(apps_std_FILE sin, const byte* buf, int bufLen, int* bytesRead, int* bEOF) __QAIC_IMPL_ATTRIBUTE {
316 int nErr = AEE_SUCCESS;
317 struct apps_std_info* sinfo = 0;
318
319 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
320 if(sinfo->type == APPS_STD_STREAM_FILE) {
321 int out = fwrite(buf, 1, bufLen, sinfo->u.stream);
322 *bEOF = FALSE;
323 if(out <= bufLen) {
324 int err;
325 if(0 == out && (0 != (err = ferror(sinfo->u.stream)))) {
326 nErr = AEE_EFWRITE;
327 VERIFY_EPRINTF("Error %x: fwrite returning %d bytes, requested was %d bytes, errno is %x\n", nErr, out, bufLen, err);
328 return nErr;
329 }
330 *bEOF = feof(sinfo->u.stream);
331 }
332 *bytesRead = out;
333 } else {
334 nErr = AEE_EFWRITE;
335 }
336 bail:
337 return nErr;
338 }
339
__QAIC_IMPL(apps_std_fgetpos)340 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fgetpos)(apps_std_FILE sin, byte* pos, int posLen, int* posLenReq) __QAIC_IMPL_ATTRIBUTE {
341 int nErr = AEE_SUCCESS;
342 fpos_t fpos;
343 struct apps_std_info* sinfo = 0;
344
345 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
346 if(sinfo->type == APPS_STD_STREAM_FILE) {
347 if(0 == fgetpos(sinfo->u.stream, &fpos)) {
348 std_memmove(pos, &fpos, STD_MIN((int)sizeof(fpos), posLen));
349 *posLenReq = sizeof(fpos);
350 return AEE_SUCCESS;
351 } else {
352 nErr = AEE_EFGETPOS;
353 }
354 } else {
355 nErr = AEE_EFGETPOS;
356 }
357 bail:
358 VERIFY_EPRINTF("Error %x: fgetpos failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
359 return nErr;
360 }
361
__QAIC_IMPL(apps_std_fsetpos)362 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fsetpos)(apps_std_FILE sin, const byte* pos, int posLen) __QAIC_IMPL_ATTRIBUTE {
363 int nErr = AEE_SUCCESS;
364 fpos_t fpos;
365 struct apps_std_info* sinfo = 0;
366
367 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
368 if(sinfo->type == APPS_STD_STREAM_FILE) {
369 if(sizeof(fpos) != posLen) {
370 return AEE_EBADSIZE;
371 }
372 std_memmove(&fpos, pos, sizeof(fpos));
373 if(0 == fsetpos(sinfo->u.stream, &fpos)) {
374 return AEE_SUCCESS;
375 } else {
376 nErr = AEE_EFSETPOS;
377 }
378 } else {
379 nErr = AEE_EFSETPOS;
380 }
381 bail:
382 VERIFY_EPRINTF("Error %x: fsetpos failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
383 return nErr;
384 }
385
__QAIC_IMPL(apps_std_ftell)386 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_ftell)(apps_std_FILE sin, int* pos) __QAIC_IMPL_ATTRIBUTE {
387 int nErr = AEE_SUCCESS;
388 struct apps_std_info* sinfo = 0;
389
390 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
391 if(sinfo->type == APPS_STD_STREAM_FILE) {
392 if((*pos = ftell(sinfo->u.stream)) >= 0) {
393 return AEE_SUCCESS;
394 } else {
395 nErr = AEE_EFTELL;
396 }
397 } else {
398 *pos = sinfo->u.binfo.pos;
399 return AEE_SUCCESS;
400 }
401 bail:
402 VERIFY_EPRINTF("Error %x: ftell failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
403 return nErr;
404 }
405
__QAIC_IMPL(apps_std_fseek)406 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fseek)(apps_std_FILE sin, int offset, apps_std_SEEK whence) __QAIC_IMPL_ATTRIBUTE {
407 int nErr = AEE_SUCCESS;
408 int op = (int)whence;
409 struct apps_std_info* sinfo = 0;
410
411 C_ASSERT(APPS_STD_SEEK_SET == SEEK_SET);
412 C_ASSERT(APPS_STD_SEEK_CUR == SEEK_CUR);
413 C_ASSERT(APPS_STD_SEEK_END == SEEK_END);
414 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
415 if(sinfo->type == APPS_STD_STREAM_FILE) {
416 if(0 == fseek(sinfo->u.stream, offset, whence)) {
417 return AEE_SUCCESS;
418 } else {
419 nErr = AEE_EFSEEK;
420 }
421 } else {
422 switch(op) {
423 case APPS_STD_SEEK_SET:
424 VERIFYC(offset <= sinfo->u.binfo.flen, AEE_EFSEEK);
425 sinfo->u.binfo.pos = offset;
426 break;
427 case APPS_STD_SEEK_CUR:
428 VERIFYC(offset + sinfo->u.binfo.pos <= sinfo->u.binfo.flen, AEE_EFSEEK);
429 sinfo->u.binfo.pos += offset;
430 break;
431 case APPS_STD_SEEK_END:
432 VERIFYC(offset + sinfo->u.binfo.flen <= sinfo->u.binfo.flen, AEE_EFSEEK);
433 sinfo->u.binfo.pos += offset + sinfo->u.binfo.flen;
434 break;
435 }
436 }
437 bail:
438 if(nErr != AEE_SUCCESS) {
439 VERIFY_EPRINTF("Error %x: fseek failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
440 }
441 return nErr;
442 }
443
__QAIC_IMPL(apps_std_rewind)444 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_rewind)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE {
445 int nErr = AEE_SUCCESS;
446 struct apps_std_info* sinfo = 0;
447
448 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
449 if(sinfo->type == APPS_STD_STREAM_FILE) {
450 rewind(sinfo->u.stream);
451 } else {
452 sinfo->u.binfo.pos = 0;
453 }
454 bail:
455 return nErr;
456 }
457
__QAIC_IMPL(apps_std_feof)458 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_feof)(apps_std_FILE sin, int* bEOF) __QAIC_IMPL_ATTRIBUTE {
459 int nErr = AEE_SUCCESS;
460 struct apps_std_info* sinfo = 0;
461
462 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
463 if(sinfo->type == APPS_STD_STREAM_FILE) {
464 *bEOF = feof(sinfo->u.stream);
465 } else {
466 nErr = AEE_EUNSUPPORTED;
467 }
468 bail:
469 return nErr;
470 }
471
__QAIC_IMPL(apps_std_ferror)472 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_ferror)(apps_std_FILE sin, int* err) __QAIC_IMPL_ATTRIBUTE {
473 int nErr = AEE_SUCCESS;
474 struct apps_std_info* sinfo = 0;
475
476 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
477 if(sinfo->type == APPS_STD_STREAM_FILE) {
478 *err = ferror(sinfo->u.stream);
479 } else {
480 nErr = AEE_EUNSUPPORTED;
481 }
482 bail:
483 return nErr;
484 }
485
__QAIC_IMPL(apps_std_clearerr)486 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_clearerr)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE {
487 int nErr = AEE_SUCCESS;
488 struct apps_std_info* sinfo = 0;
489
490 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
491 if(sinfo->type == APPS_STD_STREAM_FILE) {
492 clearerr(sinfo->u.stream);
493 } else {
494 nErr = AEE_EUNSUPPORTED;
495 }
496 bail:
497 return nErr;
498 }
499
__QAIC_IMPL(apps_std_flen)500 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_flen)(apps_std_FILE sin, uint64* len) __QAIC_IMPL_ATTRIBUTE {
501 int nErr = AEE_SUCCESS;
502 struct apps_std_info* sinfo = 0;
503
504 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
505 if(sinfo->type == APPS_STD_STREAM_FILE) {
506 struct stat st_buf;
507 int fd = fileno(sinfo->u.stream);
508 C_ASSERT(sizeof(st_buf.st_size) <= sizeof(*len));
509 if(fd == -1) {
510 nErr = AEE_EFLEN;
511 VERIFY_EPRINTF("Error %x: flen failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
512 return nErr;
513 }
514 if(0 != fstat(fd, &st_buf)) {
515 nErr = AEE_EFLEN;
516 VERIFY_EPRINTF("Error %x: flen failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
517 return nErr;
518 }
519 *len = st_buf.st_size;
520 } else {
521 *len = sinfo->u.binfo.flen;
522 }
523 bail:
524 return nErr;
525 }
526
__QAIC_IMPL(apps_std_print_string)527 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_print_string)(const char* str) __QAIC_IMPL_ATTRIBUTE {
528 printf("%s", str);
529 return AEE_SUCCESS;
530 }
531
__QAIC_IMPL(apps_std_getenv)532 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_getenv)(const char* name, char* val, int valLen, int* valLenReq) __QAIC_IMPL_ATTRIBUTE {
533 int nErr = AEE_SUCCESS;
534 char* vv = getenv(name);
535 if(vv) {
536 *valLenReq = std_strlen(vv) + 1;
537 std_strlcpy(val, vv, valLen);
538 return AEE_SUCCESS;
539 }
540 nErr = AEE_EGETENV;
541 VERIFY_IPRINTF("Error %x: apps_std getenv failed: %s %s\n", nErr, name, strerror(ERRNO));
542 return nErr;
543 }
544
__QAIC_IMPL(apps_std_setenv)545 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_setenv)(const char* name, const char* val, int override) __QAIC_IMPL_ATTRIBUTE {
546 int nErr = AEE_SUCCESS;
547 #ifdef _WIN32
548 return AEE_EUNSUPPORTED;
549 #else //_WIN32
550 if(0 != setenv(name, val, override)) {
551 nErr = AEE_ESETENV;
552 VERIFY_EPRINTF("Error %x: setenv failed for %s, errno is %s\n", nErr, name, strerror(ERRNO));
553 return nErr;
554 }
555 return AEE_SUCCESS;
556 #endif //_WIN32
557 }
558
__QAIC_IMPL(apps_std_unsetenv)559 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_unsetenv)(const char* name) __QAIC_IMPL_ATTRIBUTE {
560 int nErr = AEE_SUCCESS;
561 #ifdef _WIN32
562 return AEE_EUNSUPPORTED;
563 #else //_WIN32
564 if(0 != unsetenv(name)) {
565 nErr = AEE_ESETENV;
566 VERIFY_EPRINTF("Error %x: unsetenv failed for %s, errno is %s\n", nErr, name, strerror(ERRNO));
567 return nErr;
568 }
569 return AEE_SUCCESS;
570 #endif //_WIN32
571 }
572
573
574 #if (defined LE_ENABLE)
575 static char* ADSP_LIBRARY_PATH=";/usr/lib/rfsa/adsp;/usr/lib;/dsp;/usr/share/fastrpc";
576 static char* ADSP_AVS_CFG_PATH=";/etc/acdbdata/";
577 #elif (defined __BRILLO__)
578 static char* ADSP_LIBRARY_PATH=";/system/etc/lib/rfsa/adsp;/system/vendor/etc/lib/rfsa/adsp;/dsp";
579 static char* ADSP_AVS_CFG_PATH=";/etc/acdbdata/";
580 #elif (defined _ANDROID) || (defined ANDROID)
581 #if (defined ANDROID_P) && (defined FULL_TREBLE)
582 #ifdef SYSTEM_RPC_LIBRARY
583 static char* ADSP_LIBRARY_PATH=";/system/lib/rfsa/adsp";
584 static char* ADSP_AVS_CFG_PATH=";/etc/acdbdata/";
585 #else
586 static char* ADSP_LIBRARY_PATH=";/vendor/lib/rfsa/adsp;/vendor/dsp";
587 static char* ADSP_AVS_CFG_PATH=";/vendor/etc/acdbdata/";
588 #endif
589 #else
590 static char* ADSP_LIBRARY_PATH=";/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp;/vendor/dsp";
591 static char* ADSP_AVS_CFG_PATH=";/etc/acdbdata/;/vendor/etc/acdbdata/";
592 #endif
593 #elif (defined __QNX__)
594 static char* ADSP_LIBRARY_PATH="/radio/lib/firmware";
595 #else
596 static char* ADSP_LIBRARY_PATH="";
597 #endif
598
599 #define EMTPY_STR ""
600 #define ENV_LEN_GUESS 256
601
get_dirlist_from_env(const char * envvarname,char ** ppDirList)602 static int get_dirlist_from_env(const char* envvarname, char** ppDirList){
603 char *envList = NULL;
604 char *envListBuf = NULL;
605 char *dirList = NULL;
606 char *dirListBuf = NULL;
607 char *srcStr = NULL;
608 int nErr = AEE_SUCCESS;
609 int envListLen = 0;
610 int listLen = 0;
611 int envLenGuess = STD_MAX(ENV_LEN_GUESS, 1 + std_strlen(ADSP_LIBRARY_PATH));
612
613 VERIFYC(NULL != ppDirList, AEE_EMEMPTR);
614
615 VERIFYC(envListBuf = (char*)malloc(sizeof(char) * envLenGuess), AEE_ENOMEMORY);
616 envList = envListBuf;
617 *envList = '\0';
618 if (0 == apps_std_getenv(envvarname, envList, envLenGuess, &envListLen)) {
619 if (envLenGuess < envListLen) {
620 FREEIF(envListBuf);
621 VERIFYC(envListBuf = realloc(envListBuf, sizeof(char) * envListLen), AEE_ENOMEMORY);
622 envList = envListBuf;
623 VERIFY(0 == (nErr = apps_std_getenv(envvarname, envList, envListLen, &listLen)));
624 }
625 } else if(std_strncmp(envvarname, "ADSP_LIBRARY_PATH", 17) == 0) {
626 envListLen = listLen = 1 + std_strlcpy(envListBuf, ADSP_LIBRARY_PATH, envLenGuess);
627 } else if(std_strncmp(envvarname, "ADSP_AVS_CFG_PATH", 17) == 0) {
628 envListLen = listLen = 1 + std_strlcpy(envListBuf, ADSP_AVS_CFG_PATH, envLenGuess);
629 }
630
631 /*
632 * Allocate mem. to copy envvarname.
633 * If envvarname not set, allocate mem to create an empty string
634 */
635 if('\0' != *envList) {
636 srcStr = envList;
637 } else {
638 srcStr = EMTPY_STR;
639 envListLen = std_strlen(EMTPY_STR) + 1;
640 }
641 VERIFYC(dirListBuf = (char*)malloc(sizeof(char) * envListLen), AEE_ENOMEMORY);
642 dirList = dirListBuf;
643 std_strlcpy(dirList, srcStr, envListLen);
644 *ppDirList = dirListBuf;
645 bail:
646 FREEIF(envListBuf);
647 if(nErr != AEE_SUCCESS) {
648 VERIFY_EPRINTF("Error %x: get dirlist from env failed for %s\n", nErr, envvarname);
649 }
650 return nErr;
651 }
652
__QAIC_IMPL(apps_std_fopen_with_env)653 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)(const char* envvarname,
654 const char* delim, const char* name, const char* mode,
655 apps_std_FILE* psout) __QAIC_IMPL_ATTRIBUTE {
656
657 int nErr = AEE_SUCCESS;
658 char *dirName = NULL;
659 char *pos = NULL;
660 char *dirListBuf = NULL;
661 char *dirList = NULL;
662 char *absName = NULL;
663 uint16 absNameLen = 0;
664 int domain;
665
666 VERIFYC(NULL != mode, AEE_EINVALIDMODE);
667 VERIFYC(NULL != delim, AEE_EINVALIDFORMAT);
668 VERIFYC(NULL != name, AEE_EMEMPTR);
669
670 VERIFY(0 == (nErr = get_dirlist_from_env(envvarname, &dirListBuf )));
671 VERIFYC(NULL != (dirList = dirListBuf), AEE_EMEMPTR);
672
673 while(dirList)
674 {
675 pos = strstr(dirList, delim);
676 dirName = dirList;
677 if (pos) {
678 *pos = '\0';
679 dirList = pos + std_strlen(delim);
680 } else {
681 dirList = 0;
682 }
683
684 // Account for slash char
685 absNameLen = std_strlen(dirName) + std_strlen(name) + 2;
686 VERIFYC(NULL != (absName = (char*)malloc(sizeof(char) * absNameLen)), AEE_ENOMEMORY);
687 if ('\0' != *dirName) {
688 std_strlcpy(absName, dirName, absNameLen);
689 std_strlcat(absName, "/", absNameLen);
690 std_strlcat(absName, name, absNameLen);
691 } else {
692 std_strlcpy(absName, name, absNameLen);
693 }
694
695 nErr = apps_std_fopen(absName, mode, psout);
696 FREEIF(absName);
697 if (AEE_SUCCESS == nErr) {
698 // Success
699 goto bail;
700 }
701 }
702 domain = get_domain_id() & DOMAIN_ID_MASK;
703
704 #ifdef ANDROID_P
705 absNameLen = std_strlen("/vendor/dsp/adsp/") + std_strlen(name) + 1;
706 VERIFYC(NULL != (absName = (char*)malloc(sizeof(char) * absNameLen)), AEE_ENOMEMORY);
707
708 if (domain == ADSP_DOMAIN_ID){
709 std_strlcpy(absName, "/vendor/dsp/adsp/", absNameLen);
710 std_strlcat(absName, name,absNameLen);
711 } else if (domain == MDSP_DOMAIN_ID){
712 std_strlcpy(absName, "/vendor/dsp/mdsp/", absNameLen);
713 std_strlcat(absName, name,absNameLen);
714 } else if (domain == SDSP_DOMAIN_ID){
715 std_strlcpy(absName, "/vendor/dsp/sdsp/", absNameLen);
716 std_strlcat(absName, name,absNameLen);
717 } else if (domain == CDSP_DOMAIN_ID) {
718 std_strlcpy(absName, "/vendor/dsp/cdsp/", absNameLen);
719 std_strlcat(absName, name,absNameLen);
720 } else {
721 absName[0] = '\0';
722 }
723 nErr = apps_std_fopen(absName, mode, psout);
724 #else
725 absNameLen = std_strlen("/dsp/adsp/") + std_strlen(name) + 1;
726 VERIFYC(NULL != (absName = (char*)malloc(sizeof(char) * absNameLen)), AEE_ENOMEMORY);
727
728 if (domain == ADSP_DOMAIN_ID){
729 std_strlcpy(absName, "/dsp/adsp/", absNameLen);
730 std_strlcat(absName, name,absNameLen);
731 } else if (domain == MDSP_DOMAIN_ID){
732 std_strlcpy(absName, "/dsp/mdsp/", absNameLen);
733 std_strlcat(absName, name,absNameLen);
734 } else if (domain == SDSP_DOMAIN_ID){
735 std_strlcpy(absName, "/dsp/sdsp/", absNameLen);
736 std_strlcat(absName, name,absNameLen);
737 } else if (domain == CDSP_DOMAIN_ID) {
738 std_strlcpy(absName, "/dsp/cdsp/", absNameLen);
739 std_strlcat(absName, name,absNameLen);
740 } else {
741 absName[0] = '\0';
742 }
743 nErr = apps_std_fopen(absName, mode, psout);
744 #endif
745 bail:
746 FREEIF(absName);
747 FREEIF(dirListBuf);
748 if (nErr != AEE_SUCCESS) {
749 VERIFY_IPRINTF("Error %x: fopen failed for %s. (%s)", nErr, name, strerror(ERRNO));
750 }
751 return nErr;
752 }
753
__QAIC_IMPL(apps_std_get_search_paths_with_env)754 __QAIC_HEADER_EXPORT int __QAIC_IMPL(apps_std_get_search_paths_with_env)(
755 const char* envvarname, const char* delim, _cstring1_t* paths,
756 int pathsLen, uint32* numPaths, uint16* maxPathLen) __QAIC_IMPL_ATTRIBUTE{
757
758 char *path = NULL;
759 int nErr = AEE_SUCCESS;
760 char *dirListBuf = NULL;
761 int i = 0;
762 char *saveptr = NULL;
763 struct stat st;
764
765 VERIFYC(NULL != numPaths, AEE_EBADSIZE);
766 VERIFYC(NULL != delim, AEE_EINVALIDFORMAT);
767 VERIFYC(NULL != maxPathLen, AEE_EBADSIZE);
768
769 VERIFY(AEE_SUCCESS == (nErr = get_dirlist_from_env(envvarname, &dirListBuf )));
770
771 *numPaths = 0;
772 *maxPathLen = 0;
773
774 // Get the number of folders
775 path = strtok_r (dirListBuf, delim, &saveptr);
776 while (path != NULL){
777 // If the path exists, add it to the return
778 if ((stat(path, &st) == 0) && (S_ISDIR(st.st_mode))) {
779 *maxPathLen = STD_MAX(*maxPathLen, std_strlen(path)+1);
780 if (paths && i < pathsLen && paths[i].data && paths[i].dataLen >= std_strlen(path)) {
781 std_strlcpy(paths[i].data, path, paths[i].dataLen);
782 }
783 i++;
784 }
785 path = strtok_r (NULL, delim, &saveptr);
786 }
787 *numPaths = i;
788
789 bail:
790 FREEIF(dirListBuf);
791 if (nErr != AEE_SUCCESS) {
792 VERIFY_EPRINTF("Error %x: apps_std_get_search_paths_with_env failed\n", nErr);
793 }
794 return nErr;
795 }
796
797
__QAIC_IMPL(apps_std_fgets)798 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fgets)(apps_std_FILE sin, byte* buf, int bufLen, int* bEOF) __QAIC_IMPL_ATTRIBUTE {
799 int nErr = AEE_SUCCESS;
800 struct apps_std_info* sinfo = 0;
801
802 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
803 if(sinfo->type == APPS_STD_STREAM_FILE) {
804 char* out = fgets((char*)buf, bufLen, sinfo->u.stream);
805 *bEOF = FALSE;
806 if(!out) {
807 int err;
808 if(0 != (err = ferror(sinfo->u.stream))) {
809 nErr = AEE_EFGETS;
810 VERIFY_EPRINTF("Error %x: fgets failed for %x, errno is %s\n", nErr, sin, strerror(ERRNO));
811 return nErr;
812 }
813 *bEOF = feof(sinfo->u.stream);
814 }
815 } else {
816 nErr = AEE_EUNSUPPORTED;
817 }
818 bail:
819 return nErr;
820 }
821
__QAIC_HEADER(apps_std_fileExists)822 __QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fileExists)(const char* path, boolean* exists) __QAIC_HEADER_ATTRIBUTE{
823 int nErr = AEE_SUCCESS;
824 struct stat buffer;
825
826 VERIFYC(path != NULL, AEE_EMEMPTR);
827 VERIFYC(exists != NULL, AEE_EMEMPTR);
828
829 *exists = (stat (path, &buffer) == 0);
830
831 bail:
832 if (nErr != AEE_SUCCESS) {
833 VERIFY_EPRINTF("Error %x: fileExists failed for path %s\n", nErr, path);
834 }
835 return nErr;
836 }
837
__QAIC_IMPL(apps_std_fsync)838 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fsync)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE {
839 int nErr = AEE_SUCCESS;
840 struct apps_std_info* sinfo = 0;
841
842 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
843 if(sinfo->type == APPS_STD_STREAM_FILE) {
844 // This flushes the given sin file stream to user-space buffer.
845 // NOTE: this does NOT ensure data is physically sotred on disk
846 nErr = fflush(sinfo->u.stream);
847 if(nErr != AEE_SUCCESS){
848 VERIFY_EPRINTF("Error %x: apps_std fsync failed,errno is %s\n", nErr, strerror(ERRNO));
849 }
850 } else {
851 nErr = AEE_EUNSUPPORTED;
852 }
853
854 bail:
855 return nErr;
856 }
857
__QAIC_IMPL(apps_std_fremove)858 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fremove)(const char* name) __QAIC_IMPL_ATTRIBUTE {
859 int nErr = AEE_SUCCESS;
860
861 if(NULL == name){
862 return nErr;
863 }
864 nErr = remove(name);
865 if(nErr != AEE_SUCCESS){
866 VERIFY_EPRINTF("Error %x: failed to remove file %s,errno is %s\n", nErr, name, strerror(ERRNO));
867 }
868
869 return nErr;
870 }
871
decrypt_int(char * fbuf,int size)872 static int decrypt_int(char* fbuf, int size) {
873 int nErr = 0, fd;
874 void* handle = 0;
875 int32_t (*l_init)(void);
876 int32_t (*l_deinit)(void);
877 int32_t (*l_decrypt)(int32_t, int32_t);
878
879 VERIFYC(NULL != (handle = dlopen("liblmclient.so", RTLD_NOW)), AEE_EBADHANDLE);
880 VERIFYC(NULL != (l_init = dlsym(handle, "license_manager_init")), AEE_ENOSUCHSYMBOL);
881 VERIFYC(NULL != (l_deinit = dlsym(handle, "license_manager_deinit")), AEE_ENOSUCHSYMBOL);
882 VERIFYC(NULL != (l_decrypt = dlsym(handle, "license_manager_decrypt")), AEE_ENOSUCHSYMBOL);
883 VERIFY(0 == (nErr = l_init()));
884 VERIFY(-1 != (fd = rpcmem_to_fd_internal(fbuf)));
885 VERIFY(0 == (nErr = l_decrypt(fd, size)));
886 VERIFY(0 == (nErr = l_deinit()));
887 bail:
888 if(nErr) {
889 VERIFY_EPRINTF("Error %x: dlopen for licmgr failed. errno: %s\n", nErr, dlerror());
890 }
891 if(handle) {
892 dlclose(handle);
893 }
894 return nErr;
895 }
896
__QAIC_IMPL(apps_std_fdopen_decrypt)897 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fdopen_decrypt)(apps_std_FILE sin, apps_std_FILE *psout) __QAIC_IMPL_ATTRIBUTE {
898 int fd, nErr = AEE_SUCCESS;
899 struct stat st_buf;
900 struct apps_std_info* sinfo = 0;
901 int sz, pos;
902 char* fbuf = 0;
903
904 VERIFY(0 == (nErr = apps_std_FILE_get(sin, &sinfo)));
905 if(sinfo->type == APPS_STD_STREAM_FILE) {
906 pos = ftell(sinfo->u.stream);
907 VERIFYC(-1 != (fd = fileno(sinfo->u.stream)), AEE_EFLEN);
908 VERIFYC(0 == fstat(fd, &st_buf), AEE_EFLEN);
909 sz = (int)st_buf.st_size;
910 VERIFYC(0 != (fbuf = rpcmem_alloc_internal(ION_HEAP_ID_QSEECOM, 1, sz)), AEE_EMEMPTR);
911 VERIFYC(0 == fseek(sinfo->u.stream, 0, SEEK_SET), AEE_EFSEEK);
912 VERIFYC(sz == (int)fread(fbuf, 1, sz, sinfo->u.stream), AEE_EFREAD);
913 VERIFY(0 == (nErr = decrypt_int(fbuf, sz)));
914 apps_std_FILE_set_buffer_stream(sinfo, fbuf, sz, pos);
915 *psout = sin;
916 } else {
917 nErr = AEE_EUNSUPPORTED;
918 }
919 bail:
920 if(nErr) {
921 if(fbuf) {
922 rpcmem_free_internal(fbuf);
923 fbuf = NULL;
924 }
925 }
926 return nErr;
927 }
928
929
__QAIC_HEADER(apps_std_opendir)930 __QAIC_IMPL_EXPORT int __QAIC_HEADER(apps_std_opendir)(const char* name, apps_std_DIR* dir) __QAIC_IMPL_ATTRIBUTE {
931 int nErr = 0;
932 DIR *odir;
933
934 if(NULL == dir) {
935 return AEE_EBADPARM;
936 }
937 odir = opendir(name);
938 if(odir != NULL) {
939 dir->handle = (uint64)odir;
940 } else {
941 nErr = -1;
942 VERIFY_EPRINTF("Error %x: failed to opendir %s,errno is %s\n", nErr, name, strerror(ERRNO));
943 }
944 return nErr;
945 }
946
__QAIC_HEADER(apps_std_closedir)947 __QAIC_IMPL_EXPORT int __QAIC_HEADER(apps_std_closedir)(const apps_std_DIR* dir) __QAIC_IMPL_ATTRIBUTE {
948 int nErr = AEE_SUCCESS;
949
950 if((NULL == dir) || (0 == dir->handle)){
951 return AEE_EBADPARM;
952 }
953 nErr = closedir((DIR *)dir->handle);
954 if(nErr != AEE_SUCCESS) {
955 VERIFY_EPRINTF("Error %x: failed to closedir, errno is %s\n", nErr, strerror(ERRNO));
956 }
957
958 return nErr;
959 }
960
__QAIC_HEADER(apps_std_readdir)961 __QAIC_IMPL_EXPORT int __QAIC_HEADER(apps_std_readdir)(const apps_std_DIR* dir, apps_std_DIRENT* dirent, int *bEOF) __QAIC_IMPL_ATTRIBUTE {
962 int nErr = AEE_SUCCESS;
963 struct dirent *odirent;
964
965 if((NULL == dir) || (0 == dir->handle)){
966 return AEE_EBADPARM;
967 }
968 *bEOF = 0;
969 errno = 0;
970 odirent = readdir((DIR *)dir->handle);
971 if(odirent != NULL) {
972 dirent->ino = (int)odirent->d_ino;
973 std_strlcpy(dirent->name, odirent->d_name, sizeof(dirent->name));
974 } else {
975 if(errno == 0) {
976 *bEOF = 1;
977 } else {
978 nErr = -1;
979 }
980 }
981
982 return nErr;
983 }
984
__QAIC_HEADER(apps_std_mkdir)985 __QAIC_IMPL_EXPORT int __QAIC_HEADER(apps_std_mkdir)(const char* name, int mode) __QAIC_IMPL_ATTRIBUTE {
986 int nErr = AEE_SUCCESS;
987
988 if(NULL == name){
989 return nErr;
990 }
991 nErr = mkdir(name, mode);
992 if(nErr != AEE_SUCCESS){
993 VERIFY_EPRINTF("Error %x: failed to mkdir %s,errno is %s\n", nErr, name, strerror(ERRNO));
994 }
995
996 return nErr;
997 }
998
__QAIC_HEADER(apps_std_rmdir)999 __QAIC_IMPL_EXPORT int __QAIC_HEADER(apps_std_rmdir)(const char* name) __QAIC_IMPL_ATTRIBUTE {
1000 int nErr = AEE_SUCCESS;
1001
1002 if(NULL == name){
1003 return nErr;
1004 }
1005 nErr = rmdir(name);
1006 if(nErr != AEE_SUCCESS){
1007 VERIFY_EPRINTF("Error %x: failed to rmdir %s,errno is %s\n", nErr, name, strerror(ERRNO));
1008 }
1009
1010 return nErr;
1011 }
1012
__QAIC_HEADER(apps_std_stat)1013 __QAIC_IMPL_EXPORT int __QAIC_HEADER(apps_std_stat)(const char* name, apps_std_STAT* ist) __QAIC_IMPL_ATTRIBUTE {
1014 int nErr = AEE_SUCCESS, nOpenErr = AEE_SUCCESS, fd = -1;
1015 apps_std_FILE ps;
1016 struct apps_std_info* sinfo = 0;
1017 struct stat st;
1018
1019 if((NULL == name) || (NULL == ist)) {
1020 return AEE_EBADPARM;
1021 }
1022 VERIFYC(0 == (nOpenErr = apps_std_fopen_with_env("ADSP_LIBRARY_PATH", ";", name, "r", &ps)), AEE_EFOPEN);
1023 VERIFYC(0 == (nErr = apps_std_FILE_get(ps, &sinfo)), AEE_EBADFD);
1024 VERIFYC(-1 != (fd = fileno(sinfo->u.stream)), AEE_EBADFD);
1025 VERIFYC(0 == fstat(fd, &st), AEE_EBADFD);
1026 ist->dev = st.st_dev;
1027 ist->ino = st.st_ino;
1028 ist->mode = st.st_mode;
1029 ist->nlink = st.st_nlink;
1030 ist->rdev = st.st_rdev;
1031 ist->size = st.st_size;
1032 ist->atime = (int64)st.st_atim.tv_sec;
1033 ist->atimensec = (int64)st.st_atim.tv_nsec;
1034 ist->mtime = (int64)st.st_mtim.tv_sec;
1035 ist->mtimensec =(int64)st.st_mtim.tv_nsec;
1036 ist->ctime = (int64)st.st_ctim.tv_nsec;
1037 ist->ctimensec = (int64)st.st_ctim.tv_nsec;
1038 bail:
1039 if(nErr != AEE_SUCCESS) {
1040 VERIFY_EPRINTF("Error %x: failed to stat %s, file open returned %x, errno is %s\n", nErr, name, nOpenErr, strerror(ERRNO));
1041 }
1042 if (nOpenErr == AEE_SUCCESS) {
1043 apps_std_fclose(ps);
1044 sinfo = 0;
1045 }
1046 if(sinfo) {
1047 apps_std_FILE_free(sinfo);
1048 }
1049 return nErr;
1050 }
1051
__QAIC_HEADER(apps_std_ftrunc)1052 __QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ftrunc)(apps_std_FILE sin, int offset) __QAIC_HEADER_ATTRIBUTE {
1053 int nErr = 0, fd = -1;
1054 struct apps_std_info* sinfo = 0;
1055
1056 VERIFYC(0 == (nErr = apps_std_FILE_get(sin, &sinfo)), AEE_EBADFD);
1057 VERIFYC(-1 != (fd = fileno(sinfo->u.stream)), AEE_EBADFD);
1058
1059 if(0 != ftruncate(fd, offset)) {
1060 return ERRNO;
1061 }
1062 bail:
1063 return nErr;
1064 }
1065
__QAIC_IMPL(apps_std_frename)1066 __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_frename)(const char* oldname, const char* newname) __QAIC_IMPL_ATTRIBUTE {
1067 int nErr = AEE_SUCCESS;
1068
1069 VERIFYC(NULL != oldname && NULL != newname, AEE_EBADPARM);
1070 nErr = rename(oldname, newname);
1071 bail:
1072 if(nErr != AEE_SUCCESS) {
1073 VERIFY_EPRINTF("Error %x: failed to rename file, errno is %s\n", nErr, strerror(ERRNO));
1074 }
1075 return nErr;
1076 }
1077