mu578 commented on PR #10602: URL: https://github.com/apache/nuttx/pull/10602#issuecomment-1719938788
> > I once had a look at that to handle a `fomempen` and alike properly, it would require that LIBC `struct FILE` not to be a direct alias to internal FS struct, as indeed you need to keep a reference to fs operation callbacks and permission flags, so it would require an indirection where `struct FILE` holds a private pointer to internal. Meanwhile, I think LIBC stdio would benefit at term that indirection to be made. > > ```c > > struct libc_stdio_file > > { > > // ... stdio specifics; > > libc_stdio_fread_t read; > > libc_stdio_fwrite_t write; > > libc_stdio_fseek_t seek; > > libc_stdio_fclose_t close; > > libc_stdio_cookie_t cookie; > > > > file_struct * internal; > > } > > > > typedef libc_stdio_file FILE; > > ``` > > we don't need add a new struct libc_stdio_file. Here is the current definition: > > ``` > struct file_struct > { > FAR struct file_struct *fs_next; /* Pointer to next file stream */ > rmutex_t fs_lock; /* Recursive lock */ > int fs_fd; /* File descriptor associated with stream */ > #ifndef CONFIG_STDIO_DISABLE_BUFFERING > FAR unsigned char *fs_bufstart; /* Pointer to start of buffer */ > FAR unsigned char *fs_bufend; /* Pointer to 1 past end of buffer */ > FAR unsigned char *fs_bufpos; /* Current position in buffer */ > FAR unsigned char *fs_bufread; /* Pointer to 1 past last buffered read char. */ > # if CONFIG_STDIO_BUFFER_SIZE > 0 > unsigned char fs_buffer[CONFIG_STDIO_BUFFER_SIZE]; > # endif > #endif > uint16_t fs_oflags; /* Open mode flags */ > uint8_t fs_flags; /* Stream flags */ > #if CONFIG_NUNGET_CHARS > 0 > uint8_t fs_nungotten; /* The number of characters buffered for ungetc */ > unsigned char fs_ungotten[CONFIG_NUNGET_CHARS]; > #endif > }; > > typedef struct file_struct FILE; > ``` > > Here is the simple change to the struct: > > ``` > struct file_struct > { > ... > - int fs_fd; /* File descriptor associated with stream */ > + cookie_io_functions_t fs_iofunc; > + FAR void * fs_cookie; > ... > }; > ``` > > and replace all read/write/seek/close with stream->iofunc.read/write/seek/close. The remaining work is adding the simple wrapper for fopen: > > ``` > static ssize_t read_fd(void *cookie, char *buf, size_t size) > { > int fd = (int)(intptr_t)cookie; > return read(fd, buf, size); > } > > static ssize_t write_fd(void *cookie, const char *buf, size_t size) > { > int fd = (int)(intptr_t)cookie; > return write(fd, buf, size); > } > > static int seek_fd(void *cookie, off_t *offset, int whence) > { > int fd = (int)(intptr_t)cookie; > off_t ret = seek(fd, *offset, whence); > if (ret >= 0) > { > *offset = ret; > ret = 0; > } > > return ret; > } > ``` you would if want to keep separated internal implementation to actual in-memory Os layout and a libc stdio frontend. Indeed `nutxx/fs.h` is one possible core-stream handling implementation, you don't want to mixup ; theoretically you could swap to any `OS vfs` implementation without changing any of your LIBC frontend. `fopencookie` is a solution/vilain patch which only regards end-user and a LIBC frontend to address the implementation of open_memstream and fmemopen, nuttx_file_struct should remain agnostic to such concerns, now I don't say it could be smarter and hold default callback pointers, the problem: the ones defined by `fopencookie` do not match exactly. But again do not hot patch such. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org