How to find execute files in Linux? - c

I wants to get the names of execute files in some directory in Linux.
How can I do it?
I tried to use opendir like this:
dir = opendir(directoryName);
I need to get only the names of the execute files.
I programming in C.
thanks :)

You should define what you mean by executable files.
That could be any file with its execute bit (it is the owner, group, or other) set. Then test with access(2) & X_OK and/or use stat(2).
That could also be only ELF executables. See elf(5); then the issue might be to check that a file could indeed be executed, which might be difficult (what about missing library dependencies? or ill-formed ELF files?). Maybe use libelf (and/or libmagic to do the equivalent of file(1) command).
To scan recursively a file tree, use nftw(3); to scan just a directory use opendir(3) & readdir(3) (don't forget the closedir!), then you'll probably need to build the complete file path from each directory entry (perhaps using snprintf(3) or asprintf(3))
See also Advanced Linux Programming

Related

File Config, creation and usage in C unix

I'm trying to understand how I can create a ".config" file containing a bunch of parameters to later use to set up the variables in my C project on Unix.
I created my ".config" file using sudo nano test.config and wrote some stuff inside such as:
#N is this
N 10
#p is that
p 0.002
#T is this
T 10
Now that I did that how can I read its content and use it to initialize my variables?
The several answers to this question explain how to parse that config file, but you could use standard parsing techniques (perhaps your own recursive descent parser) or Glib's lexical scanning or key-value pair parser (or use something else). You certainly should define and document (perhaps using EBNF) what is the format of that textual configuration file (and what the various entries there represent: for example, if that configuration file refers to other files, how do you handle spaces in such file paths, etc....). A common (but not universal) convention is to consider as comments so skip any line starting with #.
Another question is how to get that config file while running in an arbitrary working directory. You just need to build the absolute path of your file (for fopen(3) or open(2)), e.g. with
char configpath[100];
snprintf(configpath, sizeof(configpath), "%s/.test.config", getenv("HOME"));
You could test before that getenv("HOME") is not NULL, but in practice that is very unlikely; see environ(7) and getenv(3); and the case when it gives a very long file path is also unlikely; you might test that snprintf(3) returns a count less than sizeof(configpath) or use asprintf(3).
You might use other functions, e.g. glob(3) or wordexp(3) to get that file path (but you probably should stick to snprintf or asprintf with getenv("HOME")...).
You might consider instead embedding some scriptable interpreter like lua or guile in your program (but that is a strong architectural design decision). Then the configuration file becomes some (Turing-complete!) script.
BTW, there is no need to use sudo to edit that configuration file (under your home directory), and you might decide to also read some system-wide configuration under /etc/

Pass Directory Context to Compiler

I'm writing a Java compiler in C just as a recreational project. But, I've noticed that when we compile files in the command line, such as "gcc example.c", the compiler is able to find example.c in the working directory of the terminal without error. How does the compiler know what directory to search example.c for? Does OS find example.c in the directory for the compiler? Also, how may I emulate this action in my C program so that the user can compile their java program from any working directory by calling my compiler such as: "compiler example.java"?
fopen will treat relatives paths as relative to the current directory, not the directory where the executable resides. This is the same with most (or even all) file handling function in most other languages.
So to emulate the behaviour of the Java compiler, all you need to do is to iterate over the file names in argv, fopen(the_file_name), generate code for that file, then fopen(class_file_name, "wb") (where class_file_name is file_name with .java replaced by .class) and write the generated bytecode to that.
Getting the full path of the current directory is neither necessary nor helpful. Note that if you just appended each argument to the current directory name, the code would break for absolute paths, whereas simply doing nothing will do the correct thing both for relative and for absolute paths.
If I understand correctly, you need to obtain the full path of the current working directory. There is a POSIX function getcwd (on Windows _getcwd) that can be used to retrieve current working directory of your program.
Then it should be simple to search this directory and find your sources (if they are present).

emacs open includes in code files, multiple directories

ECB, cscope, xcscope. All working. Is cedet necessary?
MSVS, eclipse, code::blocks, xcode. All of them allow easy click on an included source file and take you to it.
Now, with the above setup, emacs does too.
Except emacs doesn't take you to the std:: libraries, doesn't assume their location in /src/linux or some such. Emacs is a little blind and needs you to manually set it up.
But I can't find anything that explains how to set up ff-find-other-file to search for any other directories, let alone standard major libraries, outside of a project's directory.
So, how do I do it?
Edit; Most important is to be able to request on either a file name (.h, .c, .cpp, .anything) or a library (iostream) and open the file in which the code resides.
Additional directories for ff-find-other-file to look into are in ff-search-directories variable which by default uses the value of cc-search-directories, so you should be able to customize any of the two to specify additional search paths.
As for the second question about requesting a file name and finding corresponding file, something like that will do:
(defun ff-query-find-file (file-name)
(interactive "sFilename: ")
;; dirs expansion is borrowed from `ff-find-the-other-file` function
(setq dirs
(if (symbolp ff-search-directories)
(ff-list-replace-env-vars (symbol-value ff-search-directories))
(ff-list-replace-env-vars ff-search-directories)))
(ff-get-file dirs file-name))
Call it with M-x ff-query-find-file or bind it to a key to your liking.

how to find source file name from executable?

IN LINUX:
Not sure if it is possible. I have 100 source file, and 100 respective executable files.
Now, given the executable file, is it possible to determine, respective source file.
I guess you can give this a try.
readelf -s a.out | grep FILE
I think you can add some grep and sed magic to the above command and get the source file name.
No, since your assumption, that a single binary comes from exactly one source file, is very false.
Most real applications consist of hundreds, if not thousands, of individual source files that are all compiled separately, with the results liked together to form the binary.
If you have non-stripped binaries, or (even better) binaries compiled with debugging information present, then there might (or will, for the case of debugging info) be information left in the file to allow you to figure out the names of the source files, but in general you won't have such binaries unless you build them yourself.
If source filenames are present in an executable, you can find them with:
strings executable | grep '\.c'
But filenames may or may not be present in the executable and they may or may not represent the source filenames.
Change .c to whatever extension you assume the program has been written in.
Your question only makes sense if we presume that it is a given fact that every single one of these 100 executables comes from a single source file, and that you have all those source files and are capable of compiling them all.
What you can do is to declare within each source file a string that looks like "HERE!HERE!>>>" + __FILE__ and then write a utility which searches for "HERE!HERE!>>>" inside the executable and parses the string which follows it. __FILE__ is a preprocessor directive which expands to the full pathname of the source file being compiled.
This kind of help falls in the 'close the barn door after the horse has run away' kind of thing, but it might help future posters.
This is an old problem. UNIX and Linux support the what command which was invented by Mark Rochkind (if I remember correctly), for his version of SCCS. Handles exactly this type of problem. It is only 100% reliable for one source file -> one exectuable (or object file ) kind of thing. There are other more important uses.
char unique_id[] = "#(#)identification information";
The #(#) is called a "what string" and does not occur as a by-product of compiling source into an executable image. Use what from the command line. Inside code use maybe something like this (assumes you get only one file name as an answer, therefore choose your what strings carefully):
char *foo(char *whoami, size_t len_whoami)
{
char tmp[80]={0x0};
FILE *cmd;
sprintf(tmp, "/usr/bin/grep -F -l '%s' /path/to/*.c", unique_id);
cmd=popen(tmp, "r");
fgets(whoami, len_whoami, cmd);
pclose(cmd);
return whoami;
}
will return the source code file name with the same what string from which your executable was built. In other words, exactly what you asked, except I'm sure you never heard of what strings, so they do not exist in your current code base.

How to remove multiple files in C using wildcards?

Is there any way in C to remove (using remove()) multiple files using a * (wildcards)?
I have a set of files that all start with Index. For example: Index1.txt, Index-39.txt etc.
They all start with Index but I don't know what text follows. There are also other files in the same directory so deleting all files won't work.
I know you can read the directory, iterate each file name, read the the first 5 chars, compare and if it fits then delete, but, is there an easier way (this is what I currently do by the way)?
This is standard C, since the code runs on Linux and Windows.
As you point out you could use diropen, dirread, dirclose to access the directory contents, a function of your own (or transform the wildcards into a regex and use a regex library) to match, and unlink to delete.
There isn't a standard way to do this easier. There are likely to be libraries, but they won't be more efficient than what you're doing. Typically a file finding function takes a callback where you provide the matching and action part of the code. All you'd be saving is the loop.
If you don't mind being platform-specific, you could use the system() call:
system("del index*.txt"); // DOS
system("rm index*.txt"); // unix
Here is some documentation on the system() call, which is part of the standard C library (cstdlib).
Is this all the program does? If so, let the command line do the wildcard expansion for you:
int main(int argc, char* argv[])
{
while (argc--)
remove(argv[argc]);
}
on Windows, you need to link against 'setargv.obj', included in the VC standard lib directory.

Resources