0

On couple of RHEL 5.8, I am facing problem with execve calls. The execve is not failing however, getting the following error:

/bin/bash: h: No such file or directory

I am using it the following way in C++ code:

::fork();
.
.
.
char achWritePipeDescriptor[8], achReadPipeDescriptor[8];
snprintf(achWritePipeDescriptor, sizeof(achWritePipeDescriptor), "%d", fWritePipeDescriptor);
    snprintf(achReadPipeDescriptor, sizeof(achReadPipeDescriptor), "%d", fReadPipeDescriptor);

// fWritePipeDescriptor and fReadPipeDescriptor are integers

::execl("/bin/sh", "/bin/sh", "Launcher.sh", achWritePipeDescriptor, achReadPipeDescriptor, (char*)0);

switch(errno)
{
default:
    printf("\n Failed to launch Launcher.sh\n");
    break;
}

The exec call here is not failing, but I was getting above error when trying to interact with the above script.sh. The strace output for this process looks like following:

execve("/bin/bash", ["/bin/bash", "h", "10", "6"], [/* 36 vars */]) = 0
.
.
.
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat(2, 0x7fff23708910)                = -1 EBADF (Bad file descriptor)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b9d1c785000
write(2, "/bin/bash: h: No such file or di"..., 40) = -1 EBADF (Bad file descriptor)
exit_group(127)                         = ?
Process 13030 detached

There is no file "h" being referenced here, but the last character of the script name is "h". Also, the script that I am trying to exec does exist at expected location and is having sufficient permissions.

I have no clue from where the "h" is coming.

I changed my execve call to following:

::execl("Launcher.sh", "Launcher.sh", achWritePipeDescriptor, achReadPipeDescriptor,(char*)0);

With this, it worked properly, but down the code below, I am seeing similar error for another execl call. The difference in the second exec is that the binary is different, but the error remains the same.

I am not sure, if this is server specific issue.

Any clues, any troubleshooting steps would be of great help.

My Bad, I should have mentioned it earlier itself, the <script.sh> is a placeholder. I tried to indicate that a shell script is what I am trying to exec. Also, writefd and readfd are char* here. It can be clearly seen in the strace output I have pasted here. Again, the exec is not failing here as i am not seeing the "Failed to launch Launcher.sh" message.

  • Since you're hiding the all-important information — which is what your pseudo-value `` is — from us, it is not possible to help much. You should print the values before you do the exec. When you're getting funny results, print out the values. The chances are, `strace` is telling the truth and the shell is being asked to execute a script `h` which it can't find. Your `switch (errno) case default: printf("...");` code is bizarre; valid (sort of) but bizarre. If the `execl()` returns, it failed. You don't need to test anything; just report the error (to `stderr` or `cerr`). – Jonathan Leffler Nov 01 '12 at 04:56
  • @Jonathan, for the information, the exec call I have mentioned perfectly fine on other RHEL servers. there are only couple of RHEL where the same thing is failing. I have edited my post to indicate the values. I have posted example from the actual post. – user1787572 Nov 01 '12 at 06:37
  • I mean actual code not post in previous comment believe me, i have already done the exercise to find out if the values being passed to the exec call are correct and all the basic things like permission and location of the script are correct. Its the matter of identifying whats going wrong on the specific RHEL servers. For your information, is Launcher.sh. Also corrected the syntax error in switch (errno). This is all I think of while posting the question. Let me know, if I am missing on any information which is important from troubleshooting point of view and I shall provide it. – user1787572 Nov 01 '12 at 06:48
  • You've got a problem with your code. We cannot execute or compile what you've showed. What you've showed does not tell us what the problem is. Therefore, it is likely the problem is in what you've not showed us. We can't guess what's wrong with the code you've not shown us. Please consider the merits of an SSCCE (a [Short, Self-Contained, Correct (Compilable) Example](http://sscce.org/)). – Jonathan Leffler Nov 01 '12 at 09:25

2 Answers2

1

There's another problem here in addition to the <script.sh> vs "script.sh" problem addressed by MikeyB. That other problem is the writefd and readfd being passed to execl. Given the names, I'm assuming those are the write end of one pipe and the read end of another pipe. If this is the case, writefd and readfd are integers, not char* pointers.

The simplest approach to making some script communicate with your program through pipes is to dup2 the read end of one pipeline to standard input and dup2 the write end of the other pipeline to standard output before the call to execl. The script simply reads from standard input and writes to standard output. You don't need to pass those file descriptors at all to the script.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
0
execl("/bin/sh", "/bin/sh", <script.sh>, writefd, readfd, NULL);

That's just not going to work… <script.sh> isn't valid C++.

Change it to:

execl("/bin/sh", "/bin/sh", "script.sh", writefd, readfd, NULL);
MikeyB
  • 3,288
  • 1
  • 27
  • 38