Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
tp 1 - shell
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
sebastie.gendre
tp 1 - shell
Commits
68411d3e
Commit
68411d3e
authored
4 years ago
by
Sébastien Gendre
Browse files
Options
Downloads
Patches
Plain Diff
Start to implement the pipeline mechanism with a chained list of cmd_t
parent
5ab94051
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/command.c
+84
-11
84 additions, 11 deletions
src/command.c
src/command.h
+26
-7
26 additions, 7 deletions
src/command.h
src/shell.c
+5
-4
5 additions, 4 deletions
src/shell.c
with
115 additions
and
22 deletions
src/command.c
+
84
−
11
View file @
68411d3e
...
...
@@ -3,10 +3,22 @@
#include
"command.h"
in
t
command_from_str
(
char
*
str
,
cmd_t
*
cmd
)
{
cmd_
t
*
command_from_str
(
char
*
str
)
{
// Stor next command argument, used in the do…while loop
char
*
str_copy
=
malloc
((
strlen
(
str
)
+
1
)
*
sizeof
(
char
));
// Generate the command
cmd_t
*
cmd
=
malloc
(
sizeof
(
cmd_t
));
// Store next command argument, used in the do…while loop
char
*
next_arg
;
// Work with a copy of the given str
strcpy
(
str_copy
,
str
);
// If malloc didn't work
if
(
cmd
==
NULL
)
{
perror
(
"Malloc error for new command"
);
return
(
cmd_t
*
)
NULL
;
}
// Initialize a simple command (empty, simple, foreground)
cmd
->
type
=
JOB
;
...
...
@@ -19,10 +31,10 @@ int command_from_str(char *str, cmd_t *cmd) {
if
(
cmd
->
argc
==
0
)
{
// Extract the commmand name
next_arg
=
strtok
(
str
,
DELIMITERS
);
next_arg
=
strtok
(
str
_copy
,
ARGS_
DELIMITERS
);
}
else
{
// Get the next argument
next_arg
=
strtok
(
NULL
,
DELIMITERS
);
next_arg
=
strtok
(
NULL
,
ARGS_
DELIMITERS
);
}
// Extend the cmd->argv array with a new char pointer
...
...
@@ -47,22 +59,83 @@ int command_from_str(char *str, cmd_t *cmd) {
}
else
{
cmd
->
type
=
JOB
;
}
return
0
;
return
cmd
;
}
/* Parse a string to get a pipeline of commands */
cmd_t
*
command_pipeline_from_str
(
char
*
str
){
char
**
commands
=
NULL
;
char
*
next_command
=
NULL
;
int
commands_count
=
0
;
cmd_t
*
previous_command
=
NULL
;
cmd_t
*
first_command
=
NULL
;
// Cut str into a list of commands string
do
{
if
(
commands_count
==
0
)
{
// Extract the first command
next_command
=
strtok
(
str
,
COMMAND_PIPE_DELIMITER
);
}
else
{
// Get the next command
next_command
=
strtok
(
NULL
,
COMMAND_PIPE_DELIMITER
);
}
// Extend the command list to add a new command
commands
=
realloc
(
commands
,
(
commands_count
+
1
)
*
sizeof
(
char
*
));
if
(
commands
==
NULL
)
{
// In case the reallocation didn't work
die_errno
(
"parse_command::realloc"
);
}
// Store the next command
commands
[
commands_count
]
=
next_command
;
if
(
next_command
!=
NULL
)
{
// A now command has been added
commands_count
+=
1
;
}
}
while
(
next_command
!=
NULL
);
// For each command string, create a command struct
for
(
int
i
=
0
;
i
<
commands_count
;
++
i
)
{
if
(
previous_command
==
NULL
)
{
first_command
=
command_from_str
(
commands
[
i
]);
}
else
{
previous_command
->
next
=
command_from_str
(
commands
[
i
]);
}
}
return
first_command
;
}
// Dispose the commande
void
command_dispose
(
cmd_t
*
cmd
)
{
// Free all the command arguments str inside argv
for
(
int
i
=
0
;
i
<
cmd
->
argc
;
++
i
)
{
free
(
cmd
->
argv
[
i
]);
}
//
Then, finally, f
ree argv
/*
for (int i = 0; i < cmd->argc; ++i) {
*/
/*
free(cmd->argv[i]);
*/
/* } */
//
F
ree argv
free
(
cmd
->
argv
);
// Then, finally, free the command
free
(
cmd
);
}
/* Fee a pipeline of command from the given command */
void
command_free_pipeline
(
cmd_t
*
cmd
)
{
if
(
cmd
->
next
!=
NULL
)
{
command_free_pipeline
(
cmd
->
next
);
}
else
{
command_dispose
(
cmd
);
}
}
// Execute the commande
int
command_exec
(
cmd_t
*
cmd
)
{
int
command_
pipeline_
exec
(
cmd_t
*
cmd
)
{
switch
(
cmd
->
type
)
{
case
BUILTIN
:
{
return
builtin_exec_builtin_command
(
cmd
->
argc
,
cmd
->
argv
);
...
...
This diff is collapsed.
Click to expand it.
src/command.h
+
26
−
7
View file @
68411d3e
...
...
@@ -13,7 +13,8 @@
#include
"jobs.h"
// Chars used to separate atoms of a command
#define DELIMITERS " \t"
#define ARGS_DELIMITERS " \t"
#define COMMAND_PIPE_DELIMITER "|"
// Command types
enum
command_type
{
BUILTIN
,
JOB
,
PIZZA
};
...
...
@@ -21,22 +22,33 @@ enum command_type {BUILTIN, JOB, PIZZA};
// A full user command
typedef
struct
cmd
cmd_t
;
struct
cmd
{
enum
command_type
type
;
// Command type
enum
command_type
type
;
// Command type
char
**
argv
;
// The command arguments
int
argc
;
// Number of command arguments
bool
foreground
;
// Should the command be run in foreground or background (might not be relevant for your TP depending on TP version)
cmd_t
*
next
;
// Pointer to the next command, in case of pipe
};
/* Parse a
user input
to get
a
command
/* Parse a
string
to get
one
command
*
* Parameters
* -
user_input
: A string containing the full command. IT WILL BE MODIFIED BY THE FUNCTION.
* -
str
: A string containing the full command. IT WILL BE MODIFIED BY THE FUNCTION.
* - cmd: Command updated from user input string (i.e. command input). MUST BE DISPOSED SEE FUNCTION dispose_command
*
* Return:
*
-1
in case of error
otherwise 0.
*
A pointer to the new command, NULL
in case of error
*/
int
command_from_str
(
char
*
str
,
cmd_t
*
cmd
);
cmd_t
*
command_from_str
(
char
*
str
);
/* Parse a string to get a pipeline of commands
*
* Parameters
* - user_input: A string containing the full command. IT WILL BE MODIFIED BY THE FUNCTION.
*
* Return:
* The pointer to the first command, NULL in case of error
*/
cmd_t
*
command_pipeline_from_str
(
char
*
str
);
/* Dispose of the command, which free some allocated memory
...
...
@@ -47,6 +59,13 @@ int command_from_str(char *str, cmd_t *cmd);
*/
void
command_dispose
(
cmd_t
*
cmd
);
/* Fee a pipeline of command from the given command
*
* Parameters:
* - cmd: The command start command of the pipeline to free
*/
void
command_free_pipeline
(
cmd_t
*
cmd
);
/* Execute a given command as job or as builtin
*
* Parameters:
...
...
@@ -55,7 +74,7 @@ void command_dispose(cmd_t *cmd);
* Return:
* - The command return code, 0 is success
*/
int
command_exec
(
cmd_t
*
cmd
);
int
command_
pipeline_
exec
(
cmd_t
*
cmd
);
#endif
/* COMMAND_H */
This diff is collapsed.
Click to expand it.
src/shell.c
+
5
−
4
View file @
68411d3e
...
...
@@ -10,15 +10,16 @@
int
main
(
int
argc
,
char
*
argv
[])
{
char
*
user_input
;
cmd_t
command
;
char
*
user_input
;
cmd_t
*
command
_p
;
user_input
=
calloc
(
LIMIT_USER_INPUT_MAX_LENGTH
,
sizeof
(
char
));
while
(
1
){
interface_ask_user_input
(
user_input
);
command_from_str
(
user_input
,
&
command
);
command_exec
(
&
command
);
command_p
=
command_pipeline_from_str
(
user_input
);
command_pipeline_exec
(
command_p
);
command_free_pipeline
(
command_p
);
}
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment