HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

mini-(Docker)-shell

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
dockershellmini

Problem

I was given an assignment to write a mini-shell:


To write your own shell, you will need to start with a C program that
will prompt the user for input and accept in a number of arguments
from a command line. The commands entered will be accepted into your
shell and then processed to understand if it is a built in command or
something that needs to be executed via fork/exec (NOTE: No use of
system function). Your shell should emulate the standard shells in
how it deals with background commands ( & ). The interaction with your
shell should be just like the standard shells. What I mean by this is
to have a good usage statement returned if the arguments passed to the
shell are not correct, and when there is an error you should send back
a useful error, and not exit the shell, just continue.


Namespaces allow for virtualization and sharing of spaces between
parent and child processes. This is a part of the Linux operating
system since 2008 that allows for the creation of different models to
create containers for software applications. The most popular version
of Linux namespaces is Docker. Your task for this lab
is to create the option inside your shell through “built in” commands
to move your shell into a container. The options for different
containers can be added together in a clone or clone2 call. Here
are some of the options:



  • CLONE_NEWIPC - New namespace for IPC



  • CLONE_NEWUTS - Setup new hostname and domain



  • CLONE_NEWUSER - User and group changes



  • CLONE_NEWNET - New network namespace



  • CLONE_NEWNS - New mount namespace





When using a clone function, you will have the ability to run
another function. To test your clone call, you will need to be able
to demonstrate the change, and the best way to do that is to spawn
another shell to “look around” at what changed. The best way to do
this is to spawn another shell using the system function call.

Here is my

Solution

-
Background task handling

You must wait for the child process regardless of how it is started, in the background or not. As written, a background command ends up in the zombie state. To let the parent shell to continue, set up a signal handler for SIGCHLD, and wait there.

I know the program statement doesn't require it, but it always nice to let user query a return status of last command.

-
command("sh")

It is unclear from the program statement, which shell should be cloned. In any case, it is highly recommended to supply a full path to system.

-
freeCmd

cmd->params = NULL and cmd = NULL are meaningless: cmd = NULL is invisible to caller, and caller shall not touch params of a freed cmd anyway.

-
parseCmd

The code recognizes & anywhere within a command line as a background indicator. It doesn't feel right for many reasons: compatibility with existing shells; & could be valid character in a filename; etc. I recommend to test for a last argument being & after parsing is done, and adjust the command appropriately.

-
Built-in commands

Is clone the only built-in? If so, your shell is at least unable to cd.

-
Misc

-
You may want to fflush(stdout) after printing the prompt.

-
Test what malloc returns.

-
It is unclear whether the command line may have quotes and escapes. They are obviously not addressed.

Edit: handling background termination

In a nutshell it seems is fairly simple: define a function

void handle_child_exit(int signo)
{
    int status;
    wait(&status);
    signal(SIGCHLD, handle_child_exit); // Not always required, but helpful
}


and in install it in main:

signal(SIGCHLD, handle_child_exit);


The reality is a bit hairier, and I can only recommend reading man signal and man sigaction.

Code Snippets

void handle_child_exit(int signo)
{
    int status;
    wait(&status);
    signal(SIGCHLD, handle_child_exit); // Not always required, but helpful
}
signal(SIGCHLD, handle_child_exit);

Context

StackExchange Code Review Q#143729, answer score: 4

Revisions (0)

No revisions yet.