• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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