📄 nofork.c
字号:
#ifdef __MSDOS__
#include <ctype.h>
#include <errno.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include "config.h"
#include "command.h"
#include "general.h"
#include "error.h"
#include "variables.h"
#include "subst.h"
#include "externs.h"
#include "builtins/common.h"
#include "dosutil.h"
#include "hashcmd.h"
#define SAVESTRING(p) ((p != NULL) ? savestring (p) : NULL)
#define FREE_AND_CLEAR(p) (free (p), p = NULL)
#define CURRENT_PID ((pid_t) 1)
pid_t dosutil_current_pid = CURRENT_PID;
int dosutil_wait_status = -1;
static void
save_jmp_buf (jmp_buf save, jmp_buf now)
{
memcpy ((char *) save, (char *) now, sizeof (jmp_buf));
}
static void
restore_jmp_buf (jmp_buf save, jmp_buf now)
{
memcpy ((char *) now, (char *) save, sizeof (jmp_buf));
}
extern jmp_buf top_level, subshell_top_level;
extern int interactive, interactive_shell, login_shell;
extern int subshell_environment;
extern int subshell_exit_builtin, exit_immediately_on_error;
extern int dollar_dollar_pid;
extern int array_needs_making;
extern char **temporary_env, **function_env, **builtin_env;
static void
save_current_directory (OLDENVBUF *envp)
{
envp->pwd = SAVESTRING (get_string_value ("PWD"));
#if 0
envp->oldpwd = SAVESTRING (get_string_value ("OLDPWD"));
#endif
envp->curdir = getcwd (NULL, PATH_MAX);
}
static void
restore_current_directory (OLDENVBUF *envp)
{
/* change old directory */
if (envp->curdir != NULL)
{
chdir (envp->curdir);
if (envp->pwd != NULL)
set_working_directory (envp->pwd);
else
set_working_directory (envp->curdir);
FREE_AND_CLEAR (envp->curdir);
}
else if (envp->pwd != NULL)
{
chdir (envp->pwd);
set_working_directory (envp->pwd);
}
#if 0
/* replace variables */
unbind_variable ("PWD");
if (envp->pwd)
{
bind_variable ("PWD", envp->pwd);
FREE_AND_CLEAR (envp->pwd);
}
unbind_variable ("OLDPWD");
if (envp->oldpwd)
{
bind_variable ("OLDPWD", envp->oldpwd);
FREE_AND_CLEAR (envp->oldpwd);
}
#else
if (envp->pwd)
FREE_AND_CLEAR (envp->pwd);
#endif
}
extern WORD_LIST *subst_assign_varlist;
static void
save_global_variables (OLDENVBUF *envp)
{
envp->interactive = interactive;
envp->interactive_shell = interactive_shell;
envp->login_shell = login_shell;
envp->subshell_environment = subshell_environment;
envp->subshell_exit_builtin = subshell_exit_builtin;
envp->exit_immediately_on_error = exit_immediately_on_error;
envp->variable_context = variable_context;
envp->dollar_dollar_pid = dollar_dollar_pid;
envp->subst_assign_varlist = subst_assign_varlist;
subst_assign_varlist = NULL;
}
static void
restore_global_variables (OLDENVBUF *envp)
{
interactive = envp->interactive;
interactive_shell = envp->interactive_shell;
login_shell = envp->login_shell;
subshell_environment = envp->subshell_environment;
subshell_exit_builtin = envp->subshell_exit_builtin;
exit_immediately_on_error = envp->exit_immediately_on_error;
variable_context = envp->variable_context;
dollar_dollar_pid = envp->dollar_dollar_pid;
subst_assign_varlist = envp->subst_assign_varlist;
}
static HASH_TABLE *
copy_shell_variables_hash_table (HASH_TABLE *table)
{
int i;
HASH_TABLE *new_table;
BUCKET_CONTENTS *new_item, *old_item;
SHELL_VAR *new_var, *old_var;
if (!table)
return (HASH_TABLE *) NULL;
new_table = make_hash_table (table->nbuckets);
new_table->nentries = table->nentries;
for (i = 0; i < table->nbuckets; i++)
{
old_item = table->bucket_array[i];
new_item = (BUCKET_CONTENTS *) NULL;
while (old_item)
{
if (new_item)
{
new_item->next = (BUCKET_CONTENTS *) xmalloc (sizeof (BUCKET_CONTENTS));
new_item = new_item->next;
}
else
{
new_table->bucket_array[i] =
(BUCKET_CONTENTS *) xmalloc (sizeof (BUCKET_CONTENTS));
new_item = new_table->bucket_array[i];
}
new_item->data = (char *) copy_variable ((SHELL_VAR *) old_item->data);
old_var = (SHELL_VAR *)old_item->data;
new_var = (SHELL_VAR *)new_item->data;
while (old_var->prev_context)
{
new_var->prev_context = copy_variable (old_var->prev_context);
new_var = new_var->prev_context;
old_var = old_var->prev_context;
}
new_item->next = (BUCKET_CONTENTS *)NULL;
new_item->key = SAVESTRING (old_item->key);
new_item->times_found = old_item->times_found;
old_item = old_item->next;
}
}
return new_table;
}
static void
dispose_shell_variables_hash_table (HASH_TABLE *table)
{
int i;
BUCKET_CONTENTS *item, *next;
SHELL_VAR *var, *prev;
if (!table)
return;
for (i = 0; i < table->nbuckets; i++)
{
item = table->bucket_array[i];
while (item)
{
var = (SHELL_VAR *) item->data;
while (var)
{
prev = var->prev_context;
dispose_variable (var);
var = prev;
}
if (item->key)
free (item->key);
next = item->next;
free (item);
item = next;
}
}
free (table->bucket_array);
free (table);
}
static void
save_shell_variables (OLDENVBUF *envp)
{
maybe_make_export_env ();
envp->shell_variables = shell_variables;
shell_variables = copy_shell_variables_hash_table (shell_variables);
envp->shell_functions = shell_functions;
shell_functions = copy_shell_variables_hash_table (shell_functions);
envp->temporary_env = temporary_env;
if (temporary_env != NULL)
temporary_env = copy_array (temporary_env);
envp->function_env = function_env;
if (function_env != NULL)
function_env = copy_array (function_env);
envp->builtin_env = builtin_env;
if (builtin_env != NULL)
builtin_env = copy_array (builtin_env);
#if 0
/* made by maybe_make_export_env () */
envp->export_env = export_env;
if (export_env != NULL)
export_env = copy_array (export_env);
#endif
envp->rest_of_args = list_rest_of_args ();
}
static void
restore_shell_variables (OLDENVBUF *envp)
{
dispose_shell_variables_hash_table (shell_variables);
shell_variables = envp->shell_variables;
dispose_shell_variables_hash_table (shell_functions);
shell_functions = envp->shell_functions;
free_array (temporary_env);
temporary_env = envp->temporary_env;
free_array (function_env);
function_env = envp->function_env;
free_array (builtin_env);
builtin_env = envp->builtin_env;
#if 0
/* made by maybe_make_export_env () */
free_array (export_env);
export_env = envp->export_env;
#endif
remember_args (envp->rest_of_args, 1);
array_needs_making = 1;
maybe_make_export_env ();
}
int
dosutil_save_all_environment (OLDENVBUF *envp)
{
save_jmp_buf (envp->top_level, top_level);
save_jmp_buf (envp->subshell_top_level, subshell_top_level);
dosutil_save_std_fds (envp->fds);
save_current_directory (envp);
save_global_variables (envp);
save_shell_variables (envp);
return 0;
}
int
dosutil_restore_all_environment (OLDENVBUF *envp)
{
restore_shell_variables (envp);
restore_global_variables (envp);
restore_current_directory (envp);
dosutil_restore_std_fds (envp->fds);
restore_jmp_buf (envp->top_level, top_level);
restore_jmp_buf (envp->subshell_top_level, subshell_top_level);
return 0;
}
#include <sys/param.h>
#if !defined (MAXPID)
#define MAXPID ((pid_t) 30000)
#endif
static pid_t last_pid = CURRENT_PID;
pid_t
dosutil_make_child_pid (void)
{
if (++last_pid > MAXPID)
last_pid = CURRENT_PID + 1;
return last_pid;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -