Add mbed_file_handle lookup function

Add a necessary helper to allow FileHandle objects to be obtained
from POSIX file descriptors.

Primary envisaged use case is to act on STDIN_FILENO etc, eg to
set it non-blocking or use sigio, or to use the enable API.
pull/9797/head
Kevin Bracey 2019-02-21 16:46:24 +02:00
parent 649856f3ff
commit f91d044b6c
2 changed files with 36 additions and 16 deletions

View File

@ -290,7 +290,7 @@ static FileHandle *get_console(int fd)
}
/* Deal with the fact C library may not _open descriptors 0, 1, 2 - auto bind */
static FileHandle *get_fhc(int fd)
FileHandle *mbed::mbed_file_handle(int fd)
{
if (fd >= OPEN_MAX) {
return NULL;
@ -490,13 +490,13 @@ extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags)
/* Use the posix convention that stdin,out,err are filehandles 0,1,2.
*/
if (std::strcmp(name, __stdin_name) == 0) {
get_fhc(STDIN_FILENO);
mbed_file_handle(STDIN_FILENO);
return STDIN_FILENO;
} else if (std::strcmp(name, __stdout_name) == 0) {
get_fhc(STDOUT_FILENO);
mbed_file_handle(STDOUT_FILENO);
return STDOUT_FILENO;
} else if (std::strcmp(name, __stderr_name) == 0) {
get_fhc(STDERR_FILENO);
mbed_file_handle(STDERR_FILENO);
return STDERR_FILENO;
}
#endif
@ -555,7 +555,7 @@ extern "C" int PREFIX(_close)(FILEHANDLE fh)
extern "C" int close(int fildes)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
filehandles[fildes] = NULL;
if (fhc == NULL) {
errno = EBADF;
@ -667,7 +667,7 @@ finish:
extern "C" ssize_t write(int fildes, const void *buf, size_t length)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -761,8 +761,7 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int
extern "C" ssize_t read(int fildes, void *buf, size_t length)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -789,7 +788,7 @@ extern "C" int _isatty(FILEHANDLE fh)
extern "C" int isatty(int fildes)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return 0;
@ -828,7 +827,7 @@ int _lseek(FILEHANDLE fh, int offset, int whence)
extern "C" off_t lseek(int fildes, off_t offset, int whence)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -844,7 +843,7 @@ extern "C" off_t lseek(int fildes, off_t offset, int whence)
extern "C" int ftruncate(int fildes, off_t length)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -868,7 +867,7 @@ extern "C" int PREFIX(_ensure)(FILEHANDLE fh)
extern "C" int fsync(int fildes)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -886,7 +885,7 @@ extern "C" int fsync(int fildes)
#ifdef __ARMCC_VERSION
extern "C" long PREFIX(_flen)(FILEHANDLE fh)
{
FileHandle *fhc = get_fhc(fh);
FileHandle *fhc = mbed_file_handle(fh);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -936,7 +935,7 @@ extern "C" int _fstat(int fh, struct stat *st)
extern "C" int fstat(int fildes, struct stat *st)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -949,7 +948,7 @@ extern "C" int fstat(int fildes, struct stat *st)
extern "C" int fcntl(int fildes, int cmd, ...)
{
FileHandle *fhc = get_fhc(fildes);
FileHandle *fhc = mbed_file_handle(fildes);
if (fhc == NULL) {
errno = EBADF;
return -1;
@ -994,7 +993,7 @@ extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout)
for (nfds_t n = 0; n < nfds; n++) {
// Underlying FileHandle poll returns POLLNVAL if given NULL, so
// we don't need to take special action.
fhs[n].fh = get_fhc(fds[n].fd);
fhs[n].fh = mbed_file_handle(fds[n].fd);
fhs[n].events = fds[n].events;
}
int ret = poll(fhs, nfds, timeout);

View File

@ -133,6 +133,27 @@ FileHandle *mbed_target_override_console(int fd);
*/
FileHandle *mbed_override_console(int fd);
/** Look up the Mbed file handle corresponding to a file descriptor
*
* This conversion function permits an application to find the underlying
* FileHandle object corresponding to a POSIX file descriptor.
*
* This allows access to specialized behavior only available via the
* FileHandle API.
*
* Example of saving power by disabling console input - for buffered serial,
* this would release the RX interrupt handler, which would release the
* deep sleep lock.
* @code
* mbed_file_handle(STDIN_FILENO)->enable_input(false);
* @endcode
*
* @param fd file descriptor
* @return FileHandle pointer
* NULL if descriptor does not correspond to a FileHandle (only
* possible if it's not open with current implementation).
*/
FileHandle *mbed_file_handle(int fd);
}
typedef mbed::DirHandle DIR;