I'm trying to implement a tool that starts 2 ssh connections and executes a script that requires root permission.
Here is a very simple implementation:
void* SshConnection(void* args)
{
char buffer[5000];
FILE* popenReturn = NULL;
//get the hostname to connect to
const char* hostname = (const char*)args;
snprintf(buffer, sizeof(buffer),
"/usr/bin/gnome-terminal -x bash -c \""
"ssh -t user@%s "
"-i /home/user/.ssh/key.key "
"\\\"/home/user/DoRootThings.bash\\\" ",hostname);
popenReturn = popen(buffer,"w");
pclose(popenReturn);
//...connect to the host again later on and look at results of DoRootThings.bash...
}
I create 2 threads using this function and detach them
Given the above implementation I would expect 2 gnome-terminals to be visible that have logged into the 'user' account using they keys provided with the -i ssh option. The script should have been executed and is waiting for the root password to be provided while both threads of execution have stopped at pclose() while waiting for their respective gnome-terminals to return.
Instead, 2 gnome-terminals do open and they are waiting for the root password. The execution for 1 of the threads stops at the pclose() while the other threads pclose() immediately returns. This thread then continues onto look at the results of DoRootThings.bash without there being any results since it is still waiting for the password to execute!
Solaris man page for popen() and pclose() claims that they are both thread safe. I have tried multiple forms of locking just to be safe to no avail.
The only form of locking that works is
pthread_lock(&lock1);
popenReturn = popen(buffer,"w");
pclose(popenReturn);
pthread_unlock(&lock1);
but this leaves me with a single threaded solution.
Is this a case of the man page being wrong and popen() and pclose() are not thread safe? If so, is there a locking solution that will fix this?
otherwise, am I not doing something correct in my implementation?
NOTE: I initially used system() instead of popen() and pclose() but this is not a thread safe call and the Solaris man page for system() reccomends popen() and pclose()