LINUX programming

Moderators: ITA
Number of threads: 1347
Number of posts: 2935

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Simple Shell in C++ Posted by bragr on 19 Oct 2010 at 2:02 PM
I am new to linux programming, and to get my bearings, I have been writing some small programs. I have already written a ls clone that will do ls, ls -l, and ls -lR. My current project is to write a simple shell. My understanding on how to do this is to loop the following: Get some input from the user and parse it into an array of cstrings, fork the program, have the child exec the user's command. I tried this, but I found that I lost i/o with the child after the exec, which make sense considering what it does. I did some reading online, I found that I need to use pipes to connect the child stdout and stdin to the parents before the exec. I did a few experiments with the pipes, but they all either crashed or didn't work, so I'm clearly missing something.

Is my understanding of what I need to do correct? Am I missing some small, but important detail? Is it even possible to connect out pipe to the parent's stdout so the child's output is automatically output to the console, or do I need to manually read the pipe and output its contents. Can you give me some examples of using pipes in this context, preferably in C++? Thanks in advance.


My code so far:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

const unsigned int MAX_ARGS = 128;

using namespace std;

// Execute a parsed command line returning the command's exit code
int doit(const vector<string>& tok)
{
    if (!tok.size() || tok[0] == "") return 0;
    // If user entered cd, change to specified dir. If no dir specified, change to the users home dir
    else if (tok[0] == "cd")
    {
        if (tok.size() > 1) chdir(tok[1].c_str());
        else chdir(getenv("HOME"));
        return 0;
    }

    //Else execute the command specified by the user
    if (pid_t kidpid = fork())
    {
        //Parent
        int status = 0;
        if (tok.back().at(tok.back().size() - 1) != '&')
        {
            waitpid(kidpid, &status, 0);

            #ifdef _INSPECT_EXIT_STATUS
                cout << "exit status=" << status << endl;
            #endif //_INSPECT_EXIT_STATUS
        }
        return status;
    }
    //Child - execute the command
    char* arglist[MAX_ARGS];
    for (unsigned int x = 0; x < tok.size() && x < MAX_ARGS - 1; x++)
        strcpy(arglist[x], tok[x].c_str());
    arglist[tok.size()] = NULL;

    execvp(tok[0].c_str(), arglist);

    //Program will never reach here unless execvp failed
    cerr << "execpv failed: " << strerror(errno) << endl;
    exit(errno);
}

int main(int argc, char* argv[], char* envp[])
{
    while (!cin.eof())
    {
        cout << "? ";
        string temp;
        getline(cin, temp);
        if (temp == "exit") break;

        vector<string> v;
        //Break string into separate strings on whitespace
        {
            stringstream foo(temp);
            string s;
            while (foo >> s)
            {
                if (s[0]=='~') s = getenv("HOME") + s.substr(1);
                v.push_back(s);
            }
        }
        doit(v);
    }
    cout << "exit" << endl;
    return 0;
}
Report
Re: Simple Shell in C++ Posted by bragr on 25 Oct 2010 at 2:44 PM
I found that my problem was that I was secretly seg faulting in the child, which was causing the child to silently fail. The code works if you substitute the strcpy() with "arglist[x] = strdup(tok[x].c_str());" which actually allocates memory. The pipes are only needed for commands like "ps aux | grep bragr" in which the output of one child needs to be piped to the input of another.
Report
Re: Simple Shell in C++ Posted by blkhd32 on 14 Apr 2011 at 6:52 PM
Hi,
I was wondering if you ever got your '|' '>' '<' up and running on your shell?

thnks
Report
Re: Simple Shell in C++ Posted by bragr on 14 Apr 2011 at 8:22 PM
I did but if you go to ucr, I'm not going to give you code. :)



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.