Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CS503
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
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
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
Vanshika Mohan Bongade
CS503
Commits
b0467730
Commit
b0467730
authored
2 months ago
by
Vanshika Mohan Bongade
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
5541df10
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
WEEK-7/dshlib.c
+240
-0
240 additions, 0 deletions
WEEK-7/dshlib.c
with
240 additions
and
0 deletions
WEEK-7/dshlib.c
0 → 100644
+
240
−
0
View file @
b0467730
#include
<stdlib.h>
#include
<stdio.h>
#include
<string.h>
#include
<ctype.h>
#include
<stdbool.h>
#include
<unistd.h>
#include
<fcntl.h>
#include
<sys/wait.h>
#include
"dshlib.h"
int
exec_local_cmd_loop
()
{
char
cmd_buff
[
SH_CMD_MAX
];
command_list_t
clist
;
while
(
1
)
{
// Suppress prompt during testing
if
(
isatty
(
STDIN_FILENO
))
{
printf
(
"%s"
,
SH_PROMPT
);
}
// Read user input
if
(
fgets
(
cmd_buff
,
SH_CMD_MAX
,
stdin
)
==
NULL
)
{
printf
(
"
\n
"
);
break
;
// Exit if EOF is reached
}
// Remove trailing newline character
cmd_buff
[
strcspn
(
cmd_buff
,
"
\n
"
)]
=
'\0'
;
// Ignore empty input
if
(
strlen
(
cmd_buff
)
==
0
)
{
continue
;
}
// Exit command
if
(
strcmp
(
cmd_buff
,
EXIT_CMD
)
==
0
)
{
printf
(
"exiting...
\n
"
);
return
OK_EXIT
;
}
// Parse the command into a list
int
parse_status
=
build_cmd_list
(
cmd_buff
,
&
clist
);
// Error handling for parsing
if
(
parse_status
<
0
)
{
continue
;
}
// Execute the parsed commands
execute_pipeline
(
&
clist
);
// Free allocated memory
free_cmd_list
(
&
clist
);
}
return
OK
;
}
/**
* Parses the command buffer into a list of commands for execution, handling redirection.
*/
int
build_cmd_list
(
char
*
cmd_line
,
command_list_t
*
clist
)
{
char
*
token
;
int
i
=
0
;
// Initialize command list
clist
->
num
=
0
;
// Tokenize input based on pipes (|)
token
=
strtok
(
cmd_line
,
"|"
);
while
(
token
!=
NULL
)
{
// Trim leading spaces
while
(
*
token
==
' '
)
token
++
;
char
*
cmd_part
=
strtok
(
token
,
" "
);
int
j
=
0
;
clist
->
commands
[
i
].
infile
=
NULL
;
clist
->
commands
[
i
].
outfile
=
NULL
;
clist
->
commands
[
i
].
append
=
false
;
while
(
cmd_part
!=
NULL
)
{
if
(
strcmp
(
cmd_part
,
"<"
)
==
0
)
{
cmd_part
=
strtok
(
NULL
,
" "
);
if
(
cmd_part
)
{
clist
->
commands
[
i
].
infile
=
strdup
(
cmd_part
);
}
}
else
if
(
strcmp
(
cmd_part
,
">"
)
==
0
)
{
cmd_part
=
strtok
(
NULL
,
" "
);
if
(
cmd_part
)
{
clist
->
commands
[
i
].
outfile
=
strdup
(
cmd_part
);
clist
->
commands
[
i
].
append
=
false
;
}
}
else
if
(
strcmp
(
cmd_part
,
">>"
)
==
0
)
{
cmd_part
=
strtok
(
NULL
,
" "
);
if
(
cmd_part
)
{
clist
->
commands
[
i
].
outfile
=
strdup
(
cmd_part
);
clist
->
commands
[
i
].
append
=
true
;
}
}
else
{
clist
->
commands
[
i
].
argv
[
j
++
]
=
cmd_part
;
}
cmd_part
=
strtok
(
NULL
,
" "
);
}
clist
->
commands
[
i
].
argv
[
j
]
=
NULL
;
// Null-terminate argument list
clist
->
num
++
;
// Increment command count
token
=
strtok
(
NULL
,
"|"
);
// Get next command
i
++
;
if
(
i
>=
CMD_MAX
)
{
fprintf
(
stderr
,
CMD_ERR_PIPE_LIMIT
,
CMD_MAX
);
return
ERR_TOO_MANY_COMMANDS
;
}
}
return
OK
;
}
/**
* Executes commands using pipes and handles input/output redirection.
*/
int
execute_pipeline
(
command_list_t
*
clist
)
{
int
num_cmds
=
clist
->
num
;
int
pipes
[
num_cmds
-
1
][
2
];
// Pipes for communication between commands
pid_t
pids
[
num_cmds
];
// Array to store process IDs
for
(
int
i
=
0
;
i
<
num_cmds
;
i
++
)
{
// Create pipes except for the last command
if
(
i
<
num_cmds
-
1
)
{
if
(
pipe
(
pipes
[
i
])
==
-
1
)
{
perror
(
"pipe"
);
return
ERR_MEMORY
;
}
}
// Fork a child process
pids
[
i
]
=
fork
();
if
(
pids
[
i
]
<
0
)
{
perror
(
"fork"
);
return
ERR_MEMORY
;
}
if
(
pids
[
i
]
==
0
)
{
// Child process
// Handle input redirection
if
(
clist
->
commands
[
i
].
infile
)
{
int
fd
=
open
(
clist
->
commands
[
i
].
infile
,
O_RDONLY
);
if
(
fd
<
0
)
{
perror
(
"open infile"
);
exit
(
ERR_EXEC_CMD
);
}
dup2
(
fd
,
STDIN_FILENO
);
close
(
fd
);
}
// Handle output redirection ONLY for the last command
if
(
i
==
num_cmds
-
1
&&
clist
->
commands
[
i
].
outfile
)
{
int
fd
;
if
(
clist
->
commands
[
i
].
append
)
{
fd
=
open
(
clist
->
commands
[
i
].
outfile
,
O_WRONLY
|
O_CREAT
|
O_APPEND
,
0644
);
}
else
{
fd
=
open
(
clist
->
commands
[
i
].
outfile
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0644
);
}
if
(
fd
<
0
)
{
perror
(
"open outfile"
);
exit
(
ERR_EXEC_CMD
);
}
dup2
(
fd
,
STDOUT_FILENO
);
close
(
fd
);
}
// Redirect input/output for pipes
if
(
i
>
0
)
{
dup2
(
pipes
[
i
-
1
][
0
],
STDIN_FILENO
);
}
if
(
i
<
num_cmds
-
1
)
{
dup2
(
pipes
[
i
][
1
],
STDOUT_FILENO
);
}
// Close all pipes
for
(
int
j
=
0
;
j
<
num_cmds
-
1
;
j
++
)
{
close
(
pipes
[
j
][
0
]);
close
(
pipes
[
j
][
1
]);
}
// **Fix: Ensure echo does not add extra quotes**
if
(
strcmp
(
clist
->
commands
[
i
].
argv
[
0
],
"echo"
)
==
0
)
{
for
(
int
j
=
1
;
clist
->
commands
[
i
].
argv
[
j
]
!=
NULL
;
j
++
)
{
printf
(
"%s"
,
clist
->
commands
[
i
].
argv
[
j
]);
if
(
clist
->
commands
[
i
].
argv
[
j
+
1
]
!=
NULL
)
{
printf
(
" "
);
// Ensure words are properly spaced
}
}
printf
(
"
\n
"
);
// Print newline at the end
fflush
(
stdout
);
exit
(
0
);
}
execvp
(
clist
->
commands
[
i
].
argv
[
0
],
clist
->
commands
[
i
].
argv
);
// Print error message before exiting
fprintf
(
stderr
,
"error: command not found: %s
\n
"
,
clist
->
commands
[
i
].
argv
[
0
]);
fflush
(
stderr
);
exit
(
ERR_EXEC_CMD
);
}
}
// Close all pipes in parent process
for
(
int
i
=
0
;
i
<
num_cmds
-
1
;
i
++
)
{
close
(
pipes
[
i
][
0
]);
close
(
pipes
[
i
][
1
]);
}
// Wait for all child processes to finish
for
(
int
i
=
0
;
i
<
num_cmds
;
i
++
)
{
waitpid
(
pids
[
i
],
NULL
,
0
);
}
return
OK
;
}
/**
* Frees allocated memory for command list.
*/
int
free_cmd_list
(
command_list_t
*
cmd_lst
)
{
for
(
int
i
=
0
;
i
<
cmd_lst
->
num
;
i
++
)
{
if
(
cmd_lst
->
commands
[
i
].
infile
)
{
free
(
cmd_lst
->
commands
[
i
].
infile
);
cmd_lst
->
commands
[
i
].
infile
=
NULL
;
}
if
(
cmd_lst
->
commands
[
i
].
outfile
)
{
free
(
cmd_lst
->
commands
[
i
].
outfile
);
cmd_lst
->
commands
[
i
].
outfile
=
NULL
;
}
}
// Reset the command list
cmd_lst
->
num
=
0
;
return
OK
;
}
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