/* * TOPPERS ECHONET Lite Communication Middleware * * Copyright (C) 2017 Cores Co., Ltd. Japan * * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー * スコード中に含まれていること. * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 * の無保証規定を掲載すること. * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ * と. * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 * 作権表示,この利用条件および下記の無保証規定を掲載すること. * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに * 報告すること. * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを * 免責すること. * * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ * の責任を負わない. * * @(#) $Id: io_stub.c 286 2017-05-02 15:25:33Z coas-nagasima $ */ #include #include #include #include #include #include "ff.h" #include #include #include #include #include #include #include #include #include "syssvc/syslog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "ff.h" #include "socket_stub.h" #include "../../../musl-1.1.12/include/_dirent.h" #include "../../../musl-1.1.12/include/_termios.h" #include "ntstdio.h" int shell_open(const char * path, int flags) { FRESULT res; struct _IO_FILE *fp = new_file_fd(0); if (fp == NULL) return -1; BYTE fmd = 0; switch (flags & O_ACCMODE) { case O_RDONLY: fmd = FA_READ; break; case O_WRONLY: fmd = FA_WRITE; break; default: fmd = FA_READ | FA_WRITE; break; } /* ファイルを作成 */ if (flags & O_CREAT) { /* 既存の内容は消す */ if (flags & O_TRUNC) { fmd |= FA_CREATE_ALWAYS; } /* 新規作成の保障 */ else if (flags & O_EXCL) { fmd |= FA_CREATE_NEW; } else { fmd |= FA_OPEN_ALWAYS; } } /* ある場合は開く */ else { /* 既存の内容は消す */ if (flags & O_TRUNC) { fmd |= FA_CREATE_ALWAYS; } } if ((res = f_open(&fp->file, path, fmd)) == FR_OK) { fp->handle = fp->fd; return fp->fd; } return -1; } int file_close(struct _IO_FILE *fp) { FRESULT res; if ((res = f_close(&fp->file)) == FR_OK) { return 0; } return -1; } size_t file_read(struct _IO_FILE *fp, unsigned char *data, size_t len) { unsigned int ret = 0; FRESULT res; if ((res = f_read(&fp->file, data, len, &ret)) != FR_OK) return -1; return ret; } size_t file_write(struct _IO_FILE *fp, const unsigned char *data, size_t len) { unsigned int ret = 0; FRESULT res; if ((res = f_write(&fp->file, data, len, &ret)) != FR_OK) return -1; return ret; } int shell_close(int fd) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; return fp->close(fp); } int shell_read(int fd, char *data, int len) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; return fp->read(fp, (unsigned char *)data, len); } int shell_write(int fd, char *data, int len) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; return fp->write(fp, (unsigned char *)data, len); } int shell_lseek(int fd, int ptr, int dir) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; FRESULT res; if ((res = f_seek(&fp->file, ptr, dir)) != FR_OK) return -1; return fp->file.fptr; } int shell_fstat(int fd, struct stat * st) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; memset(st, 0, sizeof(*st)); st->st_mode = S_IFCHR; //st->st_blksize = 1024; return 0; } int fsync(int fd) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; return -1; } int ftruncate(int fd, off_t length) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; FRESULT res; if ((res = f_truncate(&fp->file)) != FR_OK) return -1; return 0; } int ioctl(int fd, int request, va_list ap) { struct _IO_FILE *fp = fd_to_fp(fd); if (fp == NULL) return -1; return -1; } int tcgetattr(int fd, struct termios *termios) { extern ntstdio_t ntstdio; if (fd == STDIN_FILENO) { memset(termios, 0, sizeof(*termios)); if (ntstdio.option & NTSTDIO_OPTION_LINE_ECHO) { termios->c_lflag |= ECHO; } else { termios->c_lflag &= ~ECHO; } if (ntstdio.option & NTSTDIO_OPTION_CANON) { termios->c_lflag |= ICANON; } else { termios->c_lflag &= ~ICANON; } if (ntstdio.option & NTSTDIO_OPTION_LF_CR) { termios->c_iflag |= INLCR; } else { termios->c_iflag &= ~INLCR; } if (ntstdio.option & NTSTDIO_OPTION_LF_CRLF) { termios->c_oflag |= ONLCR; } else { termios->c_oflag &= ~ONLCR; } return 0; } abort(); return 0; } int tcsetattr(int fd, int optional_actions, const struct termios *termios) { extern ntstdio_t ntstdio; if ((fd == STDIN_FILENO) && (optional_actions == TCSANOW)) { if (termios->c_lflag & ECHO) { ntstdio.option |= NTSTDIO_OPTION_LINE_ECHO; } else { ntstdio.option &= ~NTSTDIO_OPTION_LINE_ECHO; } if (termios->c_lflag & ICANON) { ntstdio.option |= NTSTDIO_OPTION_CANON; } else { ntstdio.option &= ~NTSTDIO_OPTION_CANON; } if (termios->c_iflag & INLCR) { ntstdio.option |= NTSTDIO_OPTION_LF_CR; } else{ ntstdio.option &= ~NTSTDIO_OPTION_LF_CR; } if (termios->c_oflag & ONLCR) { ntstdio.option |= NTSTDIO_OPTION_LF_CRLF; } else { ntstdio.option &= ~NTSTDIO_OPTION_LF_CRLF; } return 0; } abort(); return 0; } int shell_stat(const char *path, struct stat *st) { FILINFO fi; FRESULT ret; #if _USE_LFN static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */ fi.lfname = lfn; fi.lfsize = sizeof lfn; #endif if (strcmp(path, ".") == 0) { char cwd[_MAX_LFN]; if ((ret = f_getcwd(cwd, sizeof(cwd))) != FR_OK) { return -1; } int l = strlen(cwd); // ルートディレクトリの場合 if (cwd[l - 2] == ':' && cwd[l - 1] == '/') { st->st_size = 0; st->st_mtime = 0; st->st_mode = S_IFDIR; return 0; } if ((ret = f_stat(cwd, &fi)) != FR_OK) { return -1; } } else if ((ret = f_stat(path, &fi)) != FR_OK) { return -1; } st->st_size = fi.fsize; st->st_mtime = fi.fdate + fi.ftime; st->st_mode = (S_IRUSR | S_IRGRP | S_IROTH); st->st_mode |= (fi.fattrib & AM_RDO) ? 0 : (S_IWUSR | S_IWGRP | S_IWOTH); st->st_mode |= (fi.fattrib & (AM_DIR | AM_VOL)) ? S_IFDIR : S_IFREG; return 0; } int shell_link(void) { return -1; } int shell_unlink(const char *path) { FRESULT res; if ((res = f_unlink(path)) != FR_OK) return -1; return 0; } int rmdir(const char *path) { FRESULT res; if ((res = f_unlink(path)) != FR_OK) return -1; return 0; } int shell_rename(const char *oldpath, const char *newpath) { FRESULT res; if ((res = f_rename(oldpath, newpath)) != FR_OK) return -1; return 0; } int mkdir(const char *path, mode_t mode) { FRESULT res; if ((res = f_mkdir(path)) != FR_OK) return -1; BYTE attr = 0; BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID if(mode & S_IREAD) { if((mode & S_IWRITE) == 0) { attr |= AM_RDO; } } else { attr |= AM_SYS; } if((res = f_chmod(path, attr, mask)) != FR_OK) { return -1; } return 0; } int chmod(const char *path, mode_t mode) { FRESULT ret; BYTE attr = 0; BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID if(mode & S_IREAD) { if((mode & S_IWRITE) == 0) { attr |= AM_RDO; } } else { attr |= AM_SYS; } if((ret = f_chmod(path, attr, mask)) != FR_OK) { return -1; } return 0; } char *getcwd(char *buf, size_t size) { FRESULT ret; if((ret = f_getcwd(buf, size)) != FR_OK) { return NULL; } return buf; } int chdir(const char *path) { FRESULT ret; if ((ret = f_chdir(path)) != FR_OK) { return -1; } return 0; } int chroot(const char *path) { abort(); return -1; } DIR *opendir(const char *path) { DIR *dir = malloc(sizeof(DIR) + sizeof(struct dirent)); FRESULT ret; if ((ret = f_opendir(dir, path)) != FR_OK) { free(dir); return NULL; } dir->dirent = &dir[1]; return dir; } int closedir(DIR *dir) { FRESULT ret; if ((ret = f_closedir(dir)) != FR_OK) { free(dir); return -1; } free(dir); return 0; } struct dirent *readdir(DIR *dir) { struct dirent *de = dir->dirent; FILINFO fno; #if _USE_LFN static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */ fno.lfname = lfn; fno.lfsize = sizeof lfn; #endif FRESULT ret; if ((ret = f_readdir(dir, &fno)) != FR_OK || fno.fname[0] == '\0') { return NULL; } memset(de, 0, sizeof(*de)); #if _USE_LFN strlcpy(de->d_name, *fno.lfname ? fno.lfname : fno.fname, sizeof(de->d_name)); #else strlcpy(de->d_name, fno.fname, sizeof(de->d_name)); #endif return de; } void rewinddir(DIR *dir) { FRESULT ret; if ((ret = f_rewinddir(dir)) != FR_OK) { return; } } void seekdir(DIR *dir, long pos) { abort(); } long telldir(DIR *dir) { abort(); return 0; } int shell_getpid(int n) { return 1; }