This question already has answers here:
Changing working directories in Linux shell in a C program
(2 answers)
Closed 7 years ago.
I'm having a problem with chdir() in my C program - only when running on Linux (works fine on Mac). I've stripped down my code.
Something like this works fine:
chdir("/Documents");
but when I try to pass it as a variable it doesn't want to work.
char *home_directory;
home_directory = malloc(80);
chdir(home_directory);
Home directory is read from a file elsewhere in my code, I can post how I've done that if needed.
Thanks.
Since you are reading home_directory from a file, have you forgotten to remove a trailing newline and any other spurious characters before you use it as a parameter to chdir?
Try doing some error checking, like this;
char *home_directory;
home_directory = malloc(80);
/* ...fill the home directory... */
if (chdir(home_directory) == -1)
perror("chdir");
.. and then with a man chdir yo can look up the meaning of the error code.
Since chdir is a system call on Linux, you can simply use the strace program to see what your program really does. That doesn't free you from handling errors preoperly in your code; obviously. It just helps you to follow the actions that your program takes.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have searched around but can't find an answer to my problem.
I am cross compiling a C++ application for the beagle bone black and wish to use the linux system() function as follows :
system("echo DM-GPIO-Test > $SLOTS");
It is to add a device overlay to control GPIO pins. The echo command "echo DM-GPIO-Test > $SLOTS" works fine when executed directly on the terminal on the beagle bone from anywhere. SLOTS is an environmental variable I defined and DM-GPIO-Test-00A0.dtb0 is in /lib/firmware
I get the following error on execution of the c++ application however:
"sh: 1: cannot create : Directory nonexistent"
Is it incorrect to call the system function like I did ?
Thanks in advance
system("echo DM-GPIO-Test > $SLOTS");
This smells bad and should be avoided.
What you probably want is to write a string in a file given by your SLOTS environment variable (see environ(7)). For that particular use, you don't need to fork any /bin/sh process (which is what system(3) does). You could simply fetch that environment variable using getenv(3).
So you might try:
const char*slotspath = getenv("SLOTS");
if (!slotspath) {
fprintf(stderr, "no SLOTS\n");
exit(EXIT_FAILURE);
}
FILE* fslots = fopen(slotspath, "w");
if (!fslots) { perror(slotspath); exit(EXIT_FAILURE); };
fputs("DM-GPIO-Test\n", fslots);
fclose(fslots), fslots = NULL;
Be aware that the environment of your program -assuming it is started by some other utility (or from init or systemd)- is probably different (and smaller) than your interactive environment.
Perhaps your slotspath should not come from your environment, but from some configuration file under /etc/ (that your program should parse), or some program argument.
So I suggest to define the format of some configuration file and parse it, and get your slotspath from it.
No, it doesn't display anything doing system("echo $SLOTS")
In this case the environment variable SLOTS is simply unset/empty in the environment used by your application. Depending on your use case you either need to set it before you start the binary, or using setenv(), or replacing it directly in the string you pass to system(). If you expect the variable to be set in any of the user's profile settings you need to be aware of the different behaviour of your shell (e. g. bash) at invocation, and place it in the right file, or create a wrapper script that sets it.
$ cat .profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
[...]
A good idea would also be to check it for valid values in your application prior to the system() call, using getenv() to obtain it and asserting if it doesn't match the requirements.
Be aware that it is best practice to enclose shell variables containing strings into double quotes, in case they contain spaces, and the identifier into curly brackets, to avoid ambiguities:
system("echo DM-GPIO-Test > \"${SLOTS}\"");
And as Basile points out in a separate answer, avoiding invocation of the shell and handling the logic of writing the file completely in C would even be more powerful regarding the handling of errors and special cases, but also results in more code (which could contain bugs of its own...).
This question already has answers here:
How do I get the directory that a program is running from?
(26 answers)
Closed 6 years ago.
Is there any way to know the directory where the program is originally spawned in C? I want my program to know where it is located in the computer. I already tried using _getcwd() in direct.h. I also tried getcwd() using unistd.h. But here's the problem. If I added a PATH to my program's directory, the functions _getcwd() and getcwd() path will return the path where I called the program. So if I ran the program in dekstop, it will return the path of the desktop instead. I already tried using this method but it doesn't fix the problem. It returns the value of the calling path. I would like to know what function to use to know the path of the program and not the path that the program is called.
What function should I use?
The current working directory is of no use whatsoever. There is no connection between an executable image's location in the filesystem and the current working directory, other than coincidental.
You can retrieve the fully qualified path to the executable by calling _get_wpgmptr (a Microsoft-specific extension to the CRT that ships with Visual Studio) or GetModuleFileName (passing NULL for hModule), and extract the path by calling PathRemoveFileSpec (or PathCchRemoveFileSpec for Windows 8 and above).
This question already has answers here:
How do I execute a command and get the output of the command within C++ using POSIX?
(12 answers)
Closed 7 years ago.
I was wondering if anyone can help me:
I need to turn the output of the system command : whoami into a variable.
Example:
char *a;
a = system("whoami");
printf("username = %s",a);
I have tried a few methods such as printing the commands output to a text file like: whoami >> output.txt and than making the program read from that file, however i am encountering errors through that method. I also consider that method to be a little messy and unnecessary as im positive that there must be a way within C to let me do this.
This question may be a duplicate so please label as necessary(but also answer if capable)
Thanks a lot :)
If everything you want is to read an environment variable in a POSIX environment, you can simply call getenv:
http://man7.org/linux/man-pages/man3/getenv.3.html
#include <stdlib.h>
#include <stdio.h>
int main() {
char* username = getenv("USER");
printf("username = %s\n", username);
return 0;
}
If you want something more complex, you can use popen:
http://man7.org/linux/man-pages/man3/popen.3.html to create a pipe to a process and read from stdout, this answer should help in that case:
C: Run a System Command and Get Output?
This should do the trick. I haven't tested it myself, but I checked and its listed in the Linux man pages so I'm sure its kosher.
This question already has answers here:
What mean file with extension "h.in"?
(3 answers)
Closed 8 years ago.
I was compiling with gcc on Linux
Because sndfile.h was not there but sndfile.h.in was found, I just tried with sndfile.h.in - which is in the same directory as the *.C file.
But I got the error even though it is in the same directory. Its been a while since I programmed in Linux that these little things are bothering me - appreciate if u could help me started. Thanks
I think you are using the angular brackets for the including the file.If you place < >. It will search in /usr/include. You have to use the double quotes for including the file in the current directory. And be sure that file is available.
Like this.
#include "sndfile.h.in"
Say I have a command line C program which is currently executing, and I want to read a file or execute another binary in the same directory - how can I find out what directory that is?
Note that I'm not looking for the current working directory. The user may have invoked my original program in any of the following ways (and possibly others I don't know about).
../../program
/home/matt/program
PATH=$PATH:/home/matt program
Ideally I'm looking for something which will work on a unix system and windows via MinGW.
http://c-faq.com/osdep/exepath.html
According to the C FAQ it can't be done reliably
Finding current executable's path without /proc/self/exe
Concat getcwd() and dirname(argv[0])