michallenc commented on code in PR #10602:
URL: https://github.com/apache/nuttx/pull/10602#discussion_r1325884666


##########
libs/libc/stdio/lib_fopencookie.c:
##########
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * libs/libc/stdio/lib_fopencookie.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "libc.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct cookie_s
+{
+  void *cookie;                    /* pointer to the caller's cookie struct */
+  cookie_io_functions_t cookie_io; /* programmer-defined hook functions */
+  int cookie_fd;                   /* file descriptor */
+};
+
+static ssize_t freadcookie(FAR struct file *filep, FAR char *buf,
+                           size_t nbytes);
+static ssize_t fwritecookie(FAR struct file *filep, FAR const char *buf,
+                            size_t nbytes);
+static off_t fseekcookie(FAR struct file *filep, off_t offset, int whence);
+static int fclosecookie(FAR struct file *filep);
+
+/****************************************************************************
+  * Private Data
+ ****************************************************************************/
+
+static const struct file_operations cookie_fops =
+{
+  NULL,         /* open */
+  fclosecookie, /* close */
+  freadcookie,  /* read */
+  fwritecookie, /* write */
+  fseekcookie,  /* seek */
+  NULL,         /* ioctl */
+  NULL,         /* mmap */
+  NULL,         /* truncate */
+  NULL,         /* poll */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static ssize_t freadcookie(FAR struct file *filep, FAR char *buf,
+                           size_t nbytes)
+{
+  struct cookie_s *cookie = (struct cookie_s *)filep->f_priv;
+  int ret;
+
+  DEBUGASSERT(cookie->cookie != NULL && cookie->cookie_io.read != NULL);
+
+  ret = cookie->cookie_io.read(cookie->cookie, buf, nbytes);
+  return ret;
+}
+
+static ssize_t fwritecookie(FAR struct file *filep, FAR const char *buf,
+                            size_t nbytes)
+{
+  struct cookie_s *cookie = (struct cookie_s *)filep->f_priv;
+  int ret;
+
+  DEBUGASSERT(cookie->cookie != NULL && cookie->cookie_io.write != NULL);
+
+  ret = cookie->cookie_io.write(cookie->cookie, (FAR const char *)buf,
+                               nbytes);
+  return ret;
+}
+
+static off_t fseekcookie(FAR struct file *filep, off_t offset, int whence)
+{
+  struct cookie_s *cookie = (struct cookie_s *)filep->f_priv;
+  int ret;
+
+  DEBUGASSERT(cookie->cookie != NULL && cookie->cookie_io.seek != NULL);
+
+  ret = cookie->cookie_io.seek(cookie->cookie, &offset, whence);
+  return ret;
+}
+
+static int fclosecookie(FAR struct file *filep)
+{
+  struct cookie_s *cookie = (struct cookie_s *)filep->f_priv;
+  int ret;
+
+  DEBUGASSERT(cookie->cookie != NULL && cookie->cookie_io.close != NULL);
+
+  ret = cookie->cookie_io.close(cookie->cookie);
+
+  free(filep->f_priv);
+  free(filep->f_inode);
+  close(cookie->cookie_fd);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: fopencookie
+ ****************************************************************************/
+
+FAR FILE *fopencookie(void *restrict cookie, const char *restrict mode,
+                      cookie_io_functions_t io_funcs)
+{
+  FAR FILE *filestructp = NULL;
+  FAR struct file filep;
+  FAR struct inode *inode;
+  FAR struct cookie_s *cookie_priv;
+  int oflags;
+  int ret;
+  int fd;
+
+  /* Map the open mode string to open flags */
+
+  oflags = lib_mode2oflags(mode);
+  if (oflags < 0)
+    {
+      return NULL;
+    }
+
+  /* Allocate necessary structures. */
+
+  inode = lib_zalloc(sizeof(struct inode));
+  if (inode == NULL)
+    {
+      set_errno(-ENOMEM);
+      goto fopencookie_return;
+    }
+
+  cookie_priv = lib_zalloc(sizeof(struct cookie_s));
+  if (cookie_priv == NULL)
+    {
+      free(inode);
+      set_errno(-ENOMEM);
+      goto fopencookie_return;
+    }
+
+  memset(&filep, 0, sizeof(filep));
+
+  /* Fill cookie_priv structure. We need to add cookie provided by user
+   * and functions providd by user.
+   */
+
+  cookie_priv->cookie = cookie;
+  cookie_priv->cookie_io.read  = io_funcs.read;
+  cookie_priv->cookie_io.write = io_funcs.write;
+  cookie_priv->cookie_io.seek  = io_funcs.seek;
+  cookie_priv->cookie_io.close = io_funcs.close;
+
+  /* Add file operations */
+
+  inode->u.i_ops = &cookie_fops;
+
+  filep.f_oflags = oflags;
+  filep.f_inode = inode;
+  filep.f_priv = cookie_priv;
+
+  /* And get file descriptor. */
+
+  fd = file_allocate_from_tcb(nxsched_self(), filep.f_inode, filep.f_oflags,

Review Comment:
   > In my suggestion, you should stop to implement file_operation_s and call 
file_allocate_from_tcb. How do you go through fs/vfs without them?
   
   Yes, but you mention 
   
   > Assign the internal callback which read/write/seek through fd to 
cookie_io_functions_t in fopen
   
   How would I get fd without actually using `file_allocate_from_tcb`? I can 
call `fopen` to get it but that would require valid path. We could add hook 
that if path is NULL (or some fopencookie string) it returns correct FD and 
basically just does `file_allocate_from_tcb` and that could work. 



-- 
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

Reply via email to