Is it possible to write a program in C that upon execution deletes itself (the binary) and then terminates successfully. If so, what's the easiest way of doing this?
Yes.
#include <unistd.h>
int main(int argc, char* argv[])
{
return unlink(argv[0]);
}
(Tested and works.)
Note that if argv[0] does not point to the binary (rewritten by caller) this will not work.
Similarly if run through a symlink then the symlink, not the binary, will be deleted.
Also if the file has multiple hard links, only the called link will be removed.
I do not know that one can conveniently do it in a truly platform-independent way, but you didn't specify platform independence, so try the following, Linux-style code:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
printf("Read carefully! You cannot print this message again.\n");
return unlink(argv[0]);
}
How close is that to what you want?
If you operating system allows a running program to delete its own binary, then just look for the API for file deletion, or execute a corresponding system() command.
If the OS doesn't allow this, your program (let's call it A) could construct another binary, containing another program (let's call it B). Then, A would immediately quit.
Program B would have a single loop checking if A is still running and as soon as A quits, B would erase A's binary.
You could try to just delete the executable in the program (FILE* and stuff)... but seeing as that executable is what's being run it might not work. I see it like eating yourself, and as far as I know it's not possible, but you could certainly give it a try using the method I mentioned above.
I think it is dependent on the platform you are using. Basically, once the executable is loaded, any subsequent change to the binary does not affect the running program. In Unix, this is the case, and you can use the unlink system call.
I am not sure whether this is true on Windows or not. It may not be allowed to delete the executable image. You can try the DeleteFile() api in Windows.
Related
I've got the following issue:
int main(int argc, char **argv){
while(1){
char command[25];
scanf(" %25[^\n]s", command);
printf("Command '%s'\n", command);
}
return 0;
}
Now whenever I type something in the console it prints me a message with what I just typed.
But if I use the arrow up key to get the last command out of the memory, the command being sent is
^[[A
Which results in the cursor being moved up by the program.
Now how do I fix this?
I want that the last command from memory is triggered.
Thanks in advance!
This is actually pretty non-trivial thing you are asking for. Luckily, there is a library to fix it: GNU Readline library. Be aware about its licensing, though. Last I heard, it's actual GPL and therefore your own program needs to be that, too, if you use it. NetBSD has a library called libedit, which seems to claim to do much of the same thing with less restrictive license.
Here are some more help with readline: https://eli.thegreenplace.net/2016/basics-of-using-the-readline-library/
And if you can stomach the idea of not integrating it directly into your own program, there is a handy utility program called rlwrap, which provides the end-user at least some of the goodness transparently.
I have recently(yesterday) started trying to learn linux and to program in this os. Now, one interesting and probably easy problem I came across while surfing the net was something like this:
Consider a C program that takes a directory as an argument in the command line and calculates the sum of all the files' dimensions that are in the directory's tree.
Now, due to the fact that I've been doing a lot of reading and researching in a short matter of time, all my knowledge is piled up in my brian creating a cloud of confusion. If anyone could help me with the code, I'd be really thankful.
what you are asking is a basic task. It can be done in linux but can also be done in microsoft windows with minor code tweaks if you are writing a program in C or C++. you would be writing code, which is sort of at a lower level compared to other ways of doing it, to accomplish what you want.
However you don't need to write a program C, which then requires you to compile it into an executable. Because what you are asking is a basic task, you might be able to do it with a bash shell script which would be linux specific. And if you wanted to do this in Windows then you would write a .bat file which is either the DOS scripting language, or Windows Powershell. I am not that familiar with Windows, i only mention it to help give you a general understanding for "all the knowledge piled up in your brain creating a cloud of confusion".
There is the windirstat program which runs under Microsoft Windows, can get it free from sourceforge and I think it does mostly what you are asking. I am not sure if you can get source code for it.
For linux there is kdirstat and that you can get the source code for from
http://kdirstat.cvs.sourceforge.net/viewvc/kdirstat/
you can download it as GNU tarball.
Look at how that program is written, which is C++ as you'll see a bunch of .cpp files. That would be a good template to work off of, and you can see what libraries they are using to accomplish file system functions. There are 21 .cpp files, look at the file kdirstatmain.cpp first.
For C/C++ code the start of execution is with the function int main(int argc, char *argv[]).
Regarding accomplishing this task with a bash shell script in linux, the best i can tell you is web search on bash shell scripting for linux.
And in linux to calculate the sum of all the files' dimensions that are in the directory's tree we can quickly do that at the linux prompt with the du -sh . command. In linux at the prompt do man du so read about the disk usage command. And then consider looking for the source code for du to use it as a template, and work off how they implemented du to learn and then modify their ways to meet your needs.
linux du command source code
Use opendir(3) to "open" the directory. Since you are interested in learning how to program in GNU/Linux, start by typing man opendir in the terminal to read how this function works. The (3) in opendir(3) means that the help for this function can be found in the section 3 of the manpages. Notice, at the top of the page, that the manpage tells you which #includes you'll need.
If everything goes right, opendir(3) will return a DIR* object. To know which files or subdirectories it contains, you use this object with readdir(3). This should return a pointer of type struct dirent*. You can heck the manual pages for details on the fields of this structure, but the most important for you will probably be d_type and d_name. A second call to this function will return the next entry. When it returns NULL, that either means you have read all files or an error occurred. To know which happened, you should check errno.
Here's a short example that list all entries in /tmp:
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
int main(void)
{
DIR *dir;
struct dirent *entry;
dir = opendir("/tmp");
/* should check if dir != NULL */
while ((entry = readdir(dir)) != NULL) {
printf("Found %s\n", entry->d_name);
}
/* You may want to check errno here to see if readdir returned
* NULL because all files were read or because of some error;
* but this is beyond the purposes of my example.
*/
closedir(dir);
return 0;
}
Now you have to process each entry. If it is a directory, you have to descend into it an read its contents. A recursive function will probably help you here. If it is a file, then you have at least two options:
Open it with fopen(3), then use fseek(3) to seek the end of file. Use the return value of fseek(3) to calculate the size of the file in bytes;
Use stat(2) to get a structure with information on the file. Do not confuse it with stat(1). If you simply type man stat, you'll get information about the latter. To force man to read from section 2, type man 2 stat in the command line.
The first approach is certainly simpler. The second will require you to do a bit of reading on how stat(2) works. My advice: you should do it. Not only because it's more in the lines of Linux, but also because it gives you information that fseek(3) doesn't give. For instance, you can use stat(2) to see not only how many bytes the file contains, but how many bytes it occupies in the disk (like du does).
While reading the directory, you may stumble on other types of entries other than files and directories. stat(2) will probably help you figure the sizes of them as well. But you may want to simply ignore them for now.
I am a rookie on C, and now I want to use C to complete a wildcard function. For example, I write a photo processing program named myphoto, and I want to use it like this: myphoto ./photos/*.png, and then myphoto will process all the png file in the dir one by one.
I would like to solve this problem as easily as possible, without the usage of regular expression, and I came up with a idea that maybe I could use the EXEC function to execute a command, but the EXEC function only returns int, not the char*.
So how can I solve this problem? thanks!
It is operating system specific. I'm giving a Posix and Linux point of view (on Windows it is different, and I don't know it).
Notice that if you are writing the program myprog.c compiled into myprog then running
myprog photos/*.png the main function in myprog.c is getting an array of strings (declare int main(int argc, char**argv) then the array of arguments has argc strings in array argv ....). The expansion is done by the shell before starting your myprog binary executable. See execve(2)
On Linux and Posix systems: read glob(7), you may want to use glob(3) and/or fnmatch(3) and/or wordexp(3). These functions are useful mostly if some data (e.g. a line in a file) contains photos/*.jpeg and your program want to "glob" that. You don't need to "glob" the arguments of main, this has been done already by your shell.
Read Advanced Linux Programming
I am writing a C shared library in Linux in which a function would like to discover the path to the currently running executable. It does NOT have access to argv[0] in main(), and I don't want to require the program accessing the library to pass that in.
How can a function like this, outside main() and in the wild, get to the path of the running executable? So far I've thought of 2 rather unportable, unreliable ways: 1) try to read /proc/getpid()/exe and 2) try to climb the stack to __libc_start_main() and read the stack params. I worry about all machines having /proc mounted.
Can you think of another way? Is there something buried anywhere in dlopen(NULL, 0) ? Can I get a reliable proc image of self from the kernel??
Thanks for any thoughts.
/proc is your best chance, as "path of the executable" is not that well defined concept in Linux (you can even delete it while the program is running).
To get the breakdown of loaded modules (with the main executable usually being the first entry) you should look at /proc/<pid>/maps. It's a text formatted file which will allow you to associate executable and library paths with load addresses (if the former are known and still valid).
Unless you are writing software that may be used very early in system startup, you can safely assume that /proc will always be mounted on a Linux system. It contains quite a bit of data that is not accessible any other way, and thus must be mounted for a system to function properly. As such, you can pretty easily obtain a path to your executable using:
readlink("/proc/self/exe", buf, sizeof(buf));
If for some reason you want to avoid this, it's also possible to read it from the process's auxiliary vector:
#include <sys/auxv.h>
#include <elf.h>
const char *execpath = (const char *) getauxval(AT_EXECFN);
Note that this will require a recent version of glibc (2.16 or later). It'll also return the path that was used to execute your application (e.g, possibly something like ./binary), rather than its absolute path.
I need to run a program that crawls websites and I already have an algorithm and some parts of the code. Problem is, I do not know how to insert wget into my source code. Our student assistant hinted that some kind of keyword or function shall be used before the wget( system, I think or something but I'm not so sure).
when to not use system:
1.) when you want to distribute the program to different environment, where the program you call via system is not available
2.) in a security relevant environment, where you have to make sure that the program you call is really the program you want it to be
3.) when the thing you want to do can easily be accomplished in 10-20 lines of C code
4.) in performance-critical applications
so, you should use system virtually never.
instead, to accomplish the same thing, you could use libcurl, as David suggested (his answer seems to be gone...), or do some socket programming (it's C, after all).
In a real-world scenario, I'd probably just default to writing the crawler in a different language. web requests and complex string processing are not necessarily the strong sides of C, and most definitely not very convenient to use :)
You can use the system() command.
In your case (possibly):
system("/bin/wget");
But if you want really call wget with parameters, so you should use execl().
execl("/bin/wget", "http://anyadress.com/file");
Whenever , you want to run shell commands from your C program , you use system("shell command").In your case
system("wget");
Note - wget is an executable , whose location is added to the path variable, so there is no need to specify the path explicitly.
-- Example --
#include <stdio.h>
#define BUFFLEN 2500
int main()
{
char web_address[BUFFLEN] = "www.google.com";
system("wget 'web_address' ");
return 0;
}
The system command is used to execute a shell command. man system