Skip to content

Commit cf91b1c

Browse files
committed
Add POSIX fcntl to control blocking
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);
1 parent a8ab233 commit cf91b1c

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

platform/mbed_retarget.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,41 @@ extern "C" int fstat(int fildes, struct stat *st) {
862862
return 0;
863863
}
864864

865+
extern "C" int fcntl(int fildes, int cmd, ...) {
866+
FileHandle *fhc = get_fhc(fildes);
867+
if (fhc == NULL) {
868+
errno = EBADF;
869+
return -1;
870+
}
871+
872+
switch (cmd) {
873+
case F_GETFL: {
874+
int flags = 0;
875+
if (fhc->is_blocking()) {
876+
flags |= O_NONBLOCK;
877+
}
878+
return flags;
879+
}
880+
case F_SETFL: {
881+
va_list ap;
882+
va_start(ap, cmd);
883+
int flags = va_arg(ap, int);
884+
va_end(ap);
885+
int ret = fhc->set_blocking(flags & O_NONBLOCK);
886+
if (ret < 0) {
887+
errno = -ret;
888+
return -1;
889+
}
890+
return 0;
891+
}
892+
893+
default: {
894+
errno = EINVAL;
895+
return -1;
896+
}
897+
}
898+
}
899+
865900
extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout)
866901
{
867902
if (nfds > OPEN_MAX) {

platform/mbed_retarget.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,20 @@ typedef unsigned int uid_t; ///< User ID
4343
typedef unsigned int gid_t; ///< Group ID
4444
#endif
4545

46-
#define O_RDONLY 0 ///< Open for reading
47-
#define O_WRONLY 1 ///< Open for writing
48-
#define O_RDWR 2 ///< Open for reading and writing
49-
#define O_CREAT 0x0200 ///< Create file if it does not exist
50-
#define O_TRUNC 0x0400 ///< Truncate file to zero length
51-
#define O_EXCL 0x0800 ///< Fail if file exists
52-
#define O_APPEND 0x0008 ///< Set file offset to end of file prior to each write
53-
#define O_BINARY 0x8000 ///< Open file in binary mode
46+
/* Flags for open() and fcntl(GETFL/SETFL)
47+
* At present, fcntl only supports reading and writing O_NONBLOCK
48+
*/
49+
#define O_RDONLY 0 ///< Open for reading
50+
#define O_WRONLY 1 ///< Open for writing
51+
#define O_RDWR 2 ///< Open for reading and writing
52+
#define O_NONBLOCK 0x0004 ///< Non-blocking mode
53+
#define O_APPEND 0x0008 ///< Set file offset to end of file prior to each write
54+
#define O_CREAT 0x0200 ///< Create file if it does not exist
55+
#define O_TRUNC 0x0400 ///< Truncate file to zero length
56+
#define O_EXCL 0x0800 ///< Fail if file exists
57+
#define O_BINARY 0x8000 ///< Open file in binary mode
58+
59+
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
5460

5561
#define NAME_MAX 255 ///< Maximum size of a name in a file path
5662

@@ -480,6 +486,10 @@ enum {
480486
DT_SOCK, ///< This is a UNIX domain socket.
481487
};
482488

489+
/* fcntl.h defines */
490+
#define F_GETFL 3
491+
#define F_SETFL 4
492+
483493
struct pollfd {
484494
int fd;
485495
short events;
@@ -504,6 +514,7 @@ extern "C" {
504514
int isatty(int fildes);
505515
int fsync(int fildes);
506516
int fstat(int fildes, struct stat *st);
517+
int fcntl(int fildes, int cmd, ...);
507518
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
508519
int close(int fildes);
509520
int stat(const char *path, struct stat *st);

0 commit comments

Comments
 (0)