Skip to content

Commit

Permalink
Add POSIX fcntl to control blocking
Browse files Browse the repository at this point in the history
Add the POSIX fcntl call, but only implementing F_SETFL and F_GETFL
for O_NONBLOCK, so users can control the blocking flag of streams
with only the integer file descriptor.

Necessary to portably control the blockingness of the console:

    int flags = fcntl(STDOUT_FILENO, F_GETFL);
    fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK);
  • Loading branch information
kjbracey committed May 3, 2018
1 parent a8ab233 commit cf91b1c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 8 deletions.
35 changes: 35 additions & 0 deletions platform/mbed_retarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,41 @@ extern "C" int fstat(int fildes, 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
27 changes: 19 additions & 8 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 @@ -504,6 +514,7 @@ extern "C" {
int isatty(int fildes);
int fsync(int fildes);
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

0 comments on commit cf91b1c

Please sign in to comment.