c++linuxbashshellwildcard-expansion

Prevent wildecard expansion with system() function call


I have read this: Stop shell wildcard character expansion? and similar - this is not a duplicate question.

I am dealing with a set of legacy c++ code, from which a number of binaries are built. This code uses system function to execute a shell script passing it some arguments. Unfortunately, as it turned out, some arguments may include * character, yet arguments are not properly escaped. As a result, when the shell script is execute, the * gets expanded, which is not what I want. Here's a simple code to replicate the issue:

script.sh

#!/bin/bash

i=1
for var in "$@"
do
    echo "$i => $var"
    ((i++))
done

program.cpp

#include <stdlib.h>
#include <string>

int main(int argc, char* argv[])
{
   std::string command = "/tmp/sh/script.sh *";
   return system(command.c_str());
}

When the compiled binary executes, I get the list of files as parameters to the shell, instead of the asterisk:

$ ./program
1 => program
2 => program.cpp
3 => script.sh

Now, if I turn off glob expansion in shell using set -f or set -o noglob, then calling the script directly works as expected:

$ set -f
$ ./script.sh *
1 => *

However when the script is executed with system, this doesn't work:

$ set -f
$ ./program
1 => program
2 => program.cpp
3 => script.sh

Is there any way to prevent the expansion when command is executed via system?

I really want to avoid having to rebuild the binaries, as operationally and managerially it would be an enormous amount of work.

UPDATE: As I mentioned, I want to avoid any changes to the cpp source; I want to simply disable glob expansion on the OS level (via any flags, changed files, etc. - I'm happy to modify any files on the box if needed).


Solution

  • In the interest of closing the loop, as Slava didn't post the answer... Copied from his comment:

    You can create a shared lib with your own system() function and add it by LD_PRELOAD var

    I ended up using this method - and it worked perfectly fine.