C - get path of .c file - c

I have the following .c file:
/home/eamorr/project1/eamorr.c
I compiles fine and its exe is located at:
/home/eamorr/project1/a.out
Now, I have a php file at:
/home/eamorr/project1/a/b/c/eamorr.php
It needs to call a.out
<?php
$cmd=__DIR__."../../../a.out";
$result=`$cmd`;
?>
Here's the eamorr.c program:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main (int argc, char *argv[]){
setuid (0);
char temp[2048];
char pwd[1024];
realpath(argv[0],pwd);
sprintf(temp,"/bin/bash %s/doMagic.sh",pwd);
system((char *)temp);
return 0;
}
Unfortunately the pwd variable contains the wrong path!!!
/home/eamorr/project1/a.out/doMagic.sh
How do I get rid of the a.out bit from the path? I don't program in C very often and I've been at this for over an hour now...

If I understand correctly, what you would like to get is something like:
/home/eamorr/project1/doMagic.sh
First of all, I dont generally do this kind of path handling in C. However, I had a quick look and it seems that you could use the dirname() functionality. Have a look here http://man7.org/linux/man-pages/man3/basename.3.html. Please be careful with this because I would imagine that these are Linux stuff, not sure how you would do it in DOS.

Related

Why is direct I/O file not being written to?

I am trying to understand direct I/O. To that end I have written this little toy code, which is merely supposed to open a file and write a text string to it:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv) {
char thefile[64];
int fd;
char message[64]="jsfreowivanlsaskajght";
sprintf(thefile, "diotestfile.dat");
if ((fd = open(thefile,O_DIRECT | O_RDWR | O_CREAT, S_IRWXU)) == -1) {
printf("error opening file\n");
exit(1);
}
write(fd, message, 64);
close(fd);
}
My compile command for Cray and GNU is
cc -D'_GNU_SOURCE' diotest.c
and for Intel it is
cc -D'_GNU_SOURCE' -xAVX diotest.c
Under all three compilers, the file diotestfile.dat is created with correct permissions, but no data is ever written to it. When the executable finishes, the output file is blank. The O_DIRECT is the culprit (or, more precisely I guess, my mishandling of O_DIRECT). If I take it out, the code works just fine. I have seen this same problem in a much more complex code that I am trying to work with. What is it that I need to do differently?
Going on Ian Abbot's comment, I discovered that the problem can be solved by adding an alignment attribute to the "message" array:
#define BLOCK_SIZE 4096
int bytes_to_write, block_size=BLOCK_SIZE;
bytes_to_write = ((MSG_SIZE + block_size - 1)/block_size)*block_size;
char message[bytes_to_write] __attribute__ ((aligned(BLOCK_SIZE)));
(System I/O block size is 4096.)
So that solved it. Still can't claim to understand everything that is happening. Feel free to enlighten me if you want. Thanks to everyone for the comments.
Well, you need to rethink the question, because your program runs perfectly on my system, and I cannot guess from it's listing where the error can be.
Have you tested it before posting?
if the program doesn't write to the file, probably a good idea is to see about the return code of write(2). Have you done this? I cannot check because on my system (intel 64bit/FreeBSD) the program runs as you expected.
Your program runs, giving no output and a file named diotestfile.dat appeared in the . directory with contents jsfreowivanlsaskajght.
lcu#europa:~$ ll diotestfile.dat
-rwx------ 1 lcu lcu 64 1 feb. 18:14 diotestfile.dat*
lcu#europa:~$ cat diotestfile.dat
jsfreowivanlsaskajghtlcu#europa:~$ _

Why does my code keep failing in codeblocks?

Here's the code I wrote.
#include <stdlib.h>
#include <stdio.h>
int main(void){
printf("hello World.");
return 0;
}
This is the error message
Execution of '"C:\Users\Happy Birthday\Desktop\Coding\C++\C_C++ project\simple program.exe"' in 'C:\Users\Happy Birthday\Desktop\Coding\C++\C_C++ project' failed.|
I figured it out. I had to go to the location of the bin for MinGW, copy and paste its address into the Toolchain executables tab of the global compiler settings, as opposed to auto detecting it.

How can a C program determine and print the location of its own executable?

I want to write a a C program that prints its location.
For example if i put the program exe file to D:\myfolder\myc_prog, it should print the same location D:\myfolder\myc_prog and if I put that exe file to the location E:\mynewfold\ , it should print the updated location E:\mynewfold.
Actually, I have no idea how to do it that's why I'm not able to provide much details for this question.
Since you're using Windows, GetModuleFileName should do the trick. Just pass NULL for the hModule parameter. Be sure to read the documentation carefully if you want to handle long file names (and you typically do). You'll also have to strip the name of the executable to get the directory path. A quick-and-dirty way to do so is to remove everything after the last \.
#include <Windows.h>
#include <stdio.h>
int main(int argc, char *argv[]){
char buff[256];
if(GetCurrentDirectory(256, buff)){//get current directory
printf("%s\n", buff);
}
return 0;
}

new learner of c, the project is not compiled?

#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
system("PAUSE");
return 0;
}
After i Compiled the programme, i click run. it still tips me " project is not compiled" why? i am sorry, i am a new learner of c.
i am using dev c++, on xp, ctrl+F9 compile then ctrl+F10 run
it shows project is not compiled
multiple definition of main
Maybe in your project there is 2 Main function..
You should at least delete/change one..
if I see, there is 1-3.c and 1c.c
and the compile is error..
[Build Error]
CMIIW
Delete the file 1c.c. You cannot have two int main functions.

Can an executable discover its own path? (Linux) [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
how to find the location of the executable in C
I would like an executable to be able to discover its own path; I have a feeling that the answer is "you can't do this", but I would like this to be confirmed!
I don't think I can use getcwd(), because I might not be executing it from the same directory. I don't think I can use argv[0], because that is based on the string that's used to execute it. Are there any other options?
Rationale
The real problem is that I'd like to place an executable somewhere on a filesystem, and place a default config file alongside it. I want the executable to be able to read its config file at runtime, but I don't want to hardcode this location into the executable, nor do I want the user to have to set environment variables. If there's a better solution to this situation, I'm all ears...
The file /proc/self/exe is a simlink to the currently running executable.
Edit: It was pointed out that using /proc/self/exe is more straightforward. That is entirely true, but I didn't see any benefit in editing the code. Since I still get comments about it, I've edited it.
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
int main()
{
char dest[PATH_MAX];
memset(dest,0,sizeof(dest)); // readlink does not null terminate!
if (readlink("/proc/self/exe", dest, PATH_MAX) == -1) {
perror("readlink");
} else {
printf("%s\n", dest);
}
return 0;
}
Initial answer:
You can use getpid() to find the pid of the current process, then read /proc/<pid>/cmdline (for a human reader) or /proc/<pid>/exe which is a symlink to the actual program. Then, using readlink(), you can find the full path of the program.
Here is an implementation in C:
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
int main()
{
char path[PATH_MAX];
char dest[PATH_MAX];
memset(dest,0,sizeof(dest)); // readlink does not null terminate!
pid_t pid = getpid();
sprintf(path, "/proc/%d/exe", pid);
if (readlink(path, dest, PATH_MAX) == -1) {
perror("readlink");
} else {
printf("%s\n", dest);
}
return 0;
}
If you want to try, you can then compile this, make a symlink from the executable to an other path, and call the link:
$ gcc -o mybin source.c
$ ln -s ./mybin /tmp/otherplace
$ /tmp/otherplace
/home/fser/mybin
Use the proc filesystem
Your flow would be:
Get pid of executable
look at /proc/PID/exe for a symlink
Well, you have to use getcwd() in conjuction with argv[0]. The first one gives you the working directory, the second one gives you the relative location of the binary from the working directory (or an absolute path).
Get your name from argv[0] then call out to the which command. This will obv only work if your executable is in $PATH.

Resources