I have an issue I need resolved, so I thought I'd throw up the problem here. It goes as such.
I want to use the system() function to change directories, and run a few programs based on user input.
Code so far:
I also tried omitting the whole cd_cmd array and doing this:Code:#include <stdio.h> int main() { int MAX_PATH = 100; int i; char path[MAX_PATH]; char cd_cmd[MAX_PATH + 3]; printf("Please enter sox src directory: "); fgets(path,MAX_PATH,stdin); for(i = 0; i < MAX_PATH; i++) { if(path[i] == '\n') { path[i] = '\0'; break; } } cd_cmd[0] = 'c'; cd_cmd[1] = 'd'; cd_cmd[2] = ' '; for(i = 0; i < MAX_PATH; i++) { cd_cmd[i+3] = path[i]; } printf("cd_cmd is now %s \n", cd_cmd); system("ls -l"); system(cd_cmd); system("ls -l"); return(0); }
that compiled, but didn't change the directory like I wanted it to.Code:system("cd ", path);
So how do I get a path from a user and change the current directory to that?
Thanks!
-
-
AKAJohnDoe Mime with Tourette's
You might need to establish the drive the directory is on first.
-
Is there any vital reason why it can't be C++? Save a little sanity in the world...
Before I get into the actual code, it might be helpful if you describe what error you get, exactly. Does your code compile? If so, what does it do?
If it doesn't, which error do you get?
Code:for(i = 0; i < MAX_PATH; i++) { cd_cmd[i+3] = path[i]; }
But then again, this is C code, buffer overflows are expected. It probably isn't a proper C program if it doesn't contain one of those...
If you want to do it this way, you should run the loop backwards (for i = MAX_PATH-4; i >= 0; --i))
or you could replace your fgets line with something like this:
Code:fgets(cd_cmd+3, MAX_PATH, stdin);
And just for fun, here's an equivalent C++ version:
Code:#include <string> #include <iostream> int main(){ std::string path; std::getline( std::cin, path ); std::string cmd = "cd " + path; system("ls -l"); system(cmd); system("ls -l"); }
(Note, I haven't actually compiled and tested either version. Mine should work as far as I can see, and with yours, I'd like a bit more information about what's wrong with it) -
I'm using C because a lot of the code is directly reused in an embedded system, which is running an RTOS that requires code to be in C.
The code does compile, and I've found an answer that negates the need for the stupid loop.
new code:
Code:#include <stdio.h> int main() { int MAX_PATH = 100; int i; char path[MAX_PATH]; printf("Please enter sox src directory: "); fgets(path,MAX_PATH,stdin); for(i = 0; i < MAX_PATH; i++) { if(path[i] == '\n') { path[i] = '\0'; break; } } system("ls -l"); chdir(path); system("ls -l"); return(0); }
edit: the problem with the original code was that it didn't actually change directories -
Any particular reason why you can't just call the command with the path in one go?
(Instead of "cd ../foo/bar; /sox chimes.wav -r 8000 -c 1 -u -1 cchimes.wav", you could just do "../foo/bar/sox chimes.wav -r 8000 -c 1 -u -1 cchimes.wav")
Which, now I come to think about it, shows another solution. Instead of multiple system() calls, just use one with all the commands separated by semicolons)
As for getting the wav filename from the user, and inserting it into the middle of the command, that sounds like sprintf() to me. -
When you call system() a new instance of bash is created, and executes whatever you tell it. This means if you do system("cd /") it opens bash, changes to /, then exits bash. Then you run system again and it opens a new bash, no longer at /. As you found, chdir will change the directory of your program, so then when bash is called, it's in the correct directory to begin with.
As the C-hater () pointed out, system("cd foo; ls -l") would work, as it'd be one bash instance. He also was correct in sprintf being useful for what you want to do:
Code:#include <stdio.h> #define MAX_FILENAME 20 #define MAX_CMD 50 main() { char a[MAX_FILENAME]; char b[MAX_CMD]; fgets(a, MAX_FILENAME, stdin); if(a[strlen(a)-1] == 0x0a) /* Our capture included the "enter" key */ a[strlen(a)-1] = 0x00; // kill it /* Create a command string including the user data */ snprintf(b, MAX_CMD, "sox foo bar -l -asdf -fdsa %s -o %s.sox", a, a); printf("Command would be: [%s]\n", b); }
If security is an issue keep in mind that someone could enter "filename `rm -rf /`". If security is not an issue then you should be okay, but you still might want to do sanity checks on the data. execl() is one way of doing this. -
You'll need the #include <string.h> header for strlen() Gorn... ^^ ... though it may be different under Unix...
-
you need more background knowledge beyond C.
If your program just need to construct a string of 'shell script' then run it through system(), there is a scripting language LUA which is small(about 100K for the VM) that is very embedd friendly and you can do it at a much higher abstract level than C.
And LUA can be compiled on almost any OS, so long there is a C compiler available. It relies nothing other than a C89 compliant C compiler. -
100kb can be quite a lot on some embedded systems. And in an RTOS, I'm not sure Lua would be a particularly good idea. You generally want something much more deterministic there.
-
As for 100kB is a lot, I have no idea the targetting environment but I believe it would be a point about how many native apps(even a very basic helloworld C program may need 5-10K) and how complex the app is. So while one C program compiled may be smaller than the lua VM, 10 such thing may not be.
Any C coders here?
Discussion in 'Linux Compatibility and Software' started by system_159, Oct 11, 2007.