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

📄 sflprocx.h

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 H
📖 第 1 页 / 共 2 页
字号:
/*  ----------------------------------------------------------------<Prolog>-
    Name:       sflprocx.h
    Title:      Process control functions - extra functions
    Package:    Standard Function Library (SFL)

    Written:    1996/09/09  iMatix SFL project team <sfl@imatix.com>
    Revised:    1999/03/22

    Copyright:  Copyright (c) 1996-2000 iMatix Corporation
    License:    This is free software; you can redistribute it and/or modify
                it under the terms of the SFL License Agreement as provided
                in the file LICENSE.TXT.  This software is distributed in
                the hope that it will be useful, but without any warranty.
 ------------------------------------------------------------------</Prolog>-*/


/*  -------------------------------------------------------------------------
 *  This header file defines static variables and functions that may be used
 *  in the sflproc implementations.  We don't define function prototypes -
 *  this file must be included before the process_create_full() function
 *  definition.
 *  -------------------------------------------------------------------------*/

/*  Define default and system-specific values.
 *  The default_ext table lists extensions for all files that we can run
 *  directly; the runnable_ext table lists extensions that are directly
 *  runnable.  The script_ext table lists extensions that must be passed to
 *  a shell for execution.
 */
#if   (defined (__OS2__))
static const char *default_ext  [] = { "exe", "cmd", NULL };
static const char *runnable_ext [] = { "exe", NULL };
static const char *script_ext   [] = { "cmd", NULL };
static const char *default_shell   = "COMSPEC";
static const char *shell_run       = "/c";
#elif (defined (WIN32))
static const char *default_ext  [] = { "exe", "com", "bat", NULL };
static const char *runnable_ext [] = { "exe", "com", "bat", NULL };
static const char *script_ext   [] = { NULL };
static const char *default_shell   = "COMSPEC";
static const char *shell_run       = "/c";
#else
static const char *default_ext  [] = { NULL };
static const char *runnable_ext [] = { NULL };
static const char *script_ext   [] = { NULL };
static const char *default_shell   = "SHELL";
static const char *shell_run       = "-c";
#endif


/*  We use linked lists to create the command line with arguments            */

typedef struct _ARGLIST {
    struct _ARGLIST
        *next, *prev;
    char *value;
} ARGLIST;

#define LIST_BEFORE     0               /*  Flags for arglist calls          */
#define LIST_AFTER      1


/*  --------------------------------------------------------------------------
 *  arglist_add -- local
 *
 *  Creates a new ARGLIST node with a copy of the specified string, and adds
 *  it to the end or start of the specified argument list.
 */
 
static void
arglist_add (ARGLIST *list, int where, const char *value)
{
    /*  NOTE: There _must_not_ be a cast of the "value" parameter in the     */
    /*  macro calls list_queue or list_push, because it does not expand      */
    /*  correctly with gcc 2.7.x.  For this reason a local variable of the   */
    /*  required type is used to hold a pointer to the copy of the string.   */

    void *item = mem_strdup (value);    /*  Allocate a copy of the string    */
    
    if (where == LIST_AFTER)
        list_queue (((LIST *) list), item);
    else
        list_push  (((LIST *) list), item);
}


/*  --------------------------------------------------------------------------
 *  arglist_add_table -- local
 *
 *  Adds a token list specified to an arglist, at the start or end.  The token
 *  list is an array of char pointers, ending in a NULL pointer.  Does nothing
 *  if the token list is null.
 */
 
static void
arglist_add_table (ARGLIST *list, int where, char **tokens)
{
    int
        token_nbr;
        
    if (tokens)
      {
        for (token_nbr = 0; tokens [token_nbr]; token_nbr++)
            if (where == LIST_AFTER)
                arglist_add (list, LIST_AFTER, tokens [token_nbr]);
        if (where == LIST_BEFORE)
            for (--token_nbr; token_nbr >= 0; token_nbr--)
                arglist_add (list, LIST_BEFORE, tokens [token_nbr]);
      }
}

/*  --------------------------------------------------------------------------
 *  arglist_add_string -- local
 *
 *  Appends a string of zero or more terms onto an arglist.  Each word in the
 *  string is attached as a single node in the argument list.
 */
 
static void
arglist_add_string (ARGLIST *list, int where, const char *string)
{
    char
        **tokens;

    tokens = tok_split (string);
    arglist_add_table (list, where, tokens);
    tok_free (tokens);
}

/*  --------------------------------------------------------------------------
 *  arglist_remove_first -- local
 *
 *  Removes the first node from the argument list, assuming there is an item
 *  there.
 */
 
static void
arglist_remove_first (ARGLIST *list)
{
    ARGLIST 
        *next = list->next;

    list_unlink (next);
    mem_strfree (&next-> value);
    mem_free (next);
}

/*  --------------------------------------------------------------------------
 *  arglist_free -- local
 *
 *  Frees all memory used by the specified argument list, including the list
 *  head.  All items on the list including the head must be ARGLIST nodes.
 *  (The unix code simply leaves the process which allocates the memory,
 *  so does not call this function.)
 */

#if (! defined (__UNIX__))
static void
arglist_free (ARGLIST *list)
{
    ARGLIST
        *next;

    while (list-> next != list)
      {
        next = list-> next;
        list_unlink (next);
        mem_strfree (&next-> value);
        mem_free (next);
      }
    mem_free (list);
}
#endif

/*  --------------------------------------------------------------------------
 *  arglist_value -- local
 *
 *  Returns a string consisting of the concatenation of the argument list
 *  values, separated by spaces.  The returned string is provided in a freshly
 *  allocated buffer.  Returns NULL if there was insufficient memory.
 */

#if ((! defined (__UNIX__)) && (! defined (__OS2__)))
static char *
arglist_value (ARGLIST *list)
{
    ARGLIST
        *node;                          /*  Each node in the list            */
    int
        value_size;                     /*  Total size of value              */
    char
        *value;                         /*  Full concatenated value          */

    value_size = 0;
    for (node = list-> next; node != list; node = node-> next)
        if (node-> value)               /*  Count size of value + space      */
            value_size += strlen (node-> value) + 1;

    value = mem_alloc (value_size + 1);
    if (value)
      {
        /*  Append each value; null values will not be followed by a space   */
        value [0] = '\0';
        for (node = list-> next; node != list; node = node-> next)
            xstrcat (value, node-> value, " ", NULL);
        strcrop (value);                /*  Drop trailing space(s)           */
      }
    return (value);
}
#endif

/*  --------------------------------------------------------------------------
 *  arglist_to_table -- local
 *
 *  Returns a argv style array of strings which can be used as arguments
 *  to exec*(), or spawn*() (under unix and OS/2 respectively).  The 
 *  array of strings is in freshly allocated memory, but the the strings
 *  themselves are simply the ones in the arglist directly.  Take care
 *  not to free them prematurely, or twice, but ensure that the array is
 *  freed.  Returns NULL if there was insufficient memory.
 */

#if (defined (__UNIX__) || defined (__OS2__))
static char **
arglist_to_table (ARGLIST *list)
{
    ARGLIST
        *node;                          /*  Each node in the list            */
    int
        length = 0;                     /*  Length of arglist                */
    char **
        array = NULL;

    /*  Figure out number of items in the list                               */
    for (node = list-> next; node != list; node = node-> next)
         ++length;

    array = mem_alloc ((length + 1) * sizeof (char *));
    if (array)
      {
        for (node = list-> next, length = 0; 
             node != list; 
             node = node-> next, ++length)

             array [length] = node-> value;

        array [length] = NULL;

        return array;
      }
    else
        return NULL;
}
#endif


/*  --------------------------------------------------------------------------
 *  merge_environment -- local
 *
 *  Creates a new environment variable bundle which contains the entries from
 *  curenv, with the entries from envadd put in (overwriting any existing
 *  entries of that name), and the entries for the keys in envrm removed.
 *
 *  curenv may be NULL, in which case the processes current environment is
 *  used.  If envadd or envrm are NULL then no change is made for that part.
 *
 *  Returns the new environment variable bundle, or NULL if errors encountered.
 *
 *  When the environment is no longer required it should be freed with
 *  strtfree().
 *
 *  NOTE: strt2symb() is used to convert the environment to a symbol table,
 *  rather than env2symb(), so no conversions are applied to the strings.
 *  The environment should be "ready to go" prior to using this function.
 */

static char **
merge_environment (char **cur_env, SYMTAB *envadd, SYMTAB *envrm)
{
    int
        rc = 0;
    SYMTAB
        *envtable = NULL;
    char
        **new_env = NULL,
        **base_env;
    SYMBOL
        *symbol,                        /*  Next symbol in table             */
        *symbol_found;                  /*  Symbol to remove from table      */

    base_env = cur_env? cur_env: environ;
    ASSERT (base_env);
    if (!base_env)
        return NULL;

    ASSERT (envadd || envrm);     /*  Should be doing some translation       */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -