Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. How to verify Linux " system " call results ?
Forum Updated to NodeBB v4.3 + New Features

How to verify Linux " system " call results ?

Scheduled Pinned Locked Moved Unsolved C++ Gurus
8 Posts 4 Posters 1.4k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Anonymous_Banned275
    wrote on 5 May 2023, 15:56 last edited by
    #1

    I am embarrassed to post this, but...

    1. how can I verify - using "system" call that file exist ?
    2. how can I redirect "system" call actual text / error returns to QT widget ?

    I know how to read the pass / fail returns , no problem .
    I need the actual valid text or error to show in widget.

    I know it can be done because of "stdio" redirecting , but totally forgot how.

        text = " mkdir /tmp";
        array = text.toLocal8Bit();
        buffer = array.data();
        result = system(buffer);
    

    and it trows this error to console, I want to redirect it to widget.

    mkdir: cannot create directory ‘/tmp’: File exists

    Thanks

    P 1 Reply Last reply 6 May 2023, 00:24
    0
    • A Anonymous_Banned275
      5 May 2023, 15:56

      I am embarrassed to post this, but...

      1. how can I verify - using "system" call that file exist ?
      2. how can I redirect "system" call actual text / error returns to QT widget ?

      I know how to read the pass / fail returns , no problem .
      I need the actual valid text or error to show in widget.

      I know it can be done because of "stdio" redirecting , but totally forgot how.

          text = " mkdir /tmp";
          array = text.toLocal8Bit();
          buffer = array.data();
          result = system(buffer);
      

      and it trows this error to console, I want to redirect it to widget.

      mkdir: cannot create directory ‘/tmp’: File exists

      Thanks

      P Offline
      P Offline
      Paul Colby
      wrote on 6 May 2023, 00:24 last edited by
      #2

      Hi @AnneRanch,

      I am embarrassed to post this, but...

      Nothing to be embarrassed about.

      Before going any further, I must say: You really, really, should consider using something like QProcess for this - it will save you a huge amount of re-invention effort! :D

      That said, if you must use old Standard C library functions...

      1. how can I verify - using "system" call that file exist ?

      There are so many ways. If you must use system(), then maybe use stat like:

      auto result = system("stat /tmp > /dev/null 2>&1");
      

      But it would be better to use the (Standard C) fstat() function directly, rather than going through system(), and much, much, much better to use QFile::exits() instead.

      1. how can I redirect "system" call actual text / error returns to QT widget ?

      You can't from outside the system() call - you need to do the redirection inside the executed command itself, eg:

      system("mkdir /tmp > my-comands-stdout.txt 2> my-commands-stderr.txt");
      

      Of course then you need to clean up the temporary files afterwards. And if performance matters (unlikely with mkdir) then you'd want to mkfifo() for the output files. system() is essentially a convenience wrapper around popen() or execl(), and the above is effectively working around the shortcuts system() provides, so, you would be much better off switching to using popen() instead of system().

      And again, you would be much, much, much better of just using QProcess instead!

      mkdir: cannot create directory ‘/tmp’: File exists

      Just a side note, you might want to use mkdir's -p option. But in this case, I would super-strongly recommend QDir::mkpath() instead.

      Cheers.

      A 1 Reply Last reply 6 May 2023, 01:44
      0
      • P Paul Colby
        6 May 2023, 00:24

        Hi @AnneRanch,

        I am embarrassed to post this, but...

        Nothing to be embarrassed about.

        Before going any further, I must say: You really, really, should consider using something like QProcess for this - it will save you a huge amount of re-invention effort! :D

        That said, if you must use old Standard C library functions...

        1. how can I verify - using "system" call that file exist ?

        There are so many ways. If you must use system(), then maybe use stat like:

        auto result = system("stat /tmp > /dev/null 2>&1");
        

        But it would be better to use the (Standard C) fstat() function directly, rather than going through system(), and much, much, much better to use QFile::exits() instead.

        1. how can I redirect "system" call actual text / error returns to QT widget ?

        You can't from outside the system() call - you need to do the redirection inside the executed command itself, eg:

        system("mkdir /tmp > my-comands-stdout.txt 2> my-commands-stderr.txt");
        

        Of course then you need to clean up the temporary files afterwards. And if performance matters (unlikely with mkdir) then you'd want to mkfifo() for the output files. system() is essentially a convenience wrapper around popen() or execl(), and the above is effectively working around the shortcuts system() provides, so, you would be much better off switching to using popen() instead of system().

        And again, you would be much, much, much better of just using QProcess instead!

        mkdir: cannot create directory ‘/tmp’: File exists

        Just a side note, you might want to use mkdir's -p option. But in this case, I would super-strongly recommend QDir::mkpath() instead.

        Cheers.

        A Offline
        A Offline
        Anonymous_Banned275
        wrote on 6 May 2023, 01:44 last edited by
        #3

        @Paul-Colby You are "the man " Nice , very much needed to continue my project.
        BTW
        I have been using QProcess and decided to switch / try "system" - since they are both based on same.
        My concerns about QProcess - when I started I have been told that I really cannot interact with QProcess.
        I have been experimenting with "ready to read" time and "timeout" and found that when my command actually fails to execute my code fails "ready to read" and goes into "timeout" immediately.
        So my next step was to identify such false timeout failure as the command failure...

        It seems that "system" may do that better, after I digest you last post.

        K 1 Reply Last reply 6 May 2023, 03:16
        0
        • A Anonymous_Banned275
          6 May 2023, 01:44

          @Paul-Colby You are "the man " Nice , very much needed to continue my project.
          BTW
          I have been using QProcess and decided to switch / try "system" - since they are both based on same.
          My concerns about QProcess - when I started I have been told that I really cannot interact with QProcess.
          I have been experimenting with "ready to read" time and "timeout" and found that when my command actually fails to execute my code fails "ready to read" and goes into "timeout" immediately.
          So my next step was to identify such false timeout failure as the command failure...

          It seems that "system" may do that better, after I digest you last post.

          K Offline
          K Offline
          Kent-Dorfman
          wrote on 6 May 2023, 03:16 last edited by
          #4

          @AnneRanch

          With respect, QProcess is the better approach to access system shell commands, albeit more complicated.

          system() (POSIX call) stalls the running program until the child terminates.

          As long as you are aware of that, and can accept the consequences.

          man 3 system explains it...It forks, does an execl(), and then waits for the pid to terminate before the parent continues.

          As @Paul-Colby mentions, there are calls that check for file exists, so the above comments may not be relevant, but it is important to understand that system() stalls the parent.

          1 Reply Last reply
          1
          • JonBJ Offline
            JonBJ Offline
            JonB
            wrote on 6 May 2023, 07:51 last edited by JonB 5 Jun 2023, 09:00
            #5

            As said before. You can do much more interacting with QProcess than with system(). The latter simply runs /bin/sh -c "your command with any arguments" and waits for it to finish. There is nothing it does which cannot be done via QProcess. Effectively the static function QProcess::execute("/bin/sh", { "-c", "your command with any arguments" })' does just the same thing.

            Both of these suffer because any output from the command is written to stdout/stderr, and you cannot access those without doing redirection from the calling program (which we could do from the Qt application, but it's an effort we don't need). So for example you will not see any error output which is what you are asking for.

            However, with QProcess the following does allow to access any output:

            // next 3 lines do the same as `system("mkdir /tmp")`
            QProcess p;
            p.start("/bin/sh", { "-c", "mkdir /tmp" });
            qDebug() << p.waitForFinished();
            
            // next 2 lines read any output, which cannot be done so easily from `system()`
            qDebug() << p.readAllStandardOutput();
            qDebug() << p.readAllStandardError();
            // or above two lines can be replaced by `qDebug() << p.readAll()` if you don't want to see stdout/stderr separately
            

            I imagine p.readAllStandardError(); will report something like /tmp: Directory already exists here.

            If you always use this QProcess pattern and never use system() in a Qt application you will always be able to access a command's output, plus write to its input if wanted, with no disadvantages.

            A 1 Reply Last reply 6 May 2023, 18:41
            0
            • JonBJ JonB
              6 May 2023, 07:51

              As said before. You can do much more interacting with QProcess than with system(). The latter simply runs /bin/sh -c "your command with any arguments" and waits for it to finish. There is nothing it does which cannot be done via QProcess. Effectively the static function QProcess::execute("/bin/sh", { "-c", "your command with any arguments" })' does just the same thing.

              Both of these suffer because any output from the command is written to stdout/stderr, and you cannot access those without doing redirection from the calling program (which we could do from the Qt application, but it's an effort we don't need). So for example you will not see any error output which is what you are asking for.

              However, with QProcess the following does allow to access any output:

              // next 3 lines do the same as `system("mkdir /tmp")`
              QProcess p;
              p.start("/bin/sh", { "-c", "mkdir /tmp" });
              qDebug() << p.waitForFinished();
              
              // next 2 lines read any output, which cannot be done so easily from `system()`
              qDebug() << p.readAllStandardOutput();
              qDebug() << p.readAllStandardError();
              // or above two lines can be replaced by `qDebug() << p.readAll()` if you don't want to see stdout/stderr separately
              

              I imagine p.readAllStandardError(); will report something like /tmp: Directory already exists here.

              If you always use this QProcess pattern and never use system() in a Qt application you will always be able to access a command's output, plus write to its input if wanted, with no disadvantages.

              A Offline
              A Offline
              Anonymous_Banned275
              wrote on 6 May 2023, 18:41 last edited by
              #6

              @JonB
              Thanks everybody for all the comments. Appreciate that very much.

              As of right now I actually have basic issue with just the "command".

              I am getting confusing and conflicting results.

              "echo q | sudo -S -k unlink /dev/rfcomm0 "
              sh: 1: ��x3��t: not found
              sh: 1: �� tn�S���v~�� ty��tL��tG��tB��t=�P�D�H��[]A�: not found
              "echo q | sudo -S -k unlink /dev/rfcomm0 FAILURE not un linked "

              Since /dev/rfcomm0 does not yet exists the above is OK, I have no idea where the gobberish comes from.

              "echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt"
              [sudo] password for nov25-1: ln: failed to create symbolic link '/dev/rfcomm0': File exists

              Now this is wrong - contradicts "unlink" command.
              I need to find the reason why.

              "echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt SUCCESS linked "

              I am actually unable to determine , from the command itself , where the "tee" creates the file(s).

              I did try

              text += " | tee /home/temp_link.txt ;

              but it requires another authorization and I just do not know how
              to add another "sudo" to the already convoluted
              command.

              I would actually like to have the temp file in main .pro folder.
              That is my main task right now,
              I will decide between QProcess or system after I get
              the commands to behave.

              PS
              I do not get why everybody is always concern with "stalling the main process" -
              it does not matter if the main process is blocked - it cannot
              function until the "child process" is finished anyway.
              It would work just fine, for my application, if I process the "command"
              in parent and just skip creating the "child".

              K 1 Reply Last reply 7 May 2023, 00:39
              0
              • A Anonymous_Banned275
                6 May 2023, 18:41

                @JonB
                Thanks everybody for all the comments. Appreciate that very much.

                As of right now I actually have basic issue with just the "command".

                I am getting confusing and conflicting results.

                "echo q | sudo -S -k unlink /dev/rfcomm0 "
                sh: 1: ��x3��t: not found
                sh: 1: �� tn�S���v~�� ty��tL��tG��tB��t=�P�D�H��[]A�: not found
                "echo q | sudo -S -k unlink /dev/rfcomm0 FAILURE not un linked "

                Since /dev/rfcomm0 does not yet exists the above is OK, I have no idea where the gobberish comes from.

                "echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt"
                [sudo] password for nov25-1: ln: failed to create symbolic link '/dev/rfcomm0': File exists

                Now this is wrong - contradicts "unlink" command.
                I need to find the reason why.

                "echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt SUCCESS linked "

                I am actually unable to determine , from the command itself , where the "tee" creates the file(s).

                I did try

                text += " | tee /home/temp_link.txt ;

                but it requires another authorization and I just do not know how
                to add another "sudo" to the already convoluted
                command.

                I would actually like to have the temp file in main .pro folder.
                That is my main task right now,
                I will decide between QProcess or system after I get
                the commands to behave.

                PS
                I do not get why everybody is always concern with "stalling the main process" -
                it does not matter if the main process is blocked - it cannot
                function until the "child process" is finished anyway.
                It would work just fine, for my application, if I process the "command"
                in parent and just skip creating the "child".

                K Offline
                K Offline
                Kent-Dorfman
                wrote on 7 May 2023, 00:39 last edited by
                #7

                @AnneRanch said in How to verify Linux " system " call results ?:

                PS
                I do not get why everybody is always concern with "stalling the main process" -
                it does not matter if the main process is blocked - it cannot
                function until the "child process" is finished anyway.

                because the essense of event driven programming is an event loop that needs to be continually running. You're still thinking in procedural progamming terms, not event driven terms. It's doing a lot of "stuff" behind the scenes that you don't see...that's one of the reasons we use a framework instead of doing everything brute force. it does a lot of the housekeeping for you behind the scenes.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Anonymous_Banned275
                  wrote on 7 May 2023, 04:52 last edited by
                  #8

                  Here is an update.
                  Went back to project backup copy and got rid of the gibberish.

                  The result of the "ln" ( '/dev/rfcomm0' -> '/dev/ttyUSB0' ) is now in the temporary file
                  which resides in my main .pro folder .
                  Do not like it there , but...

                  I like to redirect good "ln" result into QString using stdio - if possible-
                  ,and error too.
                  I am working on that but could still use some assistance to add that to the current command.

                  "TASK unlink "
                  " echo q | sudo -S -k unlink /dev/rfcomm0 "
                  [sudo] password for nov25-1: " echo q | sudo -S -k unlink /dev/rfcomm0 SUCCESS un linked "
                  " Result system 0"
                  "TASK link - add tee "
                  " echo q | sudo -S -k ln -s -v /dev/ttyUSB0 /dev/rfcomm0 | tee temporary_link_file.txt"
                  [sudo] password for nov25-1: '/dev/rfcomm0' -> '/dev/ttyUSB0'
                  " echo q | sudo -S -k ln -s -v /dev/ttyUSB0 /dev/rfcomm0 | tee temporary_link_file.txt SUCCESS linked "
                  " Result system 0"

                  1 Reply Last reply
                  0

                  1/8

                  5 May 2023, 15:56

                  • Login

                  • Login or register to search.
                  1 out of 8
                  • First post
                    1/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved