source: EcnlProtoTool/trunk/ntshell/src/io_stub.c@ 331

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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