file: use easy handle meta for protocol struct

Closes #17292
This commit is contained in:
Stefan Eissing 2025-05-08 11:01:24 +02:00 committed by Daniel Stenberg
parent 1c6fc0cd2b
commit 27bc798369
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 46 additions and 39 deletions

View file

@ -83,6 +83,16 @@
#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;

View file

@ -24,17 +24,6 @@
*
***************************************************************************/
/****************************************************************************
* 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

View 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);

View 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