how can I parameterize select function in scandir - c++

The scandir() function scans the directory dir, calling
select() on each directory entry as "int(*filter)(const struct dirent *)"
How can I pass pattern value as parameter to fnmatch(const char *pattern, const char *string, int flags) function used in filter ?
Here my sample code
int my_selectgrf(const struct dirent *namelist)
{
int r = 0;
char my_pattern[] = "*.grf";
r = fnmatch(my_pattern, namelist->d_name, FNM_PERIOD);
return (r==0)?1:0;
}
scandir("/pub/data/grf", &namelist, my_selectgrf, alphasort);
my goal is to be able to use my_pattern as input parameter.

The short answer: You can't. This is an atrociously bad API, and it's outright shameful that something like this was added to POSIX as recently as 2008 (based on a bad design in glibc). This kind of API without a way to parameterize it or pass it a context should have been abolished 20+ years ago.
With that said, there are some workarounds:
Approach 1: Use a global variable, and if your code needs to be thread-safe, ensure that only one thread can be using scandir with the given scan function at a time, by locking. This of course serializes usage, which is probably not acceptable if you actually want to be calling the function from multiple threads.
Approach 2: Use thread-local storage, either the GCC __thread keyword (or the C11 _Thread_local keyword, which GCC sadly still does not accept) or POSIX pthread_setspecific and family. This is fairly clean, but unfortunately it may not be correct; if the implementation of scandir internally used multiple threads, the parameter could fail to be available in some calls back to the scan function. At present, I don't believe there are multi-threaded implementations of scandir.
Now, the better solution:
Ditch scandir and write your own function to do the same thing, with the proper API. It's only a few lines anyway.

Related

Can a function access args passed to main()?

Is there a way I could access program's args outside of main() without storing references to them?
Program arguments are stored within preserved space of the program, so I see no reason for not being able to access them. Maybe there is something like const char** get_program_arguments() and int get_program_arguments_count() but I cannot find it...
My problem comes from the fact that I am rewriting a library that is used now in many programs within the company, and I need to access these programs common arguments without changing them. For example I need program name, but I cannot use ::getenv("_") as they can be executed from various shells. I cannot use GNU extension because this needs to work on Linux, AIX, SunOS using gcc, CC and so on.
Some systems do provide access to the argument list, or at least argv[0]. But it’s common practice for main to mutate argc and argv during option processing, so there is no reliably correct answer as to what a global interface for them should return.
Add to that the general undesirability of global state, and the fact that it harms debugging to have whatever low-level functions attempt to analyze the arguments to a program they might know nothing about, and you end up with don’t do that. It’s not hard to pass arguments (or, better, meaningful flags that result from decoding them) to a library.

Running Function Inside Stub. Passing Function Pointer

I'm working on creating a user-level thread library and what I want to do is run a function inside a stub and so I would like to pass the function pointer to the stub function.
Here is my stub function:
void _ut_function_stub(void (*f)(void), int id)
{
(*f)();
DeleteThread(id);
}
This is what the user calls. What I want to do is get pointer of _ut_function_stub to assign to pc and I've tried various different options including casting but the compiler keeps saying "invalid use of void expression".
int CreateThread (void (*f) (void), int weight)
{
... more code
pc = (address_t)(_ut_function_stub(f, tcb->id));
... more code
}
Any help is appreciated. Thanks!
If you're interested in implementing your own user-level-threads library, I'd suggest looking into the (now deprecated) ucontext implementation. Specifically, looking at the definitions for the structs used in ucontext.h will help you see all the stuff you actually need to capture to get a valid snapshot of the thread state.
What you're really trying to capture with the erroneous (address_t) cast in your example is the current continuation. Unfortunately, C doesn't support first-class continuations, so you're going to be stuck doing something much more low-level, like swapping stacks and dumping registers (hence why I pointed you to ucontext as a reference—it's going to be kind of complicated if you really want to get this right).

How to transmit a function to anonymous pipe WinAPI?

I need to write to anonymous pipe something like double (*fun)(double), but the following WriteFile(pipe, fun, 4, written_bytes, 0) causes an error in a pipe-receiver while ReadFile(read_pipe, fun, 4, written_bytes, 0). Are there any methods to do this?
I have an idea. I can create a struct with field of same type:
struct Foo
{
double (*f)(double);
};
And then I write it WriteFile(hWritePipe_StdIN, &to_process, sizeof(Foo), &bytes, 0);
But I have problem, that pipe-receiver never ends to read data:
ReadFile(hReadPipe, &to_process, sizeof(Foo), &bytes, 0);
There are some problems with it:
First, you should know the size of function.
If you do, you just call WriteFile(pipe, funcPtr, funcSize, ...) to transfer it.
Second, the function should contain only position-independent code, and don't address any data.
E.g. a function like this won't work:
double fun(double x)
{
int arr[10000]; // implicit function call (alloca or something like this)
printf("some");
static int some = 1;
return globalVal + (++some);
}
because function printf will have a different address and there will be no static variable and string in another process.
(Well, maybe you can transfer data as well, but there is no way you'll generate PI code.)
So, with all that limitations, you can send a function:
__declspec(naked) double fun(double x) { __asm ret }
const auto funcSize = 1;
WriteFile(pipe, &fun, funcSize, ...);
In native code you can not send function (the code) itself, neither to the same nor to different process. (You could try low-level hacking like the one #Abyx suggests, but it seriously limits functionality that the code can perform, and will probably make you resort to writing it all in assembler by hand.)
You also can't send function's address to another process, because each process has its own isolated address space; in another process, that address will contain different data.
The solution will be to create a shared library (preferably dynamic) that will contain all functions that could possibly be sent this way. Assign each function some tag (e.g. number or name), let DLL maintain a mapping between tags and addresses. Then send tags instead.
What are you trying to achieve, here? Are you really trying to write the function itself? Why? That's not something you can easily do in C++, for instance because the size of a function is not well-defined.
You should probably write the data, i.e. the number returned by fun() instead:
const double value = fun(input);
DWORD numberOfBytesWritten;
WriteFile(pipe, &value, sizeof value, &numberOfBytesWritten, NULL);
You should of course add code to check the output. Note that writing binary data like this can be brittle.
Since you're using WinAPI, the native way to send a function is via COM. In particular, expose the function as a method on a COM object, obtain a COM moniker, and send the moniker. Monikers can be serialized and sent over pipes. The other side can deserialize the moniker and get access to your object.
Under water, this works by looking up the object in the COM Running Object Table
Seeing how this is excessively complicated and error-prone to do in C++ (and only works with a very limited set of functions at all), I recommend you use a scripting language for this. Instruction caches and DEP are another two things you'd have to consider in addition to the already mentioned ones.
Really. Transmit the function as script, and run it on the other end. Save yourself that pain.
Angelscript looks and feels almost like C++, so that might be a possible candidate.
Now, if you object to this because you need something that a script cannot trivially do, knoweth: C++ will not be able to do it either, in this scenario.
Apart from the above mentioned PIC code issue (#Abyx) and the fact that you cannot safely or portably know a function's size, the only C++ functions that you could conceivably send via a pipe and execute in a meaningful manner are strictly const functions. Here, const is in the sense of e.g. GCC's __attribute__((const)), not the C++ const keyword.
That is, any such function may not examine any values except its arguments, and have no effects except the return value. The reason is obvious: A different process lives in a different address space, so anything you reference is meaningless. Anything you change is meaningless.
Now, this is just what a script can do, in a safe, straightforward manner, and reliably. The overhead is, considering you already send code through a pipe, neglegible.

Shadowing functions of C stdlib/stdio

I am writing a game and for now i was able to implement a filesystem via sqlite with a class and its methods. To make life more easy i have planned to write some functions like fopen,fclose,fread,rename, etc. to be able to shadow the base functions and to direct my calls to my filesystem rather than to the original one. For the first three function everything worked fine for me with these prototypes:
File *fopen(String _Filename, String _Mode); // i have my own optimized File struct
void fclose(File *_File);
size_t fread(String *_DstBuf, size_t _ElementSize, size_t _Count, File *_File);
This worked fine as i am either returning another struct or the parameters except a File* and not a FILE*, however the rename function seems to be a bit trickier!
int rename(String _OldFilename, String _NewFilename);
This is nearly the same prototype. except that i use std::string (typedef'ed String) than const char*! Any idea how i could convince my compiler either to use my function or to ignore the stdio-one?
And what is the reason that you cannot simply use your own functions by any other name?
If the whole conflict is with overload resolution, you should simply just shadow the actual prototypes; You can make them forwards to your own functions.
However, I recommend against the general approach here: even with that 'fix' in place you will at the very best have include ordering issues, and possibly even duplicate link symbols.
If your functions don't do the same, make them use another name. Since you are using c++, you could do this vile trick (otherwise ill-advised) in MyFsFunctions.h:
namespace MyFsFunctions
{
// prototypes for fopen, fclose, fwrite, fread etc
}
using namespace MyFsFunctions;
// or:
using MyFsFunctions::fopen;
using MyFsFunctions::fclose;
using MyFsFunctions::fread;
using MyFsFunctions::fwrite; // etc...
I'm pretty sure you will still want (need) to shadow the exact function prototypes (or the compiler may still complain about ambiguous identifiers references).
Other hints:
use a fuse file system driver (on Linux/UNIX/MacOS; might be overkill, but implementing it seems a lot more robust and may even simpler than what you do here).
there is always C macros (-10 points for evil)
gnu linker has options that let's you 'replace' link symbols - mainly for debugging purposes, but you can leverage those here
How about implementing a rename with the standard signature that all it will do would be calling your Stringed version?
Doesn't sound complicated to me. Something like this:
int rename(const char *charOld, const char *charNew)
{
std::string stdOld(charOld);
std::string stdNew(charNew);
return rename(stdOld, stdNew);
}

Can glibc sprintf be used in a reentrant function?

Can I use sprintf in a reentrant function if it writes in a local buffer? Something like this:
void reentrant_function () {
int i = 4;
char buffer[20];
snprintf(buffer, 20, "%d", i);
}
I get to this page because I am also asking the same question. Here is what I read from books:
Advanced Programming in the UNIX Environment: Second Edition
Section 10.6
Most functions that are not in Figure 10.4 (a list of reentrant functions) are missing because (a) they are known to use static data structures, (b) they call malloc or free, or (c) they are part of the standard I/O library.
The Linux Programming Interface
Chapter 21.1.2
Functions can also be nonreentrant if they use static data structures for their
internal bookkeeping. The most obvious examples of such functions are the members
of the stdio library (printf(), scanf(), and so on), which update internal data
structures for buffered I/O.
I guess it is implementation depending. It also depends on how do you use snprintf actually (the buffer is essential). The safest answer to the question should be 'no'.
Sure you can, unless your buffer is static.
Yes.
Why do you think you could not? There's no global.
One thing thought: the buffer is local to the function, why would you want to format a string and do nothing with it?