⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sflprocx.h

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 H
📖 第 1 页 / 共 2 页
字号:

    /*  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 + -