Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Please - explain the C++ code / function

Please - explain the C++ code / function

Scheduled Pinned Locked Moved C / C++ / MFC
c++
18 Posts 5 Posters 47 Views 1 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.
  • L Lost User

    Voluntarily removed - incorrect forum.

    G Offline
    G Offline
    Graham Breach
    wrote on last edited by
    #2

    The << in this is not shift left, it is operator<<() operating on whatever QStringList() returns. It might be concatenating them, or appending them to an array, or whatever. It can handle both char* and QString because it probably has overloads for both types, or possibly because QString has an operator for returning a char*. I'm guessing this from the context because the C++ standard library also uses << this way - you would have to consult the QT documentation to be sure.

    L 1 Reply Last reply
    0
    • L Lost User

      Voluntarily removed - incorrect forum.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #3

      The << operator is an overloaded operator used in C++ stream IO. In basic terms it takes whatever object or value is on the right hand side of the operator, converts it to a string (aka char*) and sends that to the stream object on the left hand side. So using the standard ouptut stream (console), you can do:

      int number = 23;
      double half = 23 / 2;

      std::cout << "value = " << number << " halved = " << half;

      So assuming the items in your code are:

      char* command = " hcitool ";
      QString string = " dev ";

      the result of:

      QP->start("/bin/sh", QStringList() << "-c" << command << "-c" << string );

      should be:

      "/bin/sh -c hcitool -c dev"

      sent to the process handler. Maybe you should spend some more time studying C++, as well as QT.

      1 Reply Last reply
      0
      • G Graham Breach

        The << in this is not shift left, it is operator<<() operating on whatever QStringList() returns. It might be concatenating them, or appending them to an array, or whatever. It can handle both char* and QString because it probably has overloads for both types, or possibly because QString has an operator for returning a char*. I'm guessing this from the context because the C++ standard library also uses << this way - you would have to consult the QT documentation to be sure.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #4

        Thank you. Appreciate your help. Am I understanding it correctly - "<<" is pretty much like passing a parameter to a function ? I am still not clear about "where -c " is passed to - is it an option to QStringList or "/bin/sh"? I believe it is "passed to QStringList" since that is a second parameter to QProcess. Perhaps now I can make more sense from QT docs, both - QProcess and QStringList. I also need to look at the source of "sh"...

        G 1 Reply Last reply
        0
        • L Lost User

          Thank you. Appreciate your help. Am I understanding it correctly - "<<" is pretty much like passing a parameter to a function ? I am still not clear about "where -c " is passed to - is it an option to QStringList or "/bin/sh"? I believe it is "passed to QStringList" since that is a second parameter to QProcess. Perhaps now I can make more sense from QT docs, both - QProcess and QStringList. I also need to look at the source of "sh"...

          G Offline
          G Offline
          Graham Breach
          wrote on last edited by
          #5

          I'm in agreement with Richard on what is actually happening there. It looks like the QStringList is being used to join all the arguments together to make a complete command line for passing to the QProcess. /bin/sh is the Bourne shell, you should be able to find the manual page for it online or by typing "man sh" in your Linux terminal. I don't know why it is using a shell instead of executing the command directly, but I suspect there is a good reason. Maybe for wildcard parsing or terminal I/O buffering.

          L 1 Reply Last reply
          0
          • L Lost User

            Voluntarily removed - incorrect forum.

            J Offline
            J Offline
            jschell
            wrote on last edited by
            #6

            Salvatore Terress wrote:

            it fails.

            Do not post questions with information like that. That can mean anything. What you need to post is the following. 1. What you expected it to do. 2. What it actually did. From the little you posted I would have no idea what 'fails' means.

            Salvatore Terress wrote:

            sudo

            I suspect the real problem is exactly that. It is not your code. It is how that gets executed within your code. Define: A 'shell' is a operating system process that executes command line commands. Windows has the console window and powershell. First step for debugging OS shell calls is always the print the command line before you call it. (Obviously removing security info if needed.) You do that even when the code works. Then when there is a problem you use that output to figure out what is wrong. Second step is to try the exact command in your own shell window. Often this will show the problem and allow you to figure out exactly how you need to modify the command. Third step is that you need to understand that OS commands that are executed from your application can and problem will have an environment that is inherited from the application. This includes access permissions. (People often have problems with Windows Services because they do not understand this.) Finally I can only note that with my limited experience I know that 'sudo' has its own oddities. For one, at least at times, I remember it requiring a password all the time. No password and it doesn't work. Another trick I have used for OS commands in an application is the following. 1. Output the command - as I said above you should always be doing this. 2. Use an OS command to open a shell - NOTHING else. So you would see a OS shell pop on your display 3. Copy the command from the output, exactly as printed, and then run it in the shell that was popped. 4. Debug as normal for problems with that command. That trick often helps to simulate the environment problem I suggested above.

            L 1 Reply Last reply
            0
            • J jschell

              Salvatore Terress wrote:

              it fails.

              Do not post questions with information like that. That can mean anything. What you need to post is the following. 1. What you expected it to do. 2. What it actually did. From the little you posted I would have no idea what 'fails' means.

              Salvatore Terress wrote:

              sudo

              I suspect the real problem is exactly that. It is not your code. It is how that gets executed within your code. Define: A 'shell' is a operating system process that executes command line commands. Windows has the console window and powershell. First step for debugging OS shell calls is always the print the command line before you call it. (Obviously removing security info if needed.) You do that even when the code works. Then when there is a problem you use that output to figure out what is wrong. Second step is to try the exact command in your own shell window. Often this will show the problem and allow you to figure out exactly how you need to modify the command. Third step is that you need to understand that OS commands that are executed from your application can and problem will have an environment that is inherited from the application. This includes access permissions. (People often have problems with Windows Services because they do not understand this.) Finally I can only note that with my limited experience I know that 'sudo' has its own oddities. For one, at least at times, I remember it requiring a password all the time. No password and it doesn't work. Another trick I have used for OS commands in an application is the following. 1. Output the command - as I said above you should always be doing this. 2. Use an OS command to open a shell - NOTHING else. So you would see a OS shell pop on your display 3. Copy the command from the output, exactly as printed, and then run it in the shell that was popped. 4. Debug as normal for problems with that command. That trick often helps to simulate the environment problem I suggested above.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #7

              Finally I can only note that with my limited experience I know that 'sudo' has its own oddities. For one, at least at times, I remember it requiring a password all the time. No password and it doesn't work. I was asking for English explanation of the code I have inherited. I have received plenty and nice assistance and I appreciate it. Please excuse my ignorance for ADDING the "sudo". That was my mistake and was diluting the focus of my post. I assumed that both commands are valid and return valid response, which is NOT the case. PLEASE consider this closed. If I need more assistance I will ask...

              1 Reply Last reply
              0
              • G Graham Breach

                I'm in agreement with Richard on what is actually happening there. It looks like the QStringList is being used to join all the arguments together to make a complete command line for passing to the QProcess. /bin/sh is the Bourne shell, you should be able to find the manual page for it online or by typing "man sh" in your Linux terminal. I don't know why it is using a shell instead of executing the command directly, but I suspect there is a good reason. Maybe for wildcard parsing or terminal I/O buffering.

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #8

                Could you help me with one more question? I have managed to build correct "command string " and received expected response.

                QP->start("sh", QStringList() << "-c" << " xterm -maximized  -hold -fa 'Monospace' -fs 24 -e  lsusb " ); 
                

                I need to replace the -e lsusb with -e command where the command is QString passed to the function. I did try few approaches , likes

                QP->start("sh", QStringList() << "-c" << " xterm -maximized  -hold -fa 'Monospace' -fs 24 -e  << command " ); 
                

                or

                QP->start("sh", QStringList() << "-c" << " xterm -maximized  -hold -fa 'Monospace' -fs 24 -e  << "-c" << command " ); 
                

                I think the "problem" is that -e option must be the last option passed to

                xterm

                and I do not know if xterm can return meaningful error. I have been running my entire test code to see if the xterm actually executes. All I am getting is QProcess starts and then terminates without actually running xterm. Thank you for your help.

                K 1 Reply Last reply
                0
                • L Lost User

                  Could you help me with one more question? I have managed to build correct "command string " and received expected response.

                  QP->start("sh", QStringList() << "-c" << " xterm -maximized  -hold -fa 'Monospace' -fs 24 -e  lsusb " ); 
                  

                  I need to replace the -e lsusb with -e command where the command is QString passed to the function. I did try few approaches , likes

                  QP->start("sh", QStringList() << "-c" << " xterm -maximized  -hold -fa 'Monospace' -fs 24 -e  << command " ); 
                  

                  or

                  QP->start("sh", QStringList() << "-c" << " xterm -maximized  -hold -fa 'Monospace' -fs 24 -e  << "-c" << command " ); 
                  

                  I think the "problem" is that -e option must be the last option passed to

                  xterm

                  and I do not know if xterm can return meaningful error. I have been running my entire test code to see if the xterm actually executes. All I am getting is QProcess starts and then terminates without actually running xterm. Thank you for your help.

                  K Offline
                  K Offline
                  k5054
                  wrote on last edited by
                  #9

                  xterm will only return whether xterm itself failed or not. So for example xterm -e /bin/false returns true (0), since xterm executed successfully. I'm suspicious about your approach, here though. Can you not run your command directly via QProcess, rather than launching an xterm? I am assuming 2 things here: 1) you need to capture the output of command, at least in part, and 2) QProcess can do that for you, similar to using pipe(), rather than using system() to run a shell command from a program.

                  "A little song, a little dance, a little seltzer down your pants" Chuckles the clown

                  J 1 Reply Last reply
                  0
                  • K k5054

                    xterm will only return whether xterm itself failed or not. So for example xterm -e /bin/false returns true (0), since xterm executed successfully. I'm suspicious about your approach, here though. Can you not run your command directly via QProcess, rather than launching an xterm? I am assuming 2 things here: 1) you need to capture the output of command, at least in part, and 2) QProcess can do that for you, similar to using pipe(), rather than using system() to run a shell command from a program.

                    "A little song, a little dance, a little seltzer down your pants" Chuckles the clown

                    J Offline
                    J Offline
                    jschell
                    wrote on last edited by
                    #10

                    k5054 wrote:

                    I'm suspicious about your approach

                    I agree with that.

                    L 1 Reply Last reply
                    0
                    • J jschell

                      k5054 wrote:

                      I'm suspicious about your approach

                      I agree with that.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #11

                      OK, reason for using xterm - I am trying to run "sudo command..." and have not figured out how to enter password...into my code. I have actually try both "sh" and "xterm" and my primary issue (as of this post ) is to get the parameters to passed correctly to QProcess. I am well aware that there is always " many ways to skin a cat " but at this point I am still stuck at resolving the passing of parameters. For now I am looking for explanations why I cannot pass multiple options to QProcess using the "<<" operator. ( Maybe I need to go back to QT forum to resolve this ...) Here is my latest code

                      QStringList params;
                      params << "-maximized"; //  work fine 
                      params  << "-e" << "lsusb"; // QProcess starts but terminates 
                      // 
                      QP->start("xterm", params);
                      
                      K L J 3 Replies Last reply
                      0
                      • L Lost User

                        OK, reason for using xterm - I am trying to run "sudo command..." and have not figured out how to enter password...into my code. I have actually try both "sh" and "xterm" and my primary issue (as of this post ) is to get the parameters to passed correctly to QProcess. I am well aware that there is always " many ways to skin a cat " but at this point I am still stuck at resolving the passing of parameters. For now I am looking for explanations why I cannot pass multiple options to QProcess using the "<<" operator. ( Maybe I need to go back to QT forum to resolve this ...) Here is my latest code

                        QStringList params;
                        params << "-maximized"; //  work fine 
                        params  << "-e" << "lsusb"; // QProcess starts but terminates 
                        // 
                        QP->start("xterm", params);
                        
                        K Offline
                        K Offline
                        k5054
                        wrote on last edited by
                        #12

                        You can tell sudo to allow certain users the ability to run a given command without having to prompt for a password. For example you might add a file foo to the /etc/sudoers.d directory

                        # allow user "joe" to use command /usr/sbin/foobar
                        joe ALL(ALL) NOPASSWD:/usr/sbin/foobar

                        allow users in group foo to use command /usr/sbin/frobnicate

                        %foo ALL(ALL) NOPASSWD:/usr/sbin/frobnicate

                        Google for sudoers to see what other options you have for the sudoers file. But you should be aware that any time a user process "needs" sudo access, its something of a smell. That is it should be considered a signal that there may be something fundamentally wrong with the approach to solving the problem. If your app definitely, absolutely, no-question-about-it needs to elevate its permissions to perform some tasks, I would be inclined to write a program that only does that one thing, and use setuid/setgid with appropriate setuid/setgid permissions e.g.

                        $ ls /usr/local/bin/foo
                        ---s--x--x 1 root root 12345 Jan 1 08:00 /usr/local/bin/foo

                        and the code for foo would do something like

                        std::string build_cmd_str(int argc, char *argv)
                        {
                        std::string cmd{"/usr/local/bin/foo"};
                        /* build up rest of command string here */
                        if(bad_things_happened) {
                        cmd.erase();
                        }
                        return cmd;
                        }

                        main(int argc, char *argv[])
                        {

                        // create a command string
                        std::string cmd{build_cmd_str(argc, argv)};

                        if(cmd.length() == 0) {
                        // send diagnostic to cerr, maybe?
                        return -1;
                        } else {
                        setuid(0); // set actual uid to root
                        FILE *p = pipe(cmd.c_str(), "r");
                        // process output
                        // send to stdout as needed
                        pclose(p);
                        }

                        return 0;
                        }

                        This can be as simple or complex as you need, but should only execute one system command. Ideally, if you only need to run something as perhaps the database administrator, the helper program would have setuid as the dba, not root.

                        "A little song, a little dance, a little seltzer down your pants" Chuckles the clown

                        J 1 Reply Last reply
                        0
                        • L Lost User

                          OK, reason for using xterm - I am trying to run "sudo command..." and have not figured out how to enter password...into my code. I have actually try both "sh" and "xterm" and my primary issue (as of this post ) is to get the parameters to passed correctly to QProcess. I am well aware that there is always " many ways to skin a cat " but at this point I am still stuck at resolving the passing of parameters. For now I am looking for explanations why I cannot pass multiple options to QProcess using the "<<" operator. ( Maybe I need to go back to QT forum to resolve this ...) Here is my latest code

                          QStringList params;
                          params << "-maximized"; //  work fine 
                          params  << "-e" << "lsusb"; // QProcess starts but terminates 
                          // 
                          QP->start("xterm", params);
                          
                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #13

                          Salvatore Terress wrote:

                          Maybe I need to go back to QT forum to resolve this

                          Definitely yes, as none of this has anything to do with C++. I have looked at the documentationm for QStringList and QProcess, and what you are doing looks correct. But why it fails is impossible to guess.

                          1 Reply Last reply
                          0
                          • K k5054

                            You can tell sudo to allow certain users the ability to run a given command without having to prompt for a password. For example you might add a file foo to the /etc/sudoers.d directory

                            # allow user "joe" to use command /usr/sbin/foobar
                            joe ALL(ALL) NOPASSWD:/usr/sbin/foobar

                            allow users in group foo to use command /usr/sbin/frobnicate

                            %foo ALL(ALL) NOPASSWD:/usr/sbin/frobnicate

                            Google for sudoers to see what other options you have for the sudoers file. But you should be aware that any time a user process "needs" sudo access, its something of a smell. That is it should be considered a signal that there may be something fundamentally wrong with the approach to solving the problem. If your app definitely, absolutely, no-question-about-it needs to elevate its permissions to perform some tasks, I would be inclined to write a program that only does that one thing, and use setuid/setgid with appropriate setuid/setgid permissions e.g.

                            $ ls /usr/local/bin/foo
                            ---s--x--x 1 root root 12345 Jan 1 08:00 /usr/local/bin/foo

                            and the code for foo would do something like

                            std::string build_cmd_str(int argc, char *argv)
                            {
                            std::string cmd{"/usr/local/bin/foo"};
                            /* build up rest of command string here */
                            if(bad_things_happened) {
                            cmd.erase();
                            }
                            return cmd;
                            }

                            main(int argc, char *argv[])
                            {

                            // create a command string
                            std::string cmd{build_cmd_str(argc, argv)};

                            if(cmd.length() == 0) {
                            // send diagnostic to cerr, maybe?
                            return -1;
                            } else {
                            setuid(0); // set actual uid to root
                            FILE *p = pipe(cmd.c_str(), "r");
                            // process output
                            // send to stdout as needed
                            pclose(p);
                            }

                            return 0;
                            }

                            This can be as simple or complex as you need, but should only execute one system command. Ideally, if you only need to run something as perhaps the database administrator, the helper program would have setuid as the dba, not root.

                            "A little song, a little dance, a little seltzer down your pants" Chuckles the clown

                            J Offline
                            J Offline
                            jschell
                            wrote on last edited by
                            #14

                            k5054 wrote:

                            I would be inclined to write a program that only does that one thing, and use setuid/setgid with appropriate setuid/setgid permissions e.g.

                            That sounds like a really good solution to me.

                            1 Reply Last reply
                            0
                            • L Lost User

                              OK, reason for using xterm - I am trying to run "sudo command..." and have not figured out how to enter password...into my code. I have actually try both "sh" and "xterm" and my primary issue (as of this post ) is to get the parameters to passed correctly to QProcess. I am well aware that there is always " many ways to skin a cat " but at this point I am still stuck at resolving the passing of parameters. For now I am looking for explanations why I cannot pass multiple options to QProcess using the "<<" operator. ( Maybe I need to go back to QT forum to resolve this ...) Here is my latest code

                              QStringList params;
                              params << "-maximized"; //  work fine 
                              params  << "-e" << "lsusb"; // QProcess starts but terminates 
                              // 
                              QP->start("xterm", params);
                              
                              J Offline
                              J Offline
                              jschell
                              wrote on last edited by
                              #15

                              Salvatore Terress wrote:

                              I am still stuck at resolving the passing of parameters.

                              Following is not specific to sudo. When you execute an OS command in any application the following applies 1. The command to run the executable 2. What happens AFTER the executable starts running. The first represents the command (binary exe) and the command line options that the command accepts. What happens with the second depends on the command. But a normal command (non-UI) will be using STDIO (stdin, stdout, stderr.) The second can NOT be controlled with 'parameters'. Only the first can. The only way you can interact with the second in an application is by accessing the STDIO of the application as it runs. The second becomes more complicated if the application has a GUI. It can also be more complicated in specific situations depending on exactly what the application does. (There is a way to bypass STDIO.) For sudo and the first and the way you are executing it with "QP->start" you can only do what the command line options for the command allow. I suspect sudo probably varies by the specific OS. But following is one example. sudo(8) - Linux manual page[^] There is no way to change that. Either it is allowed by that or it isn't. Additionally "start" might have a specific meaning on Windows which can also impact what happens. That doesn't mean is actually applies in this case. start | Microsoft Learn[^]

                              1 Reply Last reply
                              0
                              • L Lost User

                                Voluntarily removed - incorrect forum.

                                J Offline
                                J Offline
                                jeron1
                                wrote on last edited by
                                #16

                                :thumbsdown: For the removal. :thumbsdown:

                                "the debugger doesn't tell me anything because this code compiles just fine" - random QA comment "Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst "I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle

                                L 1 Reply Last reply
                                0
                                • J jeron1

                                  :thumbsdown: For the removal. :thumbsdown:

                                  "the debugger doesn't tell me anything because this code compiles just fine" - random QA comment "Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst "I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle

                                  L Offline
                                  L Offline
                                  Lost User
                                  wrote on last edited by
                                  #17

                                  Fairly common behaviour from someone who is on their (at least) fourth incarnation here.

                                  J 1 Reply Last reply
                                  0
                                  • L Lost User

                                    Fairly common behaviour from someone who is on their (at least) fourth incarnation here.

                                    J Offline
                                    J Offline
                                    jeron1
                                    wrote on last edited by
                                    #18

                                    It takes all kinds. :sigh:

                                    "the debugger doesn't tell me anything because this code compiles just fine" - random QA comment "Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst "I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle

                                    1 Reply Last reply
                                    0
                                    Reply
                                    • Reply as topic
                                    Log in to reply
                                    • Oldest to Newest
                                    • Newest to Oldest
                                    • Most Votes


                                    • Login

                                    • Don't have an account? Register

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • World
                                    • Users
                                    • Groups