diff --git a/drivers/UARTSerial.h b/drivers/UARTSerial.h index 026215b..08c35e1 100644 --- a/drivers/UARTSerial.h +++ b/drivers/UARTSerial.h @@ -142,6 +142,15 @@ return 0; } + /** Check current blocking or non-blocking mode for file operations. + * + * @return true for blocking mode, false for non-blocking mode. + */ + virtual bool is_blocking() const + { + return _blocking; + } + /** Register a callback on state change of the file. * * The specified callback will be called on state changes such as when diff --git a/platform/FileHandle.h b/platform/FileHandle.h index b0cb10a..7c2c8f3 100644 --- a/platform/FileHandle.h +++ b/platform/FileHandle.h @@ -192,7 +192,16 @@ */ virtual int set_blocking(bool blocking) { - return -1; + return blocking ? 0 : -ENOTTY; + } + + /** Check current blocking or non-blocking mode for file operations. + * + * @return true for blocking mode, false for non-blocking mode. + */ + virtual bool is_blocking() const + { + return true; } /** Check for poll event flags diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 433b901..bd110cf 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -344,16 +344,16 @@ } int mbed::bind_to_fd(FileHandle *fh) { - int fh_i = reserve_filehandle(); - if (fh_i < 0) { - return fh_i; + int fildes = reserve_filehandle(); + if (fildes < 0) { + return fildes; } - filehandles[fh_i] = fh; - stdio_in_prev[fh_i] = 0; - stdio_out_prev[fh_i] = 0; + filehandles[fildes] = fh; + stdio_in_prev[fildes] = 0; + stdio_out_prev[fildes] = 0; - return fh_i; + return fildes; } static int unbind_from_fd(int fd, FileHandle *fh) { @@ -464,9 +464,9 @@ } extern "C" int open(const char *name, int oflag, ...) { - int fh_i = reserve_filehandle(); - if (fh_i < 0) { - return fh_i; + int fildes = reserve_filehandle(); + if (fildes < 0) { + return fildes; } FileHandle *res = NULL; @@ -476,7 +476,7 @@ /* The first part of the filename (between first 2 '/') is not a * registered mount point in the namespace. */ - return handle_open_errors(-ENODEV, fh_i); + return handle_open_errors(-ENODEV, fildes); } if (path.isFile()) { @@ -484,28 +484,28 @@ } else { FileSystemHandle *fs = path.fileSystem(); if (fs == NULL) { - return handle_open_errors(-ENODEV, fh_i); + return handle_open_errors(-ENODEV, fildes); } int err = fs->open(&res, path.fileName(), oflag); if (err) { - return handle_open_errors(err, fh_i); + return handle_open_errors(err, fildes); } } - filehandles[fh_i] = res; - stdio_in_prev[fh_i] = 0; - stdio_out_prev[fh_i] = 0; + filehandles[fildes] = res; + stdio_in_prev[fildes] = 0; + stdio_out_prev[fildes] = 0; - return fh_i; + return fildes; } extern "C" int PREFIX(_close)(FILEHANDLE fh) { return close(fh); } -extern "C" int close(int fh) { - FileHandle* fhc = get_fhc(fh); - filehandles[fh] = NULL; +extern "C" int close(int fildes) { + FileHandle* fhc = get_fhc(fildes); + filehandles[fildes] = NULL; if (fhc == NULL) { errno = EBADF; return -1; @@ -610,9 +610,9 @@ #endif } -extern "C" ssize_t write(int fh, const void *buf, size_t length) { +extern "C" ssize_t write(int fildes, const void *buf, size_t length) { - FileHandle* fhc = get_fhc(fh); + FileHandle* fhc = get_fhc(fildes); if (fhc == NULL) { errno = EBADF; return -1; @@ -700,9 +700,9 @@ #endif } -extern "C" ssize_t read(int fh, void *buf, size_t length) { +extern "C" ssize_t read(int fildes, void *buf, size_t length) { - FileHandle* fhc = get_fhc(fh); + FileHandle* fhc = get_fhc(fildes); if (fhc == NULL) { errno = EBADF; return -1; @@ -727,8 +727,8 @@ return isatty(fh); } -extern "C" int isatty(int fh) { - FileHandle* fhc = get_fhc(fh); +extern "C" int isatty(int fildes) { + FileHandle* fhc = get_fhc(fildes); if (fhc == NULL) { errno = EBADF; return 0; @@ -765,8 +765,8 @@ return off; } -extern "C" off_t lseek(int fh, off_t offset, int whence) { - FileHandle* fhc = get_fhc(fh); +extern "C" off_t lseek(int fildes, off_t offset, int whence) { + FileHandle* fhc = get_fhc(fildes); if (fhc == NULL) { errno = EBADF; return -1; @@ -786,8 +786,8 @@ } #endif -extern "C" int fsync(int fh) { - FileHandle* fhc = get_fhc(fh); +extern "C" int fsync(int fildes) { + FileHandle* fhc = get_fhc(fildes); if (fhc == NULL) { errno = EBADF; return -1; @@ -850,8 +850,8 @@ } #endif -extern "C" int fstat(int fh, struct stat *st) { - FileHandle* fhc = get_fhc(fh); +extern "C" int fstat(int fildes, struct stat *st) { + FileHandle* fhc = get_fhc(fildes); if (fhc == NULL) { errno = EBADF; return -1; @@ -862,6 +862,41 @@ return 0; } +extern "C" int fcntl(int fildes, int cmd, ...) { + FileHandle *fhc = get_fhc(fildes); + if (fhc == NULL) { + errno = EBADF; + return -1; + } + + switch (cmd) { + case F_GETFL: { + int flags = 0; + if (fhc->is_blocking()) { + flags |= O_NONBLOCK; + } + return flags; + } + case F_SETFL: { + va_list ap; + va_start(ap, cmd); + int flags = va_arg(ap, int); + va_end(ap); + int ret = fhc->set_blocking(flags & O_NONBLOCK); + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; + } + + default: { + errno = EINVAL; + return -1; + } + } +} + extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout) { if (nfds > OPEN_MAX) { diff --git a/platform/mbed_retarget.h b/platform/mbed_retarget.h index b3c6e6d..ef7f793 100644 --- a/platform/mbed_retarget.h +++ b/platform/mbed_retarget.h @@ -43,14 +43,20 @@ typedef unsigned int gid_t; ///< Group ID #endif -#define O_RDONLY 0 ///< Open for reading -#define O_WRONLY 1 ///< Open for writing -#define O_RDWR 2 ///< Open for reading and writing -#define O_CREAT 0x0200 ///< Create file if it does not exist -#define O_TRUNC 0x0400 ///< Truncate file to zero length -#define O_EXCL 0x0800 ///< Fail if file exists -#define O_APPEND 0x0008 ///< Set file offset to end of file prior to each write -#define O_BINARY 0x8000 ///< Open file in binary mode +/* Flags for open() and fcntl(GETFL/SETFL) + * At present, fcntl only supports reading and writing O_NONBLOCK + */ +#define O_RDONLY 0 ///< Open for reading +#define O_WRONLY 1 ///< Open for writing +#define O_RDWR 2 ///< Open for reading and writing +#define O_NONBLOCK 0x0004 ///< Non-blocking mode +#define O_APPEND 0x0008 ///< Set file offset to end of file prior to each write +#define O_CREAT 0x0200 ///< Create file if it does not exist +#define O_TRUNC 0x0400 ///< Truncate file to zero length +#define O_EXCL 0x0800 ///< Fail if file exists +#define O_BINARY 0x8000 ///< Open file in binary mode + +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) #define NAME_MAX 255 ///< Maximum size of a name in a file path @@ -480,6 +486,10 @@ DT_SOCK, ///< This is a UNIX domain socket. }; +/* fcntl.h defines */ +#define F_GETFL 3 +#define F_SETFL 4 + struct pollfd { int fd; short events; @@ -503,7 +513,8 @@ off_t lseek(int fildes, off_t offset, int whence); int isatty(int fildes); int fsync(int fildes); - int fstat(int fh, struct stat *st); + int fstat(int fildes, struct stat *st); + int fcntl(int fildes, int cmd, ...); int poll(struct pollfd fds[], nfds_t nfds, int timeout); int close(int fildes); int stat(const char *path, struct stat *st);