I'm trying to execute a binary file named "helloworld" (compiled from a source.c) located in another directory with my program notify.c. Here's where my files are located:
/home/morts/Desktop/helloworld
/home/morts/Desktop/Homeworks/notify
I tried with:
const char *cmd = "/home/morts/Desktop/helloworld";
execl(cmd, "LOL", NULL);
perror("execl()");
exit(EXIT_FAILURE);
but I get:
execl(): Permission denied
If helloworld would be located in the same directory of notify, I'd simply put "./helloworld", but since they are in different directories, how can I fix this?
Thanks and regards.
if you want to execute an file hello under path /bin/test by execl without any parameters
try following:
execl("/bin/test/hello", "hello", (char*)NULL);
Check following otherwise you may get a permission denial error:
The first argument must be an /path/your_file without any space
The second argument must be "your_file" the same as in first argument
the last argument must be (char*)NULL
You should check that the path is correct and you have the right permissions to execute this file by trying to run the command directly in the terminal :
/home/morts/Desktop/helloworld
If it works then you have to check that the user running your program also have the permission to execute that file.
Related
I need to make a game in C for my finals. The user should input the map file he wants to play.
Here's my simple code:
int main(){
FILE *map;
char fileToRead[100];
do{
printf("Insert file name: ");
fgets(fileToRead, 100, stdin);
map = fopen("/Users/rajunior/Desktop/map_2.txt", "r");
//map = fopen(fileToRead, "r");
printf("%s", fileToRead);
If I use the "map = fopen("/Users/rajunior...)" hardcoded, it works!
But I need to use the second (commented) option; the first one is useless for my purpose.
In other words, I need the fileToRead to be in the same directory as my .c, but how?
screenshot: https://imgur.com/a/DbX9tw4
Option 1: Install the command line tools. Put the C file and the text file in the same directory. Open a terminal window. Compile and run from the command line. If I recall correctly, the command line tools download can be found in Preferences.../Downloads.
Option 2: Go to the Product/Scheme/Edit Scheme... menu. When the dialog box appears, select Run at the left and Options at the top. Then look for Working Directory. Set the working directory to point to the directory where the text file is.
This was going to be a comment, but it is too long for comfort.
You'll need to know the current directory of the process when it is run. If you run it from the shell, the current directory of your program will be the same as the current directory of the program. If you run it from within XCode, I've no idea what the directory will be, but it probably won't be where the source is — it'll be in a build directory of some sort, probably.
Your program can find out where it is run from with getcwd(). Then you'll be able to tell how to chdir() to the directory where the source is (as long as the program knows where the source is, because you told it somehow — argument or command line variable, or …). Or you can determine how to create a relative path name that will find the file in the source directory.
There's probably an XCode (maybe Objective-C) way to find the information, perhaps via plists.
I don't code for a Mac; I only code on a Mac, and I run XCode itself rather seldom.
My application is a simple executable used from the command line and takes stdin as input and stdout as output, so it behaves like many GNU tools.
To test it, I want to set up an Eclipse CDT DEBUG Configuration to pass a file to stdin and another one to stdout.
I have tried unsuccessfully a few solutions, all inside the DEBUG Configuration GUI :
In Common / Standard Input and Output / Input File: I put inputfile.txt and in the same section Output file: I put outputfile.txt. As the GUI indicates that the working directory is ${workspace_loc:/myprogram}, it should be alright, but when the debugger is started, it warns :
[Invalid file specified for console output: test/WittenACM87ArithmCoding-1.txt.coded]
[Invalid file specified for stdin file: test/WittenACM87ArithmCoding-1.txt]
In Arguments I put < inputfile.txt > outputfile.txt which is obviously not designed for that
Of course, both files are in the working directory. All attempts fails on the ch = getc(stdin); code line with some strange message:
Can't find a source file at "/build/glibc-p3Km7c/glibc-2.24/io/../sysdeps/unix/syscall-template.S"
Locate the file or edit the source lookup path to include its location.
Here is the stack:
Thread #1 [myprogram] 31960 [core: 5] (Suspended : Signal : SIGINT:Interrupt)
__read_nocancel() at /build/glibc-p3Km7c/glibc-2.24/io/../sysdeps/unix/syscall-template.S:84 0x7ffff7811700
_IO_new_file_underflow() at /build/glibc-p3Km7c/glibc-2.24/libio/fileops.c:600 0x7ffff77a9a00
__GI__IO_default_uflow() at /build/glibc-p3Km7c/glibc-2.24/libio/genops.c:413 0x7ffff77aab02
_IO_getc() at /build/glibc-p3Km7c/glibc-2.24/libio/getc.c:38 0x7ffff77a54f0
main() at /xxxxxx/src/myprogram.c:20 0x555555554f01
When I run the application directly in the console, it works:
./myprogram < inputfile.txt > outputfile.txt
I assume from this that Eclipse does not manage to realise the files redirections to stdin and stdout, so obviously, I do it the wrong way. I have searched for it, but here and here don't provide solution for my use case.
So, in order to be able to use the debugger from Eclipse, what is the right way to set up the Eclipse DEBUG Configuration ?
In fact, solution 1 was using a relative path not related to the working directory. Using either button Workspace... or File System... in the GUI enables to select the files which shall already exist.
For example with Workspace definition, the field becomes :
${workspace_loc:/myprogram/inputfile.txt} (same for output)
And it works. Debuggers says :
[Console output redirected to file:/.../myprogram/outputfile.txt]
So, I am working on an application that reads files, much the way vim or cat would, where you type "appname /path/to/file.txt" and it passes the file path as a perameter to the program which manipulates the file in some way.
I have run into a roadblock though. In vim, cat, or a similar program, you can type "appname file.txt", and it will read the file in the current directory that you launch the application from terminal in.
For example, I want to edit a file my documents directory. I type "cd ~/Documents", and then I can either type "vim ~/Documents/Essay.txt", or I just can type "vim Essay.txt".
My application will be stored in a binary file in the /bin/ directory so I can launch it from anywhere using the Terminal, but how do I pass the path name of the directory I am in when I call it from terminal?
As I am a new Linux developer (I have always worked with the .NET launguages in Windows) I am not sure weather this is handled by the Linux terminal, or by the C application itself.
Any help or suggestions would be much appreciated!
Also, if there is a more efficiant way to run it from the terminal than sticking it in the /bin/, let me know.
If you want to get the directory the process was run from you can use the system call getcwd to copy a string into a buffer and return it. The kernel keeps track of this for every process.
e.g.
char buf[100];
printf("Current directory: %s\n", getcwd(buf, 100));
The working directory can be changed, but will default to where the process launched.
This should work just fine without you having to do anything special. Did you try something that didn't work as you expected?
Generally you don't put user programs in /bin. I would store your program in /usr/local/bin.
https://unix.stackexchange.com/a/8658
I have to do a simple task. I have to open a file which is in a directory. I have the .c file in src, when I compile I move the programs (a.out) in the a bin directory. I want to read a file in the directory asset. All these folders are in a main folder.
If I do this
FILE* fp = fopen("../asset/team_list", "r");
it won't open the file. Why can't I open the file in that directory?
guess you forgot to put the extension of your file
FILE* fp = fopen("../asset/team_list.doc", "r");
Find what error you get using perror/explicit mention of error message and expect a possible reply from stackoverflow.
Make sure you are pointing out to the correct directory where the file is present from the PWD from where your program is being executed.
Relative paths are relative to the current working directory of the process, which might not be the same location as the binary file. So, if you are in /home/user/ and you run ./project/bins/my.exe then your current working directory is /home/user/, relative paths need to be relative to that location.
You can try a few things to help with this issue. First, after the failed open you could examine errno to see why the open failed, is it permissions, invalid path?
Alternatively you might have access to the strace program, this traces system calls, like open from your application, and will allow you to see the failed system call. Try strace ./project/bins/my.exe, you'll see a lot of output, dig through this looking for the failed open call, and try to figure out why this is failing, again the errno will be included in the trace to help understand the failure.
Lastly, you could just add a call to getcwd to your program and print the result (as a debugging aid), this places the current working directory into a buffer, something like this:
char buffer [PATH_MAX + 1];
getcwd (buffer, PATH_MAX + 1);
printf (buffer);
I am creating a toy shell. I want to execute a binary file which is either located in the PATH variable or the current directory. This is what I am doing to achieve it:
execl(filePath," -e ",com.arguments,NULL); //e.g of filePath: /home/dino/programs/mywrapper
Now it works fine for some executables like which command. But for commands like tar, a whole bunch of error throws up.
Basically all I want is the execl to execute the executable mentioned in filePath in my shell. How do I do it?
EDIT:
com.arguments is the arguments list. For example in which bash, bash becomes my argument. In tar -zvcf bazinga.tar.gz bazinga/, -zvcf bazinga.tar.gz bazinga/ becomes my arguments etc.
From execl's documentation
The first argument, by convention, should point to the
filename associated with the file being executed.