Skip to content

Add POSIX fcntl flag support #6791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions drivers/UARTSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UA
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
Expand Down
11 changes: 10 additions & 1 deletion platform/FileHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,16 @@ class FileHandle : private NonCopyable<FileHandle> {
*/
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
Expand Down
99 changes: 67 additions & 32 deletions platform/mbed_retarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,16 @@ static int reserve_filehandle() {
}

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) {
Expand Down Expand Up @@ -464,9 +464,9 @@ extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags) {
}

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;
Expand All @@ -476,36 +476,36 @@ extern "C" int open(const char *name, int oflag, ...) {
/* 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()) {
res = path.file();
} 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;
Expand Down Expand Up @@ -610,9 +610,9 @@ extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsign
#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;
Expand Down Expand Up @@ -700,9 +700,9 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int
#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;
Expand All @@ -727,8 +727,8 @@ extern "C" int _isatty(FILEHANDLE fh)
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;
Expand Down Expand Up @@ -765,8 +765,8 @@ int _lseek(FILEHANDLE fh, int offset, int whence)
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;
Expand All @@ -786,8 +786,8 @@ extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
}
#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;
Expand Down Expand Up @@ -850,8 +850,8 @@ extern "C" int _fstat(int fh, struct stat *st) {
}
#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;
Expand All @@ -862,6 +862,41 @@ extern "C" int fstat(int fh, struct stat *st) {
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) {
Expand Down
29 changes: 20 additions & 9 deletions platform/mbed_retarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,20 @@ typedef unsigned int uid_t; ///< User ID
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

Expand Down Expand Up @@ -480,6 +486,10 @@ enum {
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;
Expand All @@ -503,7 +513,8 @@ extern "C" {
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);
Expand Down