Thread: System function problems - add paths, executable truncated

  1. #1
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582

    System function problems - add paths, executable truncated

    I'm trying to automate the generation of trees with Arbaro and POV-Ray (since Arbaro, oddly, lacks the option to bulk render trees). I've got main part of the code working where the scene file is updated, the seed is set, and all that. The only thing left is executing the needed programs from within my own program. I've tried so many different approaches but nothing is working. I'm often getting weird and unexpected results. This screenshot shows what's going on. I'm using exactly the same command line with my own program and that in command prompt but I get 2 totally different results.

    http://platformmasters.com/images/Pl...eenshot544.png

    Command Prompt works just fine but my own program is not. From fiddling around with things, I found a big clue. When I tried to execute other programs other than Java, I find that they execute just fine - cmd, dir, my hex editor, Virtual Dub, and even the required POV-Ray. The one thing that seems to be different is that, as soon as another argument comes in that requires a path, the "system" function call no longer works properly as it's truncating the path, whether or not quotes are present. For example. This works just fine:

    Code:
    sprintf(ExecutionString, "\"C:\\Program Files\\POV-Ray\\v3.7\\bin\\pvengine64.exe\""
            " +W%1d +H%1d +UA +FN8 -A", 
            ImageSize, ImageSize);
    system(ExecutionString); // executes the above
    When I get to that line with the "system" function call and execute it, I see POV-Ray starting up. POV-Ray errors, of course, mentioning of no input file but I'm expecting that. If I add an input file like this:

    Code:
    sprintf(ExecutionString, "\"C:\\Program Files\\POV-Ray\\v3.7\\bin\\pvengine64.exe\""
            " +I\"%s%spov\" +W%1d +H%1d +UA +FN8 -A +O\"%s%spng\"", 
            FileNameBase, SpeciesName, ImageSize, ImageSize);
    system(ExecutionString); // executes the above
    I see that the original path has been truncated to only "C:\Program" instead. When I execute the that line with the "system" function, I see this error:

    'C:\Program' is not recognized as an internal or external command, operable program or batch file

    POV-Ray does not execute because the path is being cut off. Java's path is not being cut off... unless I use the one in the program files directory where it does end up getting cut off. Surely there's something weird going on with the system function that's causing file paths to not execute correctly. This issue has been being fought for over 6 hours now and it's preventing me from finishing up this task. What's going on here?

    Edit: I'm using MSVC 2008 Express under Windows 7 Pro SP1 (fully updated).
    Last edited by Salem; 06-29-2014 at 01:20 AM. Reason: folded long lines
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It would help if you provided context - in particular, what is ExecutionString.

    Is ExecutionString an array of char large enough to hold the string being written to it, plus the terminating zero? If not, then your program has undefined behaviour, and one of the infinite number of possibilities is what you're observing.

    Two common traps are to do something like this
    Code:
    char x[10];
    strcpy(x, "ABCDEFGHIJ");     /*  write 11 characters to x, including the terminating zero */
    /*  code doesn't behave as expected */
    or, worse,
    Code:
    char *x;    /* uninitialised pointer that doesn't point at anything */
    strcpy(x, "A");     /*  write ANYTHING to x */
    /*  code doesn't behave as expected */
    The second mistake is common among beginners who have mistakenly come to believe that a pointer IS an array.

    system() also typically executes a command interpreter, which might parse the string before executing the program. Wrapping the whole string in an extra pair of double quotes can control that.
    Last edited by grumpy; 06-28-2014 at 05:27 PM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    It's a string that's 512 characters long (511 effective). This is the declaration. Even if I use something very excessive, like 32,768 for the array, I still get the same thing. It's not overflow, it's something else. Using strlen on that string returns 300 so it's well within the 512 limit which explains why 32,768 has no change.

    Code:
    unsigned char ExecutionString[512]; // this contains all the parameters needed to execute a program
    // unsigned char ExecutionString[32768]; // using this instead of the above doesn't change anything
    Last edited by ulillillia; 06-28-2014 at 05:36 PM. Reason: Meant to comment out the extreme case
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Looking at your original post again, when you "added an input file", the format string specifies two strings, then two ints, then two strings to be arguments, but you only provide a total of four arguments. That is also undefined behaviour.

    If that doesn't explain it you're going to need to resort to providing a SMALL but COMPLETE sample of code (as in, someone can compile/execute your example without modification) that exhibits the same problem.

    Although it probably wouldn't explain your symptoms, system() accepts a pointer to char - not unsigned char. With Microsoft compilers it is often a compile-time options whether char is signed or unsigned.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    You read my post wrong. Look closely: there are 4 parameters, not 6 like you're stating. Reread the post. I'm used to using unsigned for char because of negative array indexes being referenced when drawing special characters beyond the initial 127 text in my main project (and adding "(x+256)&0x100" to get it to a 0 to 255 range needs more CPU time than simply using unsigned). Also, look at the included screenshot. You can see that I'm using exactly the same string.
    Last edited by ulillillia; 06-28-2014 at 06:12 PM. Reason: Added a reference to the included screenshot
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You read my post wrong. The format string specifies six arguments will follow the format string. There are four provided.

    Your reasoning for using unsigned char is flawed, but that's unrelated.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    To avoid the space in "c:\Program Files" I often use "%ProgramFiles%" instead.
    Note: This is in Windows Batch files; not sure if it works in C files.

    I suggest outputting the array being using in the system call using either printf or fprintf to verify the command really is what you think it is.

    I also suggest fixing the undefined part of your code already mentioned.
    Quote Originally Posted by grumpy View Post
    The format string specifies six arguments will follow the format string. There are four provided.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You should probably CreateProcess rather than system().
    It cuts out the need to figure out the insane quoting rules of cmd.exe - which seems to be most of the problem here.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    I accidentally copied my code wrong. The full code had the inclusion of the include file and the output file. I only meant to copy the code with just the input file only being added in. Just pretend the "+O..." stuff is not there. My original function call for it has 8 parameters from 4 paths (the first one, for the program execution, doesn't have any %s) and the inclusion of the image size in 2 cases. I can say, for sure, that it's not missing parameters. I've spent 8 hours figuring this out and I've carefully examined the string with printf just to make sure it was right. If I omitted some %s, I'd have seen "(null)" in the string. That has not been present.

    I'll look into the CreateProcess function then, since it seems that system simply does not work if I'm to include more than 1 file path.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by stahta01 View Post
    To avoid the space in "c:\Program Files" I often use "%ProgramFiles%" instead.
    Note: This is in Windows Batch files; not sure if it works in C files.
    To access environment variables like ProgramFiles you should look to getenv(3): environment variable - Linux man page

    By the way, the purpose of using %ProgramFiles% is more than to avoid typing a space. Not every Windows system uses "C:\Program Files", but typically the environment variables ProgramFiles and ProgramFiles(x86) are set to the proper values for that system.

  11. #11
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by ulillillia View Post
    I can say, for sure, that it's not missing parameters. I've spent 8 hours figuring this out and I've carefully examined the string with printf just to make sure it was right. If I omitted some %s, I'd have seen "(null)" in the string.
    Sometimes (null) is printed, but sometimes it is not. You can't rely on such behavior. Why don't you print out the exact string you are executing before calling system. Then you can see if it is correct.

    Code:
    sprintf(ExecutionString, "\"C:\\Program Files\\POV-Ray\\v3.7\\bin\\pvengine64.exe\""
            " +I\"%s%spov\" +W%1d +H%1d +UA +FN8 -A +O\"%s%spng\"", 
            FileNameBase, SpeciesName, ImageSize, ImageSize);
    If FileNameBase is "D:\data files\foo" (without the quotes) and SpeciesName is "bar" and ImageSize is 512, what should the execution string look like? Note that you have address grumpy's comment first before you consider this -- in your code the parameters does not match your format string. Many compilers give warnings about this, look into increasing your warning level.

  12. #12
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    And just so you know, the real solution was that I only needed to surround the entire command with quotes. With that, I got POV-Ray to render the tree as expected. However, it's bringing up a window that I don't want so I'll probably have to use CreateProcess or something like it to suppress the appearance of the window - I want this stuff to run in the background.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problems with inventory system
    By a29bbas in forum C Programming
    Replies: 2
    Last Post: 01-07-2014, 11:50 AM
  2. Student GPA system problems
    By ShiroiShu in forum C Programming
    Replies: 10
    Last Post: 11-28-2011, 10:55 AM
  3. Copying system files problems
    By Dark Nemesis in forum Tech Board
    Replies: 11
    Last Post: 03-24-2004, 01:06 AM
  4. System problems
    By JLBSchreck in forum Tech Board
    Replies: 4
    Last Post: 06-06-2003, 08:46 PM
  5. System.ini Shell Problems
    By (TNT) in forum Windows Programming
    Replies: 2
    Last Post: 08-26-2001, 01:05 PM

Tags for this Thread