]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
file: use easy handle meta for protocol struct
authorStefan Eissing <stefan@eissing.org>
Thu, 8 May 2025 09:01:24 +0000 (11:01 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 8 May 2025 11:18:45 +0000 (13:18 +0200)
Closes #17292

lib/file.c
lib/file.h
lib/request.c
lib/request.h

index cec73aabdaa33ac33a3338ad4ec8444ec6a4e599..b88f61230566ea737de6f797d875b7bbb602e47e 100644 (file)
 #define AMIGA_FILESYSTEM 1
 #endif
 
+/* meta key for storing protocol meta at easy handle */
+#define CURL_META_FILE_EASY   "meta:proto:file:easy"
+
+struct FILEPROTO {
+  char *path; /* the path we operate on */
+  char *freepath; /* pointer to the allocated block we must free, this might
+                     differ from the 'path' pointer */
+  int fd;     /* open file descriptor to read from! */
+};
+
 /*
  * Forward declarations.
  */
@@ -127,13 +137,34 @@ const struct Curl_handler Curl_handler_file = {
 };
 
 
+static void file_cleanup(struct FILEPROTO *file)
+{
+  Curl_safefree(file->freepath);
+  file->path = NULL;
+  if(file->fd != -1) {
+    close(file->fd);
+    file->fd = -1;
+  }
+}
+
+static void file_easy_dtor(void *key, size_t klen, void *entry)
+{
+  struct FILEPROTO *file = entry;
+  (void)key;
+  (void)klen;
+  file_cleanup(file);
+  free(file);
+}
+
 static CURLcode file_setup_connection(struct Curl_easy *data,
                                       struct connectdata *conn)
 {
+  struct FILEPROTO *filep;
   (void)conn;
   /* allocate the FILE specific struct */
-  data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
-  if(!data->req.p.file)
+  filep = calloc(1, sizeof(*filep));
+  if(!filep ||
+     Curl_meta_set(data, CURL_META_FILE_EASY, filep, file_easy_dtor))
     return CURLE_OUT_OF_MEMORY;
 
   return CURLE_OK;
@@ -147,7 +178,7 @@ static CURLcode file_setup_connection(struct Curl_easy *data,
 static CURLcode file_connect(struct Curl_easy *data, bool *done)
 {
   char *real_path;
-  struct FILEPROTO *file = data->req.p.file;
+  struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY);
   int fd;
 #ifdef DOS_FILESYSTEM
   size_t i;
@@ -156,6 +187,9 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
   size_t real_path_len;
   CURLcode result;
 
+  if(!file)
+    return CURLE_FAILED_INIT;
+
   if(file->path) {
     /* already connected.
      * the handler->connect_it() is normally only called once, but
@@ -257,17 +291,12 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
 static CURLcode file_done(struct Curl_easy *data,
                           CURLcode status, bool premature)
 {
-  struct FILEPROTO *file = data->req.p.file;
+  struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY);
   (void)status; /* not used */
   (void)premature; /* not used */
 
-  if(file) {
-    Curl_safefree(file->freepath);
-    file->path = NULL;
-    if(file->fd != -1)
-      close(file->fd);
-    file->fd = -1;
-  }
+  if(file)
+    file_cleanup(file);
 
   return CURLE_OK;
 }
@@ -287,9 +316,9 @@ static CURLcode file_disconnect(struct Curl_easy *data,
 #define DIRSEP '/'
 #endif
 
-static CURLcode file_upload(struct Curl_easy *data)
+static CURLcode file_upload(struct Curl_easy *data,
+                            struct FILEPROTO *file)
 {
-  struct FILEPROTO *file = data->req.p.file;
   const char *dir = strchr(file->path, DIRSEP);
   int fd;
   int mode;
@@ -418,6 +447,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
      are supported. This means that files on remotely mounted directories
      (via NFS, Samba, NT sharing) can be accessed through a file:// URL
   */
+  struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY);
   CURLcode result = CURLE_OK;
   struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
                           Windows version to have a different struct without
@@ -426,16 +456,15 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
   bool size_known;
   bool fstated = FALSE;
   int fd;
-  struct FILEPROTO *file;
   char *xfer_buf;
   size_t xfer_blen;
 
   *done = TRUE; /* unconditionally */
+  if(!file)
+    return CURLE_FAILED_INIT;
 
   if(data->state.upload)
-    return file_upload(data);
-
-  file = data->req.p.file;
+    return file_upload(data, file);
 
   /* get the fd from the connection phase */
   fd = file->fd;
index 456552559202fbe6c76d8c0a484c8b954637beb2..fea1eea57d6c9505f167b283be7ab611fca9a8b9 100644 (file)
  *
  ***************************************************************************/
 
-
-/****************************************************************************
- * FILE unique setup
- ***************************************************************************/
-struct FILEPROTO {
-  char *path; /* the path we operate on */
-  char *freepath; /* pointer to the allocated block we must free, this might
-                     differ from the 'path' pointer */
-  int fd;     /* open file descriptor to read from! */
-};
-
 #ifndef CURL_DISABLE_FILE
 extern const struct Curl_handler Curl_handler_file;
 #endif
index 43923d1438b58d13bec5495ec5afc65a04dee3c9..f937a7f4bfeddc2d4f41c57864dae42cbad47d78 100644 (file)
@@ -118,9 +118,6 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data)
 {
   struct curltime t0 = {0, 0};
 
-  /* This is a bit ugly. `req->p` is a union and we assume we can
-   * free this safely without leaks. */
-  Curl_safefree(req->p.file);
   Curl_safefree(req->newurl);
   Curl_client_reset(data);
   if(req->sendbuf_init)
@@ -171,9 +168,6 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data)
 
 void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data)
 {
-  /* This is a bit ugly. `req->p` is a union and we assume we can
-   * free this safely without leaks. */
-  Curl_safefree(req->p.file);
   Curl_safefree(req->newurl);
   if(req->sendbuf_init)
     Curl_bufq_free(&req->sendbuf);
index 1ac873099ae3a8ae5c88e514c06de4ad9acbd7fb..74d9f5343964c1c16d0377bbf0b0c8b23b21bd09 100644 (file)
@@ -99,11 +99,6 @@ struct SingleRequest {
   char *newurl;     /* Set to the new URL to use when a redirect or a retry is
                        wanted */
 
-  /* Allocated protocol-specific data. Each protocol handler makes sure this
-     points to data it needs. */
-  union {
-    struct FILEPROTO *file;
-  } p;
 #ifndef CURL_DISABLE_COOKIES
   unsigned char setcookies;
 #endif