Page 1 of 2

How to implement the shell interface?

Posted: Thu Feb 19, 2009 11:33 am
by negcit.K
Hi, all.
i'm about to implement the command line interface for my os, but something confused me.
As i know, the prototype of a shell is :

Code: Select all

oid shell_init()
{
        while(1) {
                puts("$ ");
                
                /* type the command first */

                /*(1)*/then reading it from console buffer;
                
                parsing the command buffer;

                run the command;
                
        }
}
but the problem is :
How can i stop (1) be happened before the command totally be entered?

if not solve this, as you can see from the above code, it'll puts "$ " at all the time.

Have any body have ideas?
and i would appreciate it very much if some one give me some useful information about CLI.
Thanks!
negcit.K

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 11:44 am
by Solar
Hmmm... isn't that obvious?

When you type into the shell of your OS of choice. You can type, backspace, copy, paste, and only when you press return is the line passed to the shell process.

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 11:51 am
by negcit.K
Solar wrote:Hmmm... isn't that obvious?

When you type into the shell of your OS of choice. You can type, backspace, copy, paste, and only when you press return is the line passed to the shell process.
Yeah, that's what i think. but how can i stop the kernel from running just waiting your keyboard press?
like this?

Code: Select all

while( get_char() != '\n' )
        ;
in this way , while i pressed a key, the kernel hangs(is this my kernel's problem?).

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 12:20 pm
by yemista
you can have the shell program block while there are no keystrokes, and have keystrokes wake it up and then it processes the keystroke, be it either echo the character, or go back a space or whatever, and if the keystroke is enter, process the line. The whole time the shell internally is building a modifying a string consisting of keystrokes

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 4:36 pm
by Firestryke31
The basic command loop behind Socks is as follows (pseudocode):

Code: Select all

while(1)
{
  key = getKey(); // Waits for keypress
  if(key == '\b')
     removeCharFromBuffer(cmdBuffer);
  else if(key == '\n')
  {
    parseBuffer(cmdBuffer);
    findFile(cmd);
    runPrgm(foundFile, args);
    resetBuffer(cmdBuffer);
  }
  else if(' ' <= key && key <= '~')
    addCharToBuffer(cmdBuffer)
  setCursor(0, promptLine);
  print(prompt);
  print(cmdBuffer);
}
Of course, this is just a basic overview of what's going on, and isn't entirely accurate, but it's close enough. There are also probably better ways of handling it, too.

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 5:36 pm
by Troy Martin
More psuedocode, but more C-ish:

Code: Select all

void shell()
{
    char cmd_buffer[256];
    char cmd_help[] = "help";
    char cmd_hello[] = "hello";

    while(1)
    {
        puts("$ ");
        get_string(cmd_buffer,255);
        if (string_compare(cmd_buffer,cmd_help);)
        {
            puts("help file\n\n");
        }
        else if (string_compare(cmd_buffer,cmd_hello);)
        {
            puts("hello world!\n\n");
        }
        else
        {
            puts("bad command entered.\n\n");
        }
    }
}

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 5:39 pm
by JamesM
Solar wrote:Hmmm... isn't that obvious?

When you type into the shell of your OS of choice. You can type, backspace, copy, paste, and only when you press return is the line passed to the shell process.
Urrmmm, no. Most shells accept characters one-at-a-time, and have the terminal in Raw mode, so no echo, and use backspace/space characters to move the cursor left/right. Curses apps can use cleverer stuff if they have a terminfo/termcap file.

The answer is to use a grammar to parse the input. The grammar should terminate when a fully-fledged command has been entered - not just when the user presses enter. Why?

Code: Select all

$ echo "my 
> shell is cool and has newline
> breaks"
So that you can handle the above.

James

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 8:12 pm
by iammisc
JamesM wrote:
Solar wrote:Hmmm... isn't that obvious?

When you type into the shell of your OS of choice. You can type, backspace, copy, paste, and only when you press return is the line passed to the shell process.
Urrmmm, no. Most shells accept characters one-at-a-time, and have the terminal in Raw mode, so no echo, and use backspace/space characters to move the cursor left/right. Curses apps can use cleverer stuff if they have a terminfo/termcap file.
I think that's what Solar meant. The bottom line is the shell never actually runs anything until you tell it to (most of the time by pressing enter). To me it seems like the OP was under the impression that shells would spontaneously run their input.

Re: How to implement the shell interface?

Posted: Thu Feb 19, 2009 11:30 pm
by negcit.K
Thanks all.

but i think the most key problem is how to sleep the kernel before a key pressed.
or in another word, how to implement:

Code: Select all

wait_for_keypress();
and why the following code doesn't work for me?

Code: Select all

while ( (c=get_char()) != '\n')
        ;

Re: How to implement the shell interface?

Posted: Fri Feb 20, 2009 3:53 am
by jal
negcit.K wrote:but i think the most key problem is how to sleep the kernel
I think the most 'key problem' is that you do not only understand at all how an OS works, but you also do not know how to program. Please, learn some programming first, then learn some OS stuff (like interrupt handling, scheduling, multi-tasking, blocking, critical sections, etc.), then come back. See you in 3 years (yeah, I'm an optimist)...


JAL

Re: How to implement the shell interface?

Posted: Fri Feb 20, 2009 4:21 am
by negcit.K
jal wrote:
negcit.K wrote:but i think the most key problem is how to sleep the kernel
I think the most 'key problem' is that you do not only understand at all how an OS works, . Please, learn some programming first, then learn some OS stuff (like interrupt handling, scheduling, multi-tasking, blocking, critical sections, etc.), then come back. See you in 3 years (yeah, I'm an optimist)...


JAL
Thank you first, just for some unknown reason.!

But, can you give me more details on what you saying?
especially
but you also do not know how to program
this sentence.

Thanks again!

Re: How to implement the shell interface?

Posted: Fri Feb 20, 2009 6:04 am
by jal
negcit.K wrote:But, can you give me more details on what you saying?
especially
but you also do not know how to program
this sentence.
It seems obvious from the problems you seem to be having. Alternatively, you just really do not know how to ask questions. Otherwise you would have asked straight away how to implement reading characters without a busy loop and/or blocking the kernel. That would still be a question revealing your ignorance about OS design, but at least I wouldn't have had expected you not being able to program.


JAL

Re: How to implement the shell interface?

Posted: Fri Feb 20, 2009 6:34 am
by negcit.K
Alternatively, you just really do not know how to ask questions
I'm sorry for my bad english 'cause english isn't my mother language.
and , at first i just wanna collect some useful information about CLI since i haven't seen any things about CLI implementation on various OSDEV websites.

and after some thinking , i found the key problem is how to block the kernel before a key pressed.
something like:

Code: Select all

void shell_init()
{
        while(1) {
                puts("$ ");
               
               [color=#FF0000] **** STOP kernel running until return pressed *****[/color]
               
                parsing the command buffer;

                run the command;
               
        }
}
but, unfortunately, i make my shell work in another way.
in the ker_interrupt_handle(), i allocated a comand buffer char array com_buffer; if'\n' met, send the com_buffer to command parse routine, or store it in com_buffer.
what an ugly implementation, but it works :D

Re: How to implement the shell interface?

Posted: Fri Feb 20, 2009 6:55 am
by Solar
negcit.K wrote:I'm sorry for my bad english 'cause english isn't my mother language.
It isn't for about half of the people here. But we would forgive you your language problems allright.
at first i just wanna collect some useful information about CLI since i haven't seen any things about CLI implementation on various OSDEV websites.
That is because the CLI is a user-space thing, unless we're talking about a "toy" kernel. That means you don't implement it until most of your kernel work is already done.
i found the key problem is how to block the kernel before a key pressed.
No it isn't. The problem is that you don't implement the CLI within the kernel.
in the ker_interrupt_handle(), i allocated a comand buffer char array com_buffer; if'\n' met, send the com_buffer to command parse routine, or store it in com_buffer.
what an ugly implementation, but it works :D
There is nothing ugly about it, it's how I would expect it to be.

Re: How to implement the shell interface?

Posted: Fri Feb 20, 2009 9:15 am
by JamesM
in the ker_interrupt_handle(), i allocated a comand buffer char array com_buffer; if'\n' met, send the com_buffer to command parse routine, or store it in com_buffer.
what an ugly implementation, but it works
Again, use a grammar! This is a language problem. So solve it with a parser for a language.