source: asp3_tinet_ecnl_arm/trunk/ntshell/src/io_stub.c@ 352

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

arm向けASP3版ECNLを追加

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