0

When we start in the mono-service mode on Ubuntu Linux 16.04 in the background, we would like to create and store a log file at wherever the user wants. I tried this URL, stackoverflow.com/questions/11024474/capture-mono-service-stdout-console-output

where it says do this:

mono-service2 myservice.exe -l:/var/run/test --debug > log.txt

which does not work when I test the following C++ program:

#include <unistd.h>     // execv(), fork()
#include <sys/types.h>  // pid_t
#include <sys/wait.h>   // waitpid()
#include <stdio.h>

int main(int argc, char* argvp)
{
   char *argv[] = { "/usr/lib/mono/4.5/mono-service.exe", 
                    "SmartCamXi_NVR_Recorder.exe", "--debug", "'>&'","/home/venkat/LOGCamster.txt", 0};


    char *envp[] =
    {
        "LD_LIBRARY_PATH=/home/venkat/Debug",
        0
    };
    execve(argv[0], &argv[0], envp);
    fprintf(stderr, "Oops!\n");
    return -1;

}

because I observe no log file being created. How could I fix this error?

  • Is your C program the thing that you are calling as mono-service2? Or myservice.exe? Please edit your question to make that clear. – roaima May 17 '16 at 12:09
  • @roaima, Thanks for the comment. Myservice.exe is a C# executable. mono-service2 is a C++ utility program written by Xamarin and Microsoft to support Mono Linux deployments. – Frank May 17 '16 at 15:01
1

The C program performs the equivalent of this script:

#!/bin/bash
export LD_LIBRARY_PATH=.
exec /usr/lib/mono/4.5/mono-service.exe Audio_Video_Recorder.exe --debug '>&' LOGCamster.txt
echo "Oops!" >&2
exit 255

Notice that the >& and LOGCamster.txt are passed as literal arguments to your command line. Specifically, >& is not interpreted by the shell to mean "attach stderr to stdout" because there is no shell handling your command line.

The chances are that the program doesn't like the '>&' parameter it's being given and exits immediately.

Setting LD_LIBRARY_PATH to ., opens up a potentially huge security hole. I really wouldn't do that if I were you.


If you really need to do this from an executable then you can do one of two things

  1. Redirect stdout and stderr yourself. Here you'll need to close(1) and then open() to your log file. You can then close(2) and dup(1). After this just execve your program without trying to redirect the output anywhere - because it's already being redirected to the log file.

  2. Call a shell to interpret your command. Here you need three arguments: char *argv[] = { "/bin/sh", "-c", "mono-service.exe Audio_Recorder.exe --debug >& log.txt" }. However, if you're doing this you really might as well use a script, which is easier to write and more maintainable.

  • Thank you for your very nice answer. I am dumping the LD_LIBRARY_PATH = . , because it is a big security hole. Also, I see no file named LOGCamster.txt being created. Could you please show me how to correct my program ? Are you suggesting I ditch the redirection operator >&? – Frank May 17 '16 at 12:25
  • @Frank I must apologise - I misread your code. I have rewritten my answer to take account of my new interpretation so please check that my answer is still appropriate for you. – roaima May 17 '16 at 12:51
  • Thank you for your excellent comment. I revised my original C++ program , shown at the bottom of the original question. It still not generate LOGCamster.txt. May I request that you take a look at it and possibly suggest corrections to it? – Frank May 17 '16 at 13:30
  • It looks like you've adjusted >& so that the parameter is now the four characters '>&'. The fundamental problem is that >& cannot do what you want (i.e. to redirect stderr to stdout) because you're not invoking a shell to parse it. May I ask what you're trying to achieve with your C program that can't be handled in a couple of lines of shell script? – roaima May 17 '16 at 13:45
  • Thank you for your answer. Your idea of a couple lines of shell script is great. However, My manager wants me to write a C++ program to start the C# executable, Audio_Recorder.exe, as a service and also create and write a log file in an user-specified location. How might I do that? I tried char *argv[] = {"/bin/sh", "mono-service.exe", "Audio_Recorder.exe", "--debug", ">&", "log.txt",0) followed by execve(argv[0], &argv[0], envp) with no success. – Frank May 17 '16 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.