📄 sflprocx.h
字号:
/* If no changes are required, just return copy of base environment */
if (!envadd && !envrm)
return (env_copy (base_env));
envtable = strt2symb (cur_env);
if (envtable == NULL)
return (NULL);
if (envadd)
{
rc = sym_merge_tables (envtable, envadd);
ASSERT (rc > 0); /* 0 = nothing imported; +ve okay */
if (rc < 0) /* -ve means error during import */
{
sym_delete_table (envtable);
return (NULL);
}
}
if (envrm)
{
/* To remove the symbols we process the whole envrm table, */
/* removing symbols from the main table */
for (symbol = envrm-> symbols; symbol; symbol = symbol-> next)
{
symbol_found = sym_lookup_symbol (envtable, symbol-> name);
while (symbol_found)
symbol_found = sym_delete_symbol (envtable, symbol_found);
}
}
/* Now turn the symbol table back into a set of environment variables */
new_env = symb2env (envtable);
/* Free up the symbol table, and exit. */
sym_delete_table (envtable);
return (new_env);
}
/* --------------------------------------------------------------------------
* redirect_via_interpreter -- local
*
* If the specified file is an executable script, extracts the name of the
* script interpreter plus arguments from the first line of the file, plus
* the full name of the script file to be executed, and returns this string
* in a static buffer. If the specified file is not an executable script,
* or is not found, returns NULL.
*
* Searches for the file on the path if necessary and searchpath is TRUE.
* The first line of the file should contain "#! interpreter" or "/ *!
* interpreter" (without the space), and under OS/2, accepts a line starting
* with "EXTPROC".
*
* Handles an interpreter name like '/usr/bin/perl' as follows: if the
* full filename exists, returns that. Else strips off the leading path
* and looks for the program name on the PATH. If that exists, returns
* just the program name (plus any arguments), else returns NULL.
*
* If the file does not contain a magic line, but has an extension listed in
* the script_ext table, returns the name of the shell plus options.
*
* To allow filenames with spaces, the specified filename should have been
* passed through process_escape() before calling this function.
*
* We implement this function on all OSes, so that features like the "/ *!"
* (without the space) invocation for ReXX scripts are portable. Note that
* under Unix, the test 'file_is_program()' should be done before calling
* this function, and so take care of normal executable scripts.
*/
static char *
redirect_via_interpreter (
char *filename, /* Name of file we want to execute */
Bool searchpath, /* Search on path? */
const char *suppliedpath, /* If so, what path symbol */
const char **searchext, /* Executable extensions to use */
const char *shell) /* Shell to use for script_ext's */
{
static char
curline [LINE_MAX + 1]; /* First line from file */
const char
*path, /* Path to search along */
**extensions; /* Extensions to try on command */
char
*full_filename, /* Filename with path */
*arguments, /* Program arguments if any */
*shell_command = NULL, /* Name of shell interpreter */
*extension; /* File extension */
FILE
*stream = NULL; /* File input stream */
Bool
redirected = FALSE; /* Did we redirect the filename? */
int
ext_index; /* Index into script_ext table */
ASSERT (filename);
if (!filename)
return (NULL);
extensions = searchext? searchext: default_ext;
if (searchpath == FALSE)
path = NULL;
else
path = suppliedpath? suppliedpath: "PATH";
if (strlen (filename) > LINE_MAX)
return (NULL); /* Filename is too long for us */
process_unesc (curline, filename); /* Unescape any spaces in filename */
/* We look for the file on the path, if searchpath is true. We first
* try the filename just as we got it, possibly without any extensions,
* and then if that didn't work, we try our default extensions (and
* optionally mandatory extensions).
*/
full_filename = file_where_ext ('r', path, curline, NULL);
if (!full_filename)
full_filename = file_where_ext ('r', path, curline, extensions);
/* Quick exit if we did not find the file on the path as specified */
if (!full_filename)
return (NULL);
/* Save full filename, since it's in a static buffer in sflfile */
full_filename = mem_strdup (full_filename);
redirected = FALSE;
/* Open the file, and look for an interpreter name */
stream = fopen (full_filename, "r");
if (stream)
{
if (file_read (stream, curline))
{
strconvch (curline, '\\', '/');
if (memcmp (curline, "#!", 2) == 0)
{
redirected = TRUE;
shell_command = curline + 2;
}
else
if (memcmp (curline, "/*!", 3) == 0)
{
/* Remove closing OS/2 style comment if present */
char
*close_comments = strstr (curline, "*/");
if (close_comments)
*close_comments = '\0';
redirected = TRUE;
shell_command = curline + 3;
}
# if (defined (__OS2__))
/* Look for EXTPROC line in both capitals and lower case.
* NOTE: If the EXTPROC line happens to specify a command
* processor that understands EXTPROC lines then if it is
* poorly written (eg 4OS/2) it may attempt to run itself
* over the script repeatedly until running out of memory.
*/
else
if (lexncmp (curline, "EXTPROC", 7) == 0)
{
redirected = TRUE;
shell_command = curline + 7;
}
# endif
}
file_close (stream);
}
if (redirected)
{
/* Skip spaces and pick-up the interpreter name */
strcrop (curline);
while (*shell_command == ' ')
shell_command++;
/* Separate shell name from arguments, if any */
arguments = strchr (shell_command, ' ');
if (arguments)
*arguments = '\0';
/* If shell name is not empty, find full executable filename */
if (strnull (shell_command))
redirected = FALSE; /* Empty line - can't redirect */
}
if (redirected)
{
/* Now check we can find shell as specified or on path */
if (!file_is_program (shell_command))
{
/* Strip leading path and search on PATH */
shell_command = strrchr (shell_command, '/');
if (shell_command && !file_is_program (++shell_command))
redirected = FALSE;
}
}
if (redirected)
{
/* Shell name is still just before arguments; we put the space back
* to turn this into a nice string again.
*/
if (arguments)
*arguments = ' ';
}
else
{
/* Now, check if filename matches the script_ext table */
if (full_filename)
extension = strrchr (full_filename, '.');
else
extension = strrchr (filename, '.');
if (extension == NULL
|| strchr (extension, '/') /* Last '.' is part of path */
|| strchr (extension, '\\')) /* => filename has no ext */
extension = NULL;
shell_command = NULL; /* Nothing executable found */
if (extension)
{
extension++; /* Bump past dot */
for (ext_index = 0; script_ext [ext_index]; ext_index++)
if (lexcmp (extension, script_ext [ext_index]) == 0)
{
xstrcpy (curline, shell, " ", shell_run, NULL);
shell_command = curline;
break;
}
}
}
/* If we found the interpreter, append the translated full filename */
/* onto the end of the string, to use to replace the existing one. */
if (shell_command && full_filename)
xstrcat (shell_command, " ", full_filename, NULL);
mem_strfree (&full_filename);
return (shell_command);
}
/* --------------------------------------------------------------------------
* restore_redirection -- local
*
* If the file handles for old_stdin, old_stdout, old_stderr, are zero or
* greater then duplicate those file handles over stdin, stdout, stderr
* respectively, and close the old file handles. Each of the file handles
* is considered seperately.
* This function is used to restore the file handles after IO redirection.
*/
static void
restore_redirection (int old_stdin, int old_stdout, int old_stderr)
{
file_fhrestore (old_stdin, STDIN_FILENO);
file_fhrestore (old_stdout, STDOUT_FILENO);
file_fhrestore (old_stderr, STDERR_FILENO);
}
#if (defined (__VMS__))
/* --------------------------------------------------------------------------
* translate_to_vms -- local
*
* Translates POSIX style filename /top/path2/path2/filename into OpenVMS
* style filename top:[path1.path2]filename, which is always the same size.
* Does nothing if the filename is not valid, i.e. with at least a top,
* one path component, and a filename.
*/
static void
translate_to_vms (char *filename)
{
char
*path_start,
*path_end;
/* Filename must start with '/' */
if (*filename != '/')
return;
/* Find start and end of file path */
path_start = strchr (filename + 1, '/');
path_end = strrchr (filename, '/');
if (path_start == NULL || path_start == path_end)
return; /* Badly-formed filename */
path_start--;
memmove (filename, filename + 1, path_start - filename);
*path_start++ = ':';
*path_start++ = '[';
*path_end = '\0'; /* Cut string before filename */
strconvch (path_start, '/', '.'); /* and replace slashes by dots */
*path_end = ']'; /* Finally, add ']' after path */
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -