source: asp3_tinet_ecnl_rx/trunk/ntshell/src/io_stub.c@ 374

Last change on this file since 374 was 374, checked in by coas-nagasima, 5 years ago

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 17.3 KB
RevLine 
[337]1/*
2 * TOPPERS ECHONET Lite Communication Middleware
[374]3 *
[337]4 * Copyright (C) 2017 Cores Co., Ltd. Japan
[374]5 *
[337]6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
[374]28 *
[337]29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
[374]34 *
[337]35 * @(#) $Id$
36 */
37#include "shellif.h"
38#include <stdint.h>
39#include "ff.h"
40#include <kernel.h>
41#include <t_syslog.h>
42#include <t_stdlib.h>
43#include <sil.h>
44#include <string.h>
[374]45#include "syssvc/serial.h"
[337]46#include "syssvc/syslog.h"
47#include "socket_stub.h"
48#include "util/ntstdio.h"
49#include "usrcmd.h"
50#include "core/ntlibc.h"
51#include "kernel_cfg.h"
[374]52#include "target_syssvc.h"
[337]53
54int fresult2errno(FRESULT res)
55{
56 switch (res) {
57 case FR_INVALID_OBJECT:
58 return -EINVAL;
59 case FR_TOO_MANY_OPEN_FILES:
60 return -ENOMEM;
61 case FR_NO_FILE:
62 case FR_NO_PATH:
63 case FR_INVALID_DRIVE:
64 case FR_INVALID_NAME:
65 return -ENOENT;
66 case FR_DISK_ERR:
67 case FR_NO_FILESYSTEM:
68 case FR_NOT_ENABLED:
69 return -ENODEV;
70 case FR_WRITE_PROTECTED:
71 case FR_DENIED:
72 return -EACCES;
73 case FR_EXIST:
74 return -EEXIST;
75 case FR_INT_ERR:
76 default:
77 return -EIO;
78 }
79}
80
[374]81static int file_close(struct SHELL_FILE *fp);
82static size_t file_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
83static size_t file_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
84static off_t file_seek(struct SHELL_FILE *fp, off_t ofs, int org);
85static int file_ioctl(struct SHELL_FILE *fp, int req, void *arg);
86static bool_t file_readable(struct SHELL_FILE *fp);
87static void file_delete(struct SHELL_FILE *fp);
88
89static int dir_close(struct SHELL_FILE *fp);
90static size_t dir_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
91static size_t dir_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
92static off_t dir_seek(struct SHELL_FILE *fp, off_t ofs, int org);
93static int dir_ioctl(struct SHELL_FILE *fp, int req, void *arg);
94static bool_t dir_readable(struct SHELL_FILE *fp);
95static void dir_delete(struct SHELL_FILE *fp);
96
97IO_TYPE IO_TYPE_FILE = { file_close, file_read, file_write, file_seek, file_ioctl, file_readable, file_delete };
98IO_TYPE IO_TYPE_DIR = { dir_close, dir_read, dir_write, dir_seek, dir_ioctl, dir_readable, dir_delete };
99
100int shell_open(const char *path, int flags, void *arg)
[337]101{
102 FRESULT res;
[374]103 struct SHELL_FILE *fp;
[337]104
105 if (flags & O_DIRECTORY) {
[374]106 fp = new_fp(&IO_TYPE_DIR, 0, 0);
[337]107 if (fp == NULL)
108 return -ENOMEM;
109
[374]110 fp->exinf = malloc(sizeof(struct SHELL_DIR));
111 memset(fp->exinf, 0, sizeof(struct SHELL_DIR));
112
113 FATFS_DIR *dir = &((struct SHELL_DIR *)fp->exinf)->dir;
[337]114 FRESULT res;
115 if ((res = f_opendir(dir, path)) != FR_OK) {
116 return fresult2errno(res);
117 }
118 return 0;
119 }
120
[374]121 fp = new_fp(&IO_TYPE_FILE, 0, 1);
[337]122 if (fp == NULL)
123 return -ENOMEM;
124
[374]125 fp->exinf = malloc(sizeof(FIL));
126 memset(fp->exinf, 0, sizeof(FIL));
127
[337]128 BYTE fmd = 0;
129 switch (flags & O_ACCMODE) {
130 case O_RDONLY:
131 fmd = FA_READ;
132 break;
133 case O_WRONLY:
134 fmd = FA_WRITE;
135 break;
136 default:
137 fmd = FA_READ | FA_WRITE;
138 break;
139 }
140 /* ファイルを作成 */
141 if (flags & O_CREAT) {
142 /* 既存の内容は消す */
143 if (flags & O_TRUNC) {
144 fmd |= FA_CREATE_ALWAYS;
145 }
146 /* 新規作成の保障 */
147 else if (flags & O_EXCL) {
148 fmd |= FA_CREATE_NEW;
149 }
150 else {
151 fmd |= FA_OPEN_ALWAYS;
152 }
153 }
154 /* ある場合は開く */
155 else {
156 /* 既存の内容は消す */
157 if (flags & O_TRUNC) {
158 fmd |= FA_CREATE_ALWAYS;
159 }
160 }
161
[374]162 if ((res = f_open((FIL *)fp->exinf, path, fmd)) == FR_OK) {
[337]163 fp->handle = fp->fd;
164 return fp->fd;
165 }
166
167 return fresult2errno(res);
168}
169
[374]170int file_close(struct SHELL_FILE *fp)
[337]171{
172 FRESULT res;
173
[374]174 if ((res = f_close((FIL *)fp->exinf)) == FR_OK) {
[337]175 return 0;
176 }
177
178 return -EINVAL;
179}
180
[374]181size_t file_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
[337]182{
183 unsigned int ret = 0;
184 FRESULT res;
185
[374]186 if ((res = f_read((FIL *)fp->exinf, data, len, &ret)) != FR_OK)
[337]187 return -EIO;
188
189 return ret;
190}
191
[374]192size_t file_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
[337]193{
194 unsigned int ret = 0;
195 FRESULT res;
196
[374]197 if ((res = f_write((FIL *)fp->exinf, data, len, &ret)) != FR_OK)
[337]198 return -EIO;
199
200 return ret;
201}
202
[374]203off_t file_seek(struct SHELL_FILE *fp, off_t ptr, int dir)
[337]204{
205 switch (dir) {
206 case SEEK_SET:
207 dir = F_SEEK_SET;
208 break;
209 case SEEK_CUR:
210 dir = F_SEEK_CUR;
211 break;
212 case SEEK_END:
213 dir = F_SEEK_END;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 FRESULT res;
[374]220 if ((res = f_seek((FIL *)fp->exinf, ptr, dir)) != FR_OK)
[337]221 return -EIO;
222
[374]223 return ((FIL *)fp->exinf)->fptr;
[337]224}
225
[374]226int file_ioctl(struct SHELL_FILE *fp, int req, void *arg)
[337]227{
228 DRESULT res;
229
[374]230 if ((res = disk_ioctl(((FIL *)fp->exinf)->fs->drv, req, arg) != RES_OK))
[337]231 return -EINVAL;
232
233 return 0;
234}
235
[374]236bool_t file_readable(struct SHELL_FILE *fp)
237{
238 return fp->readevt_w != fp->readevt_r;
239}
240
241void file_delete(struct SHELL_FILE *fp)
242{
243 free((FIL *)fp->exinf);
244 fp->exinf = NULL;
245}
246
[337]247int shell_close(int fd)
248{
[374]249 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]250 if (fp == NULL)
251 return -EBADF;
252
[374]253 int ret = fp->type->close(fp);
[337]254
255 delete_fp(fp);
256
257 return ret;
258}
259
260ssize_t shell_read(int fd, void *data, size_t len)
261{
[374]262 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]263 if (fp == NULL)
264 return -EBADF;
265
[374]266 return fp->type->read(fp, (unsigned char *)data, len);
[337]267}
268
269int shell_readv(int fd, const struct iovec *iov, int iovcnt)
270{
271 int result = 0;
[374]272 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]273 if (fp == NULL)
274 return -EBADF;
275
276 const struct iovec *end = &iov[iovcnt];
277 for (; iov < end; iov++) {
[374]278 result += fp->type->read(fp, (unsigned char *)iov->iov_base, iov->iov_len);
[337]279 }
280
281 return result;
282}
283
284ssize_t shell_write(int fd, const void *data, size_t len)
285{
[374]286 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]287 if (fp == NULL)
288 return -EBADF;
289
[374]290 return fp->type->write(fp, (unsigned char *)data, len);
[337]291}
292
293int shell_writev(int fd, const struct iovec *iov, int iovcnt)
294{
295 int result = 0;
[374]296 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]297 if (fp == NULL)
298 return -EBADF;
299
300 const struct iovec *end = &iov[iovcnt];
301 for (; iov < end; iov++) {
[374]302 result += fp->type->write(fp, (unsigned char *)iov->iov_base, iov->iov_len);
[337]303 }
304
305 return result;
306}
307
308int shell_llseek(int fd, off_t ptr, off_t *result, int dir)
309{
[374]310 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]311 if (fp == NULL)
312 return -EBADF;
313
[374]314 off_t ret = fp->type->seek(fp, ptr, dir);
[337]315 if (ret < 0)
316 return ret;
317
318 *result = ret;
319 return 0;
320}
321
322int shell_fstat(int fd, struct stat * st)
323{
[374]324 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]325 if (fp == NULL)
326 return -EBADF;
327
328 memset(st, 0, sizeof(*st));
329 st->st_mode = S_IFCHR;
330 //st->st_blksize = 1024;
331 return 0;
332}
333
334int shell_fsync(int fd)
335{
[374]336 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]337 if (fp == NULL)
338 return -EBADF;
339 return -EIO;
340}
341
342int shell_ftruncate(int fd, off_t length)
343{
[374]344 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]345 if (fp == NULL)
346 return -EBADF;
347
348 FRESULT res;
[374]349 if ((res = f_truncate((FIL *)fp->exinf)) != FR_OK)
[337]350 return fresult2errno(res);
351
352 return 0;
353}
354
355int shell_fcntl(int fd, int cmd, void *arg)
356{
357 return shell_ioctl(fd, cmd, arg);
358}
359
[374]360extern IO_TYPE IO_TYPE_SIO;
361
[337]362int sio_tcgetattr(int fd, struct termios *termios)
363{
[374]364 struct SHELL_FILE *fp = fd_to_fp(fd);
365 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
366 return -EBADF;
[337]367
[374]368 ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
[337]369
[374]370 memset(termios, 0, sizeof(*termios));
371
372 if (ntstdio->option & NTSTDIO_OPTION_LINE_ECHO) {
373 termios->c_lflag |= ECHO;
[337]374 }
[374]375 else {
376 termios->c_lflag &= ~ECHO;
377 }
378 if (ntstdio->option & NTSTDIO_OPTION_CANON) {
379 termios->c_lflag |= ICANON;
380 }
381 else {
382 termios->c_lflag &= ~ICANON;
383 }
384 if (ntstdio->option & NTSTDIO_OPTION_LF_CR) {
385 termios->c_iflag |= INLCR;
386 }
387 else {
388 termios->c_iflag &= ~INLCR;
389 }
390 if (ntstdio->option & NTSTDIO_OPTION_LF_CRLF) {
391 termios->c_oflag |= ONLCR;
392 }
393 else {
394 termios->c_oflag &= ~ONLCR;
395 }
396
[337]397 return 0;
398}
399
400int sio_tcsetattr(int fd, int optional_actions, const struct termios *termios)
401{
[374]402 struct SHELL_FILE *fp = fd_to_fp(fd);
403 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
404 return -EBADF;
[337]405
[374]406 ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
407
408 if (optional_actions == TCSANOW) {
[337]409 if (termios->c_lflag & ECHO) {
[374]410 ntstdio->option |= NTSTDIO_OPTION_LINE_ECHO;
[337]411 }
412 else {
[374]413 ntstdio->option &= ~NTSTDIO_OPTION_LINE_ECHO;
[337]414 }
415 if (termios->c_lflag & ICANON) {
[374]416 ntstdio->option |= NTSTDIO_OPTION_CANON;
[337]417 }
418 else {
[374]419 ntstdio->option &= ~NTSTDIO_OPTION_CANON;
[337]420 }
421 if (termios->c_iflag & INLCR) {
[374]422 ntstdio->option |= NTSTDIO_OPTION_LF_CR;
[337]423 }
[374]424 else {
425 ntstdio->option &= ~NTSTDIO_OPTION_LF_CR;
[337]426 }
427 if (termios->c_oflag & ONLCR) {
[374]428 ntstdio->option |= NTSTDIO_OPTION_LF_CRLF;
[337]429 }
430 else {
[374]431 ntstdio->option &= ~NTSTDIO_OPTION_LF_CRLF;
[337]432 }
433 return 0;
434 }
[374]435
[337]436 shell_abort();
437 return 0;
438}
439
440int shell_stat(const char *__restrict path, struct stat *__restrict st)
441{
442 FILINFO fi;
443 FRESULT ret;
[374]444#if FF_USE_LFN
445 static char lfn[FF_MAX_LFN + 1]; /* Buffer to store the LFN */
[337]446 fi.lfname = lfn;
447 fi.lfsize = sizeof lfn;
448#endif
449 if (strcmp(path, ".") == 0) {
[374]450 char cwd[FF_MAX_LFN];
[337]451 if ((ret = f_getcwd(cwd, sizeof(cwd))) != FR_OK) {
452 return fresult2errno(ret);
453 }
454 int l = strlen(cwd);
455 // ルートディレクトリの場合
456 if (cwd[l - 2] == ':' && cwd[l - 1] == '/') {
457 st->st_size = 0;
458 st->st_mtim.tv_nsec = 0;
459 st->st_mtim.tv_sec = 0;
460 st->st_mode = S_IFDIR;
461 return 0;
462 }
463 if ((ret = f_stat(cwd, &fi)) != FR_OK) {
464 return fresult2errno(ret);
465 }
466 }
467 else if ((ret = f_stat(path, &fi)) != FR_OK) {
468 return fresult2errno(ret);
469 }
470
471 st->st_size = fi.fsize;
472 st->st_mtim.tv_nsec = 0;
473 st->st_mtim.tv_sec = fi.fdate + fi.ftime;
[374]474 st->st_mode = (S_IRUSR | S_IRGRP | S_IROTH);
[337]475 st->st_mode |= (fi.fattrib & AM_RDO) ? 0 : (S_IWUSR | S_IWGRP | S_IWOTH);
476 st->st_mode |= (fi.fattrib & (AM_DIR | AM_VOL)) ? S_IFDIR : S_IFREG;
477
478 return 0;
479}
480
481int shell_lstat(const char *__restrict path, struct stat *__restrict st)
482{
483 return shell_stat(path, st);
484}
485
486int shell_link(const char *a, const char *b)
487{
488 return -EPERM;
489}
490
491int shell_unlink(const char *path)
492{
493 FRESULT res;
494
495 if ((res = f_unlink(path)) != FR_OK)
496 return -EIO;
497
498 return 0;
499}
500
501int shell_rmdir(const char *path)
502{
503 FRESULT res;
504
505 if ((res = f_unlink(path)) != FR_OK)
506 return -EIO;
507
508 return 0;
509}
510
511int shell_rename(const char *oldpath, const char *newpath)
512{
513 FRESULT res;
514
515 if ((res = f_rename(oldpath, newpath)) != FR_OK)
516 return fresult2errno(res);
517 return 0;
518}
519
520#define S_IREAD S_IRUSR
521#define S_IWRITE S_IWUSR
522
523int shell_mkdir(const char *path, mode_t mode)
524{
525 FRESULT res;
526
527 if ((res = f_mkdir(path)) != FR_OK)
528 return fresult2errno(res);
529
530 BYTE attr = 0;
531 BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
532
[374]533 if (mode & S_IREAD) {
534 if ((mode & S_IWRITE) == 0) {
[337]535 attr |= AM_RDO;
536 }
537 }
538 else {
539 attr |= AM_SYS;
540 }
541
[374]542 if ((res = f_chmod(path, attr, mask)) != FR_OK) {
[337]543 return fresult2errno(res);
544 }
545
546 return 0;
547}
548
549int shell_chmod(const char *path, mode_t mode)
550{
551 FRESULT res;
552 BYTE attr = 0;
553 BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
554
[374]555 if (mode & S_IREAD) {
556 if ((mode & S_IWRITE) == 0) {
[337]557 attr |= AM_RDO;
558 }
559 }
560 else {
561 attr |= AM_SYS;
562 }
563
[374]564 if ((res = f_chmod(path, attr, mask)) != FR_OK) {
[337]565 return fresult2errno(res);
566 }
567
568 return 0;
569}
570
571char *shell_getcwd(char *buf, size_t size)
572{
573 FRESULT ret;
[374]574 if ((ret = f_getcwd(buf, size)) != FR_OK) {
[337]575 return NULL;
576 }
577
578 return buf;
579}
580
581int shell_chdir(const char *path)
582{
583 FRESULT res;
584 if ((res = f_chdir(path)) != FR_OK) {
585 return fresult2errno(res);
586 }
587
588 return 0;
589}
590
591int shell_chroot(const char *path)
592{
593 shell_abort();
594 return -EPERM;
595}
596
[374]597int dir_close(struct SHELL_FILE *fp)
[337]598{
599 FRESULT res;
[374]600 if ((res = f_closedir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
[337]601 return fresult2errno(res);
602 }
603
604 return 0;
605}
606
607int shell_getdents(int fd, struct dirent *de, size_t len)
608{
609 if (len < sizeof(struct dirent))
610 return -EINVAL;
611
[374]612 struct SHELL_FILE *fp = fd_to_fp(fd);
[337]613 if (fp == NULL)
614 return -EBADF;
615
616 FILINFO fno;
[374]617#if FF_USE_LFN
618 static char lfn[FF_MAX_LFN + 1]; /* Buffer to store the LFN */
[337]619 fno.lfname = lfn;
620 fno.lfsize = sizeof lfn;
621#endif
622 FRESULT res;
[374]623 if ((res = f_readdir(&((struct SHELL_DIR *)fp->exinf)->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
[337]624 return fresult2errno(res);
625 }
626
627 memset(de, 0, sizeof(*de));
[374]628#if FF_USE_LFN
[337]629 ntlibc_strlcpy(de->d_name, *fno.lfname ? fno.lfname : fno.fname, sizeof(de->d_name));
630#else
631 ntlibc_strlcpy(de->d_name, fno.fname, sizeof(de->d_name));
632#endif
633
634 return 0;
635}
636
[374]637size_t dir_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
[337]638{
639 return -EPERM;
640}
641
[374]642size_t dir_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
[337]643{
644 return -EPERM;
645}
646
[374]647off_t dir_seek(struct SHELL_FILE *fp, off_t ptr, int dir)
[337]648{
649 FRESULT res;
650
651 if (dir != SEEK_SET)
652 return -EINVAL;
653
654 if (ptr == 0) {
[374]655 if ((res = f_rewinddir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
[337]656 return fresult2errno(res);
657 }
658 }
659 else {
660 FILINFO fno;
[374]661#if FF_USE_LFN
662 static char lfn[FF_MAX_LFN + 1]; /* Buffer to store the LFN */
[337]663 fno.lfname = lfn;
664 fno.lfsize = sizeof lfn;
665#endif
[374]666 if ((res = f_rewinddir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
[337]667 return fresult2errno(res);
668 }
669
670 for (int i = 0; i < ptr; i++) {
[374]671 if ((res = f_readdir(&((struct SHELL_DIR *)fp->exinf)->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
[337]672 return fresult2errno(res);
673 }
674 }
675 }
676
677 return ptr;
678}
679
[374]680int dir_ioctl(struct SHELL_FILE *fp, int req, void *arg)
[337]681{
682 return -EINVAL;
683}
684
[374]685bool_t dir_readable(struct SHELL_FILE *fp)
686{
687 return fp->readevt_w != fp->readevt_r;
688}
689
690void dir_delete(struct SHELL_FILE *fp)
691{
692 free((struct SHELL_DIR *)fp->exinf);
693 fp->exinf = NULL;
694}
695
[337]696pid_t shell_getpid(void)
697{
698 return 1;
699}
700
701int shell_access(const char *path, int mode)
702{
703 struct stat st;
704 int ret;
705
706 ret = shell_stat(path, &st);
707 if (ret != 0)
708 return ret;
709
710 return 0;
711}
712
713#ifndef _MSC_VER
714extern uint32_t _HeapBase;
715extern uint32_t _HeapLimit;
716#else
717uint8_t _HeapBase[14 * 4096];
718#define _HeapLimit _HeapBase[sizeof(_HeapBase)]
719#endif
720
721void *shell_brk(void *addr)
722{
723 if (addr == 0) {
724 return (void *)(&_HeapBase);
725 }
726 if ((addr >= (void *)&_HeapBase) && (addr < (void *)&_HeapLimit)) {
727 return addr;
728 }
729 return (void *)-1;
730}
731
732void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset)
733{
734 if (fd != -1)
735 return (void *)-EINVAL;
736
737 if ((length >= 0) && (length <= sizeof(&_HeapBase))) {
738 return &_HeapBase;
739 }
740 return (void *)-1;
741}
742
743int shell_mprotect(void *addr, size_t len, int prot)
744{
745 //if ((addr >= (void *)&_HeapBase) && (addr + len < (void *)&_HeapLimit)) {
[374]746 return 0;
747//}
748//return -1;
[337]749}
750
751#include "tlsf.h"
752
753static tlsf_t sys_tlsf;
754static pool_t sys_pool;
755
[374]756void sys_tlsf_init(void)
[337]757{
758 sys_tlsf = tlsf_create(&_HeapBase);
759 if (sys_tlsf == NULL)
760 return;
761
762 sys_pool = tlsf_add_pool(sys_tlsf, ((uint8_t *)&_HeapBase) + tlsf_size(), ((intptr_t)&_HeapLimit - (intptr_t)&_HeapBase) - tlsf_size());
763}
764
765void sys_fini(void)
766{
767 tlsf_destroy(sys_tlsf);
768}
769
770void *malloc(size_t size)
771{
772 void *result;
773 wai_sem(SEM_MALLOC);
774 result = tlsf_malloc(sys_tlsf, size);
775 sig_sem(SEM_MALLOC);
776 if (result == NULL)
777 tlsf_check_pool(sys_pool);
778 return result;
779}
780
781void *calloc(size_t size, size_t count)
782{
783 void *result;
784 wai_sem(SEM_MALLOC);
785 result = tlsf_malloc(sys_tlsf, count * size);
786 sig_sem(SEM_MALLOC);
787 if (result != NULL)
788 memset(result, 0, count * size);
789 else
790 tlsf_check_pool(sys_pool);
791 return result;
792}
793
794void *realloc(void *ptr, size_t size)
795{
796 void *result;
797 wai_sem(SEM_MALLOC);
798 result = tlsf_realloc(sys_tlsf, ptr, size);
799 sig_sem(SEM_MALLOC);
800 if (result == NULL)
801 tlsf_check_pool(sys_pool);
802 return result;
803}
804
805void free(void *ptr)
806{
807 wai_sem(SEM_MALLOC);
808 tlsf_free(sys_tlsf, ptr);
809 sig_sem(SEM_MALLOC);
810}
811
Note: See TracBrowser for help on using the repository browser.