程序代写代做 Hive C html * 3000shell.c */

* 3000shell.c */
/* v2 Sept. 15, 2019 */
/* v1 Sept. 24, 2017 */
/* based off of csimpleshell.c, Enrico Franchi 2005
https://web.archive.org/web/20170223203852/
http://rik0.altervista.org/snippets/csimpleshell.html */
/* Original under “BSD” license */
/* This version is under GPLv3, copyright 2017, 2019 Anil Somayaji */
/* You really shouldn’t be incorporating parts of this in any other code,
it is meant for teaching, not production */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define BUFFER_SIZE 1<<16 #define ARR_SIZE 1<<16 #define COMM_SIZE 32 const char *proc_prefix = "/proc"; void parse_args(char *buffer, char** args, size_t args_size, size_t *nargs) { char *buf_args[args_size]; /* You need C99 */ char **cp, *wbuf; size_t i, j; wbuf=buffer; buf_args[0]=buffer; args[0] =buffer; for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){ if ((*cp != NULL) && (++cp >= &buf_args[args_size]))
break;
}

for (j=i=0; buf_args[i]!=NULL; i++){
if (strlen(buf_args[i]) > 0)
args[j++]=buf_args[i];
}

*nargs=j;
args[j]=NULL;
}

/* this is kind of like getenv() */
char *find_env(char *envvar, char *notfound, char *envp[])
{
const int MAXPATTERN = 128;
int i, p;
char c;
char pattern[MAXPATTERN];
char *value = NULL;

p = 0;
while ((c = envvar[p])) {
pattern[p] = c;
p++;
if (p == (MAXPATTERN – 2)) {
break;
}
}
pattern[p] = ‘=’;
p++;
pattern[p] = ‘\0’;

i = 0;
while (envp[i] != NULL) {
if (strncmp(pattern, envp[i], p) == 0) {
value = envp[i] + p;
}
i++;
}

if (value == NULL) {
return notfound;
} else {
return value;
}
}

void find_binary(char *name, char *path, char *fn, int fn_size) {
char *n, *p;
int r, stat_return;

struct stat file_status;

if (name[0] == ‘.’ || name[0] == ‘/’) {
strncpy(fn, name, fn_size);
return;
}

p = path;
while (*p != ‘\0’) {
r = 0;
while (*p != ‘\0’ && *p != ‘:’ && r < fn_size - 1) { fn[r] = *p; r++; p++; } fn[r] = '/'; r++; n = name; while (*n != '\0' && r < fn_size) { fn[r] = *n; n++; r++; } fn[r] = '\0'; stat_return = stat(fn, &file_status); if (stat_return == 0) { return; } if (*p != '\0') { p++; } } } void setup_comm_fn(char *pidstr, char *comm_fn) { char *c; strcpy(comm_fn, proc_prefix); c = comm_fn + strlen(comm_fn); *c = '/'; c++; strcpy(c, pidstr); c = c + strlen(pidstr); strcpy(c, "/comm"); } void plist() { DIR *proc; struct dirent *e; int result; char comm[COMM_SIZE]; /* seems to just need 16 */ char comm_fn[512]; int fd, i, n; proc = opendir(proc_prefix); if (proc == NULL) { fprintf(stderr, "ERROR: Couldn't open /proc.\n"); } for (e = readdir(proc); e != NULL; e = readdir(proc)) { if (isdigit(e->d_name[0])) {
setup_comm_fn(e->d_name, comm_fn);
fd = open(comm_fn, O_RDONLY);
if (fd > -1) {
n = read(fd, comm, COMM_SIZE);
close(fd);
for (i=0; i < n; i++) { if (comm[i] == '\n') { comm[i] = '\0'; break; } } printf("%s: %s\n", e->d_name, comm);
} else {
printf(“%s\n”, e->d_name);
}
}
}

result = closedir(proc);
if (result) {
fprintf(stderr, “ERROR: Couldn’t close /proc.\n”);
}
}

void signal_handler(int the_signal)
{
int pid, status;

if (the_signal == SIGHUP) {
fprintf(stderr, “Received SIGHUP.\n”);
return;
}

if (the_signal != SIGCHLD) {
fprintf(stderr, “Child handler called for signal %d?!\n”,
the_signal);
return;
}

pid = wait(&status);

if (pid == -1) {
/* nothing to wait for */
return;
}

if (WIFEXITED(status)) {
fprintf(stderr, “\nProcess %d exited with status %d.\n”,
pid, WEXITSTATUS(status));
} else {
fprintf(stderr, “\nProcess %d aborted.\n”, pid);
}
}

void run_program(char *args[], int background, char *stdout_fn,
char *path, char *envp[])
{
pid_t pid;
int fd, *ret_status = NULL;
char bin_fn[BUFFER_SIZE];

pid = fork();
if (pid) {
if (background) {
fprintf(stderr,
“Process %d running in the background.\n”,
pid);
} else {
pid = wait(ret_status);
}
} else {
find_binary(args[0], path, bin_fn, BUFFER_SIZE);

if (stdout_fn != NULL) {
fd = creat(stdout_fn, 0666);
dup2(fd, 1);
close(fd);
}

if (execve(bin_fn, args, envp)) {
puts(strerror(errno));
exit(127);
}
}
}

void prompt_loop(char *username, char *path, char *envp[])
{
char buffer[BUFFER_SIZE];
char *args[ARR_SIZE];

int background;
size_t nargs;
char *s;
int i, j;
char *stdout_fn;

while(1){
printf(“%s $ “, username);
s = fgets(buffer, BUFFER_SIZE, stdin);

if (s == NULL) {
/* we reached EOF */
printf(“\n”);
exit(0);
}

parse_args(buffer, args, ARR_SIZE, &nargs);

if (nargs==0) continue;

if (!strcmp(args[0], “exit”)) {
exit(0);
}

if (!strcmp(args[0], “plist”)) {
plist();
continue;
}

background = 0;
if (strcmp(args[nargs-1], “&”) == 0) {
background = 1;
nargs–;
args[nargs] = NULL;
}

stdout_fn = NULL;
for (i = 1; i < nargs; i++) { if (args[i][0] == '>‘) {
stdout_fn = args[i];
stdout_fn++;
printf(“Set stdout to %s\n”, stdout_fn);
for (j = i; j < nargs - 1; j++) { args[j] = args[j+1]; } nargs--; args[nargs] = NULL; break; } } run_program(args, background, stdout_fn, path, envp); } } int main(int argc, char *argv[], char *envp[]) { struct sigaction signal_handler_struct; char *username; char *default_username = "UNKNOWN"; char *path; char *default_path = "/usr/bin:/bin"; memset (&signal_handler_struct, 0, sizeof(signal_handler_struct)); signal_handler_struct.sa_handler = signal_handler; signal_handler_struct.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &signal_handler_struct, NULL)) { fprintf(stderr, "Couldn't register SIGCHLD handler.\n"); } if (sigaction(SIGHUP, &signal_handler_struct, NULL)) { fprintf(stderr, "Couldn't register SIGHUP handler.\n"); } username = find_env("USER", default_username, envp); path = find_env("PATH", default_path, envp); prompt_loop(username, path, envp); return 0; }