Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file:// : Allow getting basic directory listings #13137

Closed
wants to merge 1 commit into from

Conversation

colinleroy
Copy link
Contributor

Hi Daniel & curl team,

Here's a little PR that allows one to get basic directory listings over file://, like for example:

$ ./src/curl file:///home/colin/Documents/git-oss/curl/
winbuild
configure~
autom4te.cache
MacOSX-Framework
LICENSES
CMake
libtool
config.status
libcurl.pc.in
missing
...

I hope you folks will consider it useful. For me, it's a way to start diving into curl code to implement the same for smb:// (which, of course, seems to be much more complicated).

@gvanem
Copy link
Contributor

gvanem commented Mar 16, 2024

Useful IMHO, but not all targets have readdir() etc.
So consider adding MSVC-support for this <dirent.h> stuff from e.g.
https://github.com/ThomasDickey/lynx-snapshots/blob/master/lib/dirent.h

into this PR first.

@colinleroy
Copy link
Contributor Author

colinleroy commented Mar 16, 2024

Useful IMHO, but not all targets have readdir() etc. So consider adding MSVC-support for this <dirent.h> stuff from e.g. https://github.com/ThomasDickey/lynx-snapshots/blob/master/lib/dirent.h

into this PR first.

Thank you for your comment, I'll do that. The linters are being mean to me, I'll handle that too.
Edit: Would you have some pointers about how to do that (like maybe another example of thing added for MSVC)?

I don't have a Windows development machine, VM or setup so I feel there may be a few issues I'll have to sort through.

@dfandrich
Copy link
Contributor

dfandrich commented Mar 16, 2024

Be sure to take a look at PR #9746 and its comments.

@bagder
Copy link
Member

bagder commented Mar 16, 2024

The linters are being mean to me

make checksrc locally is a good idea...

lib/file.c Outdated
*data = NULL;
*size = 0;

if(!file) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can file actually and legitimately be NULL here? Shouldn't this rather be an assert since it should never happen in real life?

lib/file.c Outdated

dir = fdopendir(file->fd);
if(!dir) {
result = CURLE_BAD_FUNCTION_ARGUMENT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is curious, since it already opened the file and it is said to be a dir, but this still fails. It seems to me that CURLE_BAD_FUNCTION_ARGUMENT is not the most accurate description of this error. Maybe just CURLE_READ_ERROR ?

lib/file.c Outdated

*data = tmp;
snprintf(*data + *size, entry_len + 1, "%s\n", entry->d_name);
*size += entry_len;
Copy link
Member

@bagder bagder Mar 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not make sense to just pass on the file entry to the write callback as soon as you have it, rather than to create a (potentially huge) allocated buffer and send them all later?

And if you do prefer the buffer approach, please use a dynbuf to avoid manual reallocs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with a temporary buffer because it seemed much easier to calculate expected_size and do resuming. Do you think that's a good enough reason to go the buffer route?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does provide an expected size, that is true. But resuming sounds super fragile and will break horribly if something in the directory changes in between...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this is true. Is it acceptable to reject resumes in case of a directory listing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's the only sensible thing to do

@colinleroy
Copy link
Contributor Author

I repushed to address your comments. Is this something like that you had in mind?

lib/file.c Outdated
goto out;
}
else {
DIR *dir = fdopendir(file->fd);
Copy link
Member

@bagder bagder Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add a check for fdopendir() to configure and CMake so that we know it exists for the platform you build this for. On Windows it won't exist. For now at least, I think we can presume the other POSIX dir funtions exist if this one does.

Then you can either opt to fail on other platforms, or continue to add support other dir-reading functions. Windows being a primary target I guess.

macOS also needs attention as the compiler there says:

'fdopendir' has been marked as being introduced in macOS 10.10 here, but the deployment target is macOS 10.9.0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @bagder,
Thanks for your feedback. I will add the configure/CMake checks this evening, and probably switch to opendir(file->path) to address the Mac OS X case.
For Windows, I'll see if I can find someone with Windows experience to help me either add wrappers or #ifdefs.

@bagder
Copy link
Member

bagder commented Mar 19, 2024

I googled the Windows API for this and it seems fairly simple. Something in this style lists the contents of a given directory:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

void listdir(const char *dir)
{
    WIN32_FIND_DATA entry;
    HANDLE h;
    char *wc = aprintf("%s\\*.*", dir);
    if(!wc)
      return; /* out of mem */

    h = FindFirstFile(wc, &entry);
    if(h == INVALID_HANDLE_VALUE)
      return;

    do {
      printf("%s\n", entry.cFileName);
    } while(FindNextFile(h, &entry));

    FindClose(h);
    free(wc);
}

Rough example, but the function calls should show.

@colinleroy
Copy link
Contributor Author

I'm unsure the two failing pipelines are failed related to the PR?

@colinleroy
Copy link
Contributor Author

Concerning Windows, is it OK if I do it in a different PR?

@bagder
Copy link
Member

bagder commented Mar 21, 2024

Concerning Windows, is it OK if I do it in a different PR?

Absolutely. As long as this PR does not break their builds or misbehaves for them in other ways.

Copy link
Member

@bagder bagder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: I deem this to be a "feature/change", which means that we will not merge this PR until the feature window opens again. (Normally 10 days after a release.)

lib/file.c Outdated
}
}
else {
#ifdef HAVE_OPENDIR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the #ifdef (and #else, and #endif) to column zero.

lib/file.c Show resolved Hide resolved
lib/urldata.h Show resolved Hide resolved
@bagder bagder added the feature-window A merge of this requires an open feature window label Mar 21, 2024
@colinleroy
Copy link
Contributor Author

FYI: I deem this to be a "feature/change", which means that we will not merge this PR until the feature window opens again. (Normally 10 days after a release.)

That seems logical :)
Your latest comments should be addressed in the last push.

@colinleroy
Copy link
Contributor Author

Hi @bagder! I think the feature freeze is over?
do I have to do something about the failed Mac pipelines? It seems like they're unrelated to the PR?
Thanks 🙂

@bagder
Copy link
Member

bagder commented Apr 9, 2024

The freeze is over. Those CI fails should be fixed if you rebase and force-push.

I do miss a test case specifically for this feature.

@colinleroy
Copy link
Contributor Author

Hi Daniel,
PR rebased, test added (i hope it's what you expected?) and CI passed!

Copy link
Member

@bagder bagder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@bagder bagder closed this in bfe54b0 Apr 11, 2024
@bagder
Copy link
Member

bagder commented Apr 11, 2024

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cmdline tool feature-window A merge of this requires an open feature window tests
Development

Successfully merging this pull request may close these issues.

None yet

4 participants