From: Stefan Eissing Date: Thu, 8 May 2025 09:01:24 +0000 (+0200) Subject: file: use easy handle meta for protocol struct X-Git-Tag: curl-8_14_0~129 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27bc798369cbdccf4c4ee805fad04938925b0a60;p=thirdparty%2Fcurl.git file: use easy handle meta for protocol struct Closes #17292 --- diff --git a/lib/file.c b/lib/file.c index cec73aabda..b88f612305 100644 --- a/lib/file.c +++ b/lib/file.c @@ -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; diff --git a/lib/file.h b/lib/file.h index 4565525592..fea1eea57d 100644 --- a/lib/file.h +++ b/lib/file.h @@ -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 diff --git a/lib/request.c b/lib/request.c index 43923d1438..f937a7f4bf 100644 --- a/lib/request.c +++ b/lib/request.c @@ -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); diff --git a/lib/request.h b/lib/request.h index 1ac873099a..74d9f53439 100644 --- a/lib/request.h +++ b/lib/request.h @@ -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