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

📄 sflproc.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
    out           Std_out filename, or NULL
    err           Std_err filename, or NULL
    preserveroot  True if we're running as root now
    </Table>
    Returns 0 if the PROC_INFO block was correctly initialised; returns -1 if
    there was an error opening one of the i/o streams.  Before calling this
    function you should have declared the PROC_INFO block using the syntax:
    PROCESS_DATA myproc = PROCESS_DATA_INIT;
    ---------------------------------------------------------------------[>]-*/

int
process_setinfo (
    PROCESS_DATA *procinfo,
    const char *std_in,                 /*  Stdin device, or NULL            */
    const char *std_out,                /*  Stdout device, or NULL           */
    Bool  scratch_out,                  /*  Scratch stdout file?             */
    const char *std_err,                /*  Stderr device, or NULL           */
    Bool  scratch_err                   /*  Scratch stderr file?             */
)                       
{
    const char
        *spacepos,
        *slashpos;
    char
        stdout_mode,
        stderr_mode;

    /*  Figure out if it is permissable to search the path                   */
    /*  It's permissable if the filename to be run doesn't contain a slash   */
    /*  of its own already.                                                  */
    procinfo-> searchpath = FALSE;
    if (procinfo-> filename)
      {
        spacepos = strchr (procinfo-> filename, ' ');
        if (spacepos == NULL)
            spacepos = procinfo-> filename + strlen (procinfo-> filename);
        slashpos = strchr (procinfo-> filename, '/');
#if (defined (MSDOS_FILESYSTEM))
        if (!slashpos)
            slashpos = strchr (procinfo-> filename, '\\');
#endif        
        if (slashpos == NULL || slashpos > spacepos)
            procinfo-> searchpath = TRUE;
      }
    /*  Figure out if root privilege should be retained.  If the real user   */
    /*  is root and effective user is root, then we retain root privilege    */
    /*  for the executed program.  Otherwise we want to discard it (default) */
    procinfo-> preserveroot = FALSE;
#if (defined (__UNIX__))
    if (getuid () == 0 && geteuid () == 0)
        procinfo-> preserveroot = TRUE;
#endif

    /*  Open the i/o streams if requested.  Note that process_set_io
     *  returns NULL_HANDLE if the supplied filename is null or empty.
     */
    stdout_mode = scratch_out? 'w': 'a';
    stderr_mode = scratch_err? 'w': 'a';
    procinfo-> in  = process_open_io (std_in,  'r');
    procinfo-> out = process_open_io (std_out, stdout_mode);
    procinfo-> err = process_open_io (std_err, stderr_mode);
    if (procinfo-> in  == -1
    ||  procinfo-> out == -1
    ||  procinfo-> err == -1)
      {
        process_close_io (procinfo);
        return (-1);
      }
    else
        return (0);
}


/*  ---------------------------------------------------------------------[<]-
    Function: process_open_io

    Synopsis: Opens a file for i/o and returns a handle ready for passing to
    process_create_full().  The filename may be null or empty, in which case
    this function returns -2, which indicates a null file handle.  If there is
    an error, it returns -1.  Otherwise it returns a file handle >= 0.
    ---------------------------------------------------------------------[>]-*/

int
process_open_io (
    const char *filename,
    char access_type                    /*  r, w, a                          */
)
{
    int
        handle,
        mode = 0,
        permissions = 0;

    if (filename == NULL || *filename == '\0')
        return (-2);                    /*  Indicates a null handle          */
        
#if (defined (__UNIX__) || defined (__OS2__))
    mode = O_NOCTTY;
#endif
    if (access_type == 'r')
      {
        mode += O_RDONLY;
        permissions = 0;
      }
    else
    if (access_type == 'w')
      {
        mode += O_WRONLY | O_CREAT | O_TRUNC;
        permissions = S_IREAD | S_IWRITE;
      }
    else
    if (access_type == 'a')
      {
        mode += O_WRONLY | O_CREAT | O_APPEND;
        permissions = S_IREAD | S_IWRITE;
      }
    handle = open (filename, mode, permissions);
#if (defined (WIN32))
    /*  Under Windows, we need to move the file pointer to the end of the
     *  file ourselves, for append files, since for some reason this does
     *  not happen automatically for file handles passed to subprocesses.
     */
    if (access_type == 'a')
        lseek (handle, 0, SEEK_END);
#endif

#if (defined (DEBUG))
    if (handle < 0)
        perror ("Error opening redirection stream");
#endif
    return (handle);
}


/*  ---------------------------------------------------------------------[<]-
    Function: process_close_io

    Synopsis: Closes any file handles opened for the process.  Use this
    function after you're finished with a process_create_full() call.
    ---------------------------------------------------------------------[>]-*/

void
process_close_io (PROCESS_DATA *procinfo)
{
    if (procinfo-> in >= 0)
      {
        close (procinfo-> in);
        procinfo-> in = NULL_HANDLE;
      }
    if (procinfo-> out >= 0)
      {
        close (procinfo-> out);
        procinfo-> out = NULL_HANDLE;
      }
    if (procinfo-> err >= 0)
      {
        close (procinfo-> err);
        procinfo-> err = NULL_HANDLE;
      }
}


/*  ---------------------------------------------------------------------[<]-
    Function: process_status

    Synopsis: Returns status of process specified by process ID.  Returns
    one of these values, or -1 if there was an error:
    <Table>
    PROCESS_RUNNING       Process is still running.
    PROCESS_ENDED_OK      Process ended normally.
    PROCESS_ENDED_ERROR   Process ended with an error status.
    PROCESS_INTERRUPTED   Process was interrupted (killed).
    </Table>
    In the case of PROCESS_ENDED_ERROR, the global variable process_errno is
    set to the exit code returned by the process.
    ---------------------------------------------------------------------[>]-*/

int
process_status (
    PROCESS process)
{
#if (defined (__UNIX__) || defined (__OS2__))
    int
        status;
    pid_t
        return_pid;

    /*  waitpid() returns 0 if the child process is still running, or the    */
    /*  process id if it stopped.  It can also return -1 in case of error.   */
    /*  No other return value is possible.                                   */

    return_pid = waitpid (process, &status, WNOHANG | WUNTRACED);
    if (return_pid == 0)
        return (PROCESS_RUNNING);
    else
    if (return_pid == process)
      {
        if (WIFEXITED (status))        /*  Program called exit()             */
          {
            process_errno = WEXITSTATUS (status);
            if (process_errno)         /*  Treat exit (0) as normal end      */
                return (PROCESS_ENDED_ERROR);
            else
                return (PROCESS_ENDED_OK);
          }
        else
        if (WIFSIGNALED (status))       /*  Process was interrupted          */
            return (PROCESS_INTERRUPTED);
        else
            return (PROCESS_ENDED_OK);
      }
    else
        return (-1);

#elif (defined (WIN32))
    DWORD
         status;

    ASSERT (process);
    status = WaitForSingleObject (process-> process, 0);

    if (status == WAIT_TIMEOUT)
        return (PROCESS_RUNNING);
    else
    if (status == WAIT_OBJECT_0)
        return (PROCESS_ENDED_OK);
    else
    if (status == WAIT_ABANDONED)
        return (PROCESS_ENDED_ERROR);
    else
        return (-1);

#elif (defined (__VMS__))
    ASSERT (process);
    if (process-> status == 0)
        return (PROCESS_RUNNING);
    else
        return (PROCESS_ENDED_OK);

#else
    return (-1);                        /*  Not supported on this system     */
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: process_kill

    Synopsis: Ends a process specified by a process id.  The current process
    must have the appropriate authority to stop the specified process.
    Returns zero if the process was killed, -1 if there was an error.
    ---------------------------------------------------------------------[>]-*/

int
process_kill (
    PROCESS process)
{
#if (defined (__UNIX__) || defined (__OS2__))
    int count = 5;

    ASSERT (process);

    /*  First give it a chance to gracefully exit...                         */
    kill (process, SIGTERM);
    while (process_status (process) == PROCESS_RUNNING && count--)
        sleep (1);

    /*  Then get brutal if neccessary.                                       */
    if (process_status (process) == PROCESS_RUNNING)
      {
        kill (process, SIGKILL);
        while (process_status (process) == PROCESS_RUNNING)
            sleep (1);
      }
    return (0);

#elif (defined (WIN32))
    ASSERT (process);

    TerminateProcess (process-> process, 1);
    while (process_status (process) == PROCESS_RUNNING)
        Sleep (100);

    process_close (process);
    return (0);

#elif (defined (__VMS__))
    ASSERT (process);

    sys$delprc (process-> id);
    process_close (process);
    return (0);

#else
    return (-1);                        /*  Not supported on this system     */
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: process_close

    Synopsis: You should call this function when a process has ended
    normally, if you did not specify the wait option when calling the
    process_create() function.  On some systems, each created process
    uses some memory.  process_close() guarantees that this memory is
    correctly freed.  Does nothing if the process handle is NULL.
    ---------------------------------------------------------------------[>]-*/

void
process_close (
    PROCESS process)
{
#if (defined (WIN32))
    if (process)
      {
        mem_free (process-> envd);
        mem_free (process);
      }
#elif (defined (__VMS__))
    mem_free (process);
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: process_server

    Synopsis: Converts the process from an interactive foreground process
    into a background process.  Depending on the system either the existing
    process becomes a background process, or a new process is started as
    a background process and the existing process terminates.
    
    Requires the original command-line arguments as passed to the main()
    function.  If a new process is started, any arguments that match any
    of the values in the (NULL terminated) 'sswitch' array will be omitted
    from the arguments to the new process.  You should specify the
    command-line switch(es) your main program uses to run as a background
    service.   If it returns, returns 0 if okay, and returns -1 if there
    was an error.

    The precise effect of this function depends on the system.  On UNIX,
    does this:
    <LIST>
    Switches the process to run as a background job, under init;
    closes all open files;
    moves to a safe, known working directory, if required;
    sets the umask for new files;
    opens stdin, stdout, and stderr to the null device;
    enforces exclusive execution through a lock file, if required;
    logs the process id in the lock file;
    ignores the hangup unwanted signals.
    </LIST>
    On OS/2, starts a new copy of the program up, detached, and running
    separately from the current process, and if successful, the existing
    process exits.

    On other systems does nothing except return 0.

⌨️ 快捷键说明

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