You are not logged in.

#1 2009-04-15 02:17:05

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Aprz Shell

Well, ever since I switched to Linux, I've been interested in os development. An important part of the operating system is the shell. So recently, I decided to write my own shell, which I hope I can make featureful and robust enough to use in place of GNU Bash.

I am not so sure if this is the appropriate forum because it could work in Community Contribution too in my opinion and this isn't a programming question really, just sharing the source code, but you guys can criticize and suggest things.

examplea.png

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char *args[80];
char input[80];
int errno;
int i;

int main(void) {
    while(strcmp(input, "exit")) {
        i = 1;
        do {
            printf("Aprz-0.3$ ");
            gets(input);
        } while(input[0] == '\0');
        args[0] = strtok(input, " ");
        while((args[i] = strtok(NULL, " ")) != NULL && ++i);
        if(!strcmp(args[0], "cd")) {
            chdir(args[1]);
            continue;
        }
        if(fork() == 0 && strcmp(input, "exit")) {
            errno = execvp(args[0], args);
            if(errno < 0) printf("%s: command not found!\n", args[0]);
            exit(1);
        } else wait(NULL);
    }

    return 0;
}

This is version 0.3 of it. I've been sharing this with other people on two private forums, but they haven't been so enthusiastic as I am about it so I figured putting it in a public spot such as this full of technical experts and enthusiast will get me better input.

I am terribly sorry I haven't commented it either, haha! I meant to do that starting from day 1, but I slacked off on that instead since it's so small.

Oh, feel free to distribute, modify, and all that nonsense. Don't forget to give me credit though. wink Also please, if you're taking an operating system class and you're suppose to make a shell, don't cheat yourself and the class by using this.

I am mostly making this just for kicks, but I am also giving it a lot of attention right now.

Anyhow, criticism, questions, and suggestion will be greatly appreciated.

Last edited by Aprz (2009-04-15 02:19:57)

Offline

#2 2009-04-15 07:35:17

lefallen
Member
From: Melbourne, Australia
Registered: 2006-07-06
Posts: 36
Website

Re: Aprz Shell

Cool.  It's amazing to see how simple a shell really is when you think about it smile  You'll need to put in some error checking etc (also don't use gets).  You'll want to add redirection at some point too.


JABBER: krayon -A-T- chat.qdnx.org
E-MAIL: archlinuxforums -A-T- quadronyx.org
WEB: http://www.qdnx.org/krayon/
~o~

Offline

#3 2009-04-15 08:10:55

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Aprz Shell

lefallen wrote:

Cool.  It's amazing to see how simple a shell really is when you think about it smile  You'll need to put in some error checking etc (also don't use gets).  You'll want to add redirection at some point too.

Try implementing (atleast) tab completion..then you should have your handful smile
No to mention this isn't a "complete" shell because it uses the already existing shell to run stuff..all execvp does is replace the process image with the running program..afaik the actual shell is still the one running things

Last edited by Wra!th (2009-04-15 08:17:08)


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#4 2009-04-15 09:18:54

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

It replaces the process, not use it to execute it.

Edit: By the way, I am using it as my main shell now on both my root and non-root user.

Edit: Renamed some variables to be more suitable. Replaced gets() with fgets() which is better. I wasn't thinking wink. Got signal handling so ctrl-c won't kill my shell.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char *args[128];
char input[128];
int argc;
int ret;

void sighandler(int signo) {
    write(1, "\r", 1);
}

int main(void) {
    signal(SIGINT, SIG_IGN);
    signal(SIGINT, sighandler);
    while(strcmp(input, "exit")) {
        argc = 1;
        do {
            printf("Aprz-0.3$ ");
            fgets(input, 128, stdin);
        } while(input[0] == '\0');
        input[strlen(input) - 1] = '\0';
        args[0] = strtok(input, " ");
        while((args[argc] = strtok(NULL, " ")) != NULL && ++argc);
        if(!strcmp(args[0], "cd")) {
            chdir(args[1]);
            continue;
        }
        if(!fork()) {
            ret = execvp(args[0], args);
            if(ret < 0 && strcmp(input, "exit")) printf("%s: command not found!\n", args[0]);
            exit(0);
        } else wait(NULL);
    }

    return 0;
}

I am happy with it so far. smile

Last edited by Aprz (2009-04-15 11:35:00)

Offline

#5 2009-04-15 13:58:55

Lexion
Member
Registered: 2008-03-23
Posts: 510

Re: Aprz Shell

So far, this is starting to seem like a really promising project.  It might be used as a template shell for beginning shell devs. 

It should be licensed (suggestion: gpl).


urxvtc / wmii / zsh / configs / onebluecat.net
Arch will not hold your hand

Offline

#6 2009-04-15 14:24:07

rson451
Member
From: Annapolis, MD USA
Registered: 2007-04-15
Posts: 1,233
Website

Re: Aprz Shell

We had to do this same type of project for a class when I was still in school.  We had about 2 weeks to do it and it had to do piping, redirection out and in, background processes, and run on both linux and minix.  It was actually a very fun project.  Unfortunately I lost the working source for mine due to another class I had at the time.  Have fun.


archlinux - please read this and this — twice — then ask questions.
--
http://rsontech.net | http://github.com/rson

Offline

#7 2009-04-16 12:35:10

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Heh, not so sure if it is a good template, but I guess all software, good or bad, should be free. wink

Edit: Current progress of Aprz-0.4. I actually took the seconds to annotate the code. I also added put putenv() so I wouldn't have to type /sbin/reboot and stuff like that. So you may want to edit it.

-code removed to keep post size small-

I hope by annotation the source code and putting envp() at line 48. This will make it easier to use and edit. I actually don't know how to pipe yet, but I am going to look at it soon. I hear it is easy.

Edit: Removed the code above with some very minor errors and posting it here. XD

/* Aprz Shell - an interactive prompt that execute commands
 *
 * Feel free to modify this however you wish, change it, redistribute it,
 * blah blah blah, just as long as you give me credit for starting
 * this mini project off. School childern shall not turn this in as
 * their homework assignment by the way (even though I doubt this is 
 * even considered near a C+ right. What do you guys give this? A D-
 * right now since there is no tab completion? :(
 *
 * If you notice any mistake in documentation in the source code, any
 * minor (or major) programming errors, have a suggestion, or anything
 * like that, feel free to notify me.
 *
 * Name is Andrew Przepioski.
 * E-mail: aprzepioski@hotmail.com
 *
 * ========================================================================
 * !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!!
 * =========================================================================
 * Did I get your attention now? Yes at line 48, you need to edit it
 * to fit you... I am just going to leave it as the default in
 * in the source code and it is up to you to edit it! It is your
 * PATH.
 *
 * THANKS
 *
 * Ventrue - Pointed out a few typos and grammatical errors.
 * Milo - Pointed out that PATH doesnt need ':' at the end of it.
 */

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* args        - my imitation of argv
 * input    - the user's input
 * argc        - my imitation of argc
 * ret        - return*/
char *args[128];
char input[128];
int argc;
int ret;

/* Isn't the name and what it is doing obvious enough?! Gosh... */
void sighandler(int signo) {
    write(1, "\r", 1);
}

int main(void) {
    /* Set PATH or else it would just be "/bin:/usr/bin:". */
    putenv("PATH=/bin:/usr/bin");

    /* If you're using firefox and have fancy things like flash,
     * you'll want this. */
    /*putenv("MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins:/opt/mozilla/lib/plugins");*/

    /* Disable ctrl-c. This also disabled ctrl-d and other guys,
     *  I'll work on that later since I am feeling lazy. */
    signal(SIGINT, SIG_IGN);
    signal(SIGINT, sighandler);

    /* Nice going Captain Obvious.. ;) Yes, this is the loop
     * that keeps Aprz Shell alive until the user enters exit. */
    while(strcmp(input, "exit")) {
        
        /* argc 0 would be the program name. */
        argc = 1;

        /* Print out a lovely prompt and let the user type
        * in junk. */
        do {
            printf("Aprz-0.4$ ");
            fgets(input, 128, stdin);
        } while(input[0] == '\0');

        /* Fix a minor detail with using fgets(). */
        input[strlen(input) - 1] = '\0';

        /* Parse/tokenize the user's input using space as
         * a delimiter. */
        args[0] = strtok(input, " ");
        while((args[argc] = strtok(NULL, " ")) != NULL && ++argc);

        /* Magically change directories. */
        if(!strcmp(args[0], "cd")) {
            chdir(args[1]);
            continue;
        }

        /* Initiate process and execute the user input. */
        if(!fork()) {
            ret = execvp(args[0], args);
            if(ret < 0 && strcmp(input, "exit")) printf("%s: command not found!\n", args[0]);
            exit(0);
        } else wait(NULL);
    }

    return 0;
}

Edit: Hm... I think I'll need to do something like #define to set PATH. Seems like a pain to scroll down to edit that and edit me saying where it is at ^ cause it's not in the right spot anymore.

Last edited by Aprz (2009-04-17 22:47:36)

Offline

#8 2009-06-08 09:49:00

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Hopefully double posting isn't a crime cause I think it would be even more of a crime to just let this die or to create a second post on the same subject. wink

I havn't made very much progress since I last posted this, but I have been experimenting with some header files such as dirent.h, regex.h, and termios.h.

#include <dirent.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Note: Using dirent.h for tab completion, but have not yet
 * implemented it. Necessary for struct dirent *dptr and DIR *dirp. */

#define MAX 128        /* Max input size. */

char *args[MAX];    /* Imitation of argv. */
char input[MAX];    /* User's final input. */
char ch;        /* Character used to build user's input. */
int argc;        /* Imitation of argc. */
int i;            /* Index for user's input. */
struct dirent *dptr;    /* Contents of directory. */
DIR *dirp;        /* The directory. */

/* Our signal handler. */
void sighandler(int signo) {
    write(1, "\r", 1);
}

int main(void) {
    /* Set PATH. By default, it is "/bin:/usr/bin". */
    putenv("PATH=/bin:/usr/bin");

    /* Disable ctrl-c and other signals. */
    signal(SIGINT, SIG_IGN);
    signal(SIGINT, sighandler);

    /* Loop until the user's input is "exit". */
    while(strcmp(input, "exit")) {
        /* Assuming the user types in a program name. */
        argc = 1;

        /* This is our prompt. */
        do {
            /* Start index at 0. */
            i = 0;

            /* Print the prompt. */
            printf("ash %% ");

            /* Get the user's input. */
            while((ch = getchar()) != '\n' && i < MAX) {
                input[i] = ch;
                ++i;
            }

            /* Append \0 to make the user's input a string. */
            input[i] = '\0';
        } while(input[0] == '\0');

        /* Tokenize the user's input. */
        args[0] = strtok(input, " ");
        while((args[argc] = strtok(NULL, " ")) != NULL && ++argc);

        /* Change directory if the first token is "cd". */
        if(!strcmp(args[0], "cd")) {
            chdir(args[1]);
            continue;
        }

        /* Initiate process and execute the user's input. */
        if(!fork()) {
            if(execvp(args[0], args) && strcmp(input, "exit")) printf("%s: command not found!\n", args[0]);
            exit(0);
        } else wait(NULL);
    }

    return 0;
}

I have not looked into GPLing this yet. I don't think there is any danger to this, haha, but I think I will eventually just incase when I get around to it. wink

I was playing around with dirent.h here pretty much making a duplicate of `ls' or `dir', but hopefully in my shell in the future for tab completion or regex and in a less pretty way (as in I am not going to be printing out guys, it's just gonna be so you can say /ho and hit tab to complete it or type in /ho* to complete it).

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>

struct dirent *dptr;
DIR *dirp;

int main(void) {
    if((dirp = opendir("/home/andrew")) == NULL) {
        printf("Error opening directory.");
        exit(1);
    }

    while(dptr = readdir(dirp)) {
        printf("%s\n", dptr->d_name);
    }

    close(dirp);

    return 0;
}

I didn't comment this. :[

^And to think that in Perl, this would just be <*>, lol. tongue

A friend setup an ftp server for bzr so I am gonna be using that. Maybe later I'll setup something git. He still has to add an anonymous account, but once that is up, it should be easy for you guys to get the most current stuff with my shell, make whatever edits, whatever. tongue

Last edited by Aprz (2009-06-08 10:03:55)

Offline

#9 2009-06-09 17:21:26

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: Aprz Shell

I really recommend hosting it on something like github. It's fantastic

Offline

#10 2009-06-10 09:24:56

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Well, I was considering bzr first because my friend really liked it. On IRC, folks told me that in long term, git is probably better. So I've pretty much learn how to use both git and bzr, not hard, but so far just done it with bzr. Maybe tonight I'll set it up with git. My friend hasn't told me if he created an anonymous account for his bzr server. He better. -.-

Edit: I'd like to announce that the anonymous account has been setup. To get my shell, just do:

% bzr checkout ftp://anonymous@koti.meelo.org/ash

Wow, that's a lot of typing, lol. I am probably going to turn it into a packman package and a simple tarball and make it available that way. I am about to go into detail on bzr (I've only read the 5 minute guide, haha). So I'll probably be playing around with it. Still haven't read about termios.h yet. :[

Last edited by Aprz (2009-06-10 11:39:29)

Offline

#11 2009-06-10 11:39:12

plurt
Member
Registered: 2008-10-16
Posts: 88

Re: Aprz Shell

do you plan on .aprzrc?


When everything's coming your way, you're in the wrong lane I say.
FAQ / Beginners Guide / The Arch Way

Offline

#12 2009-06-10 11:39:55

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Yes, I actually did get started on that for changing just the PATH, but that's not on my uploaded code yet. I played around it separately from the shell.

Last edited by Aprz (2009-06-10 11:40:18)

Offline

#13 2009-06-10 11:50:54

Ghost1227
Forum Fellow
From: Omaha, NE, USA
Registered: 2008-04-21
Posts: 1,422
Website

Re: Aprz Shell

Love it so far! Only one problem... the bzr command should be:

% bzr checkout ftp://anonymous@koti.meelo.org/aprz/ash

.:[My Blog] || [My GitHub]:.

Offline

#14 2009-06-10 11:51:53

Vintendo
Member
From: Netherlands
Registered: 2008-04-21
Posts: 375
Website

Re: Aprz Shell

Isn't it an idea to get the PATH out of /etc/profile? Nice shell though. Makes me wonder if I should make my own as well...

Offline

#15 2009-06-10 12:41:48

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Ghost1227 wrote:

Love it so far! Only one problem... the bzr command should be:

% bzr checkout ftp://anonymous@koti.meelo.org/aprz/ash

Haha, my bad, my bad. Good catch. wink

Edit: There appears to be a problem with the anonymous account though. It was working earlier, but now it fails. :[

Edit: Well, chit chatting with my friend and it seems that their is just a permission error with .bzr when using push on bzr so it looks like it'll be down for a little bit. He told me he'll get back when to me when it works.

Edit: Ha, I learn a new thing about bzr every second. wink Apparantly it would be better for you guys to do:

% bzr branch ftp://anonymous@koti.meelo.org/aprz/ash

So it doesn't try to commit to the main branch.

It's still down though.

Last edited by Aprz (2009-06-10 13:36:40)

Offline

#16 2009-06-10 17:01:28

Meelo
Member
From: Finland
Registered: 2009-06-10
Posts: 2
Website

Re: Aprz Shell

Now it should work again.

I'm now running a dedicated server, so in order to grab the snapshot run:

bzr branch bzr://koti.meelo.org/aprz/ash myBranch

Branch, because checkout is binded to the server, which is readonly to the public. smile

Ftp is used to commit changes, so that shall stay secret with Aprz.

But I realised, Aprz didn't actually upload his snapshot to my server before he went to sleep. So therefore this will only work as soon as Aprz uploads his project there and tells me about it, so I can chmod his files. There is currently a known bug with Bazaar + ftp, that creates the project with wrong permissions and that's what I've been fighting against today.

Offline

#17 2009-06-11 02:38:54

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

And everything should work now. wink I think Meelo meant:

% bzr branch bzr://anonymous@koti.meelo.org/aprz/ash myBranch

Or that's what I thought it was suppose to be, lol.

Offline

#18 2009-06-11 09:37:52

Meelo
Member
From: Finland
Registered: 2009-06-10
Posts: 2
Website

Re: Aprz Shell

Aprz wrote:

And everything should work now. wink I think Meelo meant:

% bzr branch bzr://anonymous@koti.meelo.org/aprz/ash myBranch

Or that's what I thought it was suppose to be, lol.

No, it uses dedicated 'bzr serve' which creates a bzr protocol, for which anonymous isn't anymore used. Anonymous is for ftp-access, so I meant what I said.

Offline

#19 2009-06-11 11:06:52

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Blah, you make me feel stupid. :[ I didn't even notice the bzr://. I just took what you had and made the changes for what it would be if it was ftp://.

Offline

#20 2009-06-12 12:23:50

oxeleo
Member
Registered: 2009-04-25
Posts: 5

Re: Aprz Shell

Hello.
Some time ago me with a friend had written a shell as a part for linux course. I developed it a little further, but right now i don't have time for it. Maybe you will find something useful in my code. I tried to comment it properly, but you know us lazy developers smile
The shell supports passing arguments to programs, redirection (>, >>, <), piping and running process in backgroud.
Ultra Stupid sHell

Offline

#21 2009-06-12 23:17:43

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Aprz Shell

oxeleo wrote:

Hello.
Some time ago me with a friend had written a shell as a part for linux course. I developed it a little further, but right now i don't have time for it. Maybe you will find something useful in my code. I tried to comment it properly, but you know us lazy developers smile
The shell supports passing arguments to programs, redirection (>, >>, <), piping and running process in backgroud.
Ultra Stupid sHell

That looks like an excellent resource there smile I'm sure others will agree, thank you for posting this

Offline

#22 2009-06-13 10:10:06

oxeleo
Member
Registered: 2009-04-25
Posts: 5

Re: Aprz Shell

HashBox wrote:

That looks like an excellent resource there smile I'm sure others will agree, thank you for posting this

Thanks big_smile
I forgot to mention it has also history, aliases, multiple commands per line (divided by ";"), testing files (is directory, is exists, is current user is owner, is readable by current user, is file size 0) and viewing current jobs.
It has some bugs and ugly workarounds, but time was limited wink Maybe I'll fix it later.

Offline

#23 2009-07-05 11:14:17

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Aprz Shell

Sounds very featureful, haha. I am still slacking. tongue About to write to write a credit card validator in assembly instead, haha. tongue

Last edited by Aprz (2009-07-05 11:20:10)

Offline

Board footer

Powered by FluxBB