zoukankan      html  css  js  c++  java
  • 【转】关于C execlp函数的理解

    转自:http://bachue.is-programmer.com/posts/21611.html

    http://support.sas.com/documentation/onlinedoc/sasc/doc/lr2/execlp.htm

    execlp(从PATH 环境变量中查找文件并执行)

    相关函数
    fork,execl,execle,execv,execve,execvp
    表头文件 #include<unistd.h>
    定义函数 int execlp(const char * file,const char * arg,……);
    函数说明
    execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
    返回值
    如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
    错误代码
    参考execve()。
    范例
     /* 执行ls -al /etc/passwd execlp()会依PATH 变量中的/bin找到/bin/ls */
    #include<unistd.h>
    main()
    {
        execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
    }
    //执行
    //-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
    其实上面的描述很奇怪,如果能从PATH中找到第一个参数指定的文件,那何须第二个参数呢,没意义啊?

    然后Google了下,看到了www.lslnet.com/linux/f/docs1/i34/big5260214.htm中别人同样的质疑。

    这张帖子的楼主索性猜测:execlp函数在实际执行的时候根本没有用到第二个参数。

    说真的,这个猜测过于草率了。

    楼下有一张回帖给出了一个反例:execlp("ls","flw","-?",(char *)0)。

    应该是execlp("ls","flw","--help",(char *)0)吧,ls是Linux命令,-?是Windows的写法,不能同时运用,疑为他的笔误。这句语句在我电脑上的效果:

    Usage: flw [OPTION]... [FILE]...

    List information about the FILEs (the current directory by default).
    Sort entries alphabetically if none of -cftuvSUX nor --sort.
     
    自已在终端上永远试不出这个结果,因为明明调用的是ls命令,不可能显示出Usage: flw来。
    再仔细看看上面关于这个函数的描述“然后将第二个以后的参数当做该文件的argv[0]、argv[1]……”
    我猛然想到了以前说过main函数是可以传入参数的,我于是尝试了这样的代码:
     
    int main(int num_args,const char* args[])
    {
        for(int i=0;i<num_args;++i)
        {
            std::cout << args[i] << std::endl;
        }
            return 0;
    }
     
    在终端而不是IDE里运行这个程序,运行的时候给他带点参数,结果自己打的命令出现的在args[0]的位置,后面的参数出现在了 args[1],args[2],args[3]....的位置,可见C程序总会把你运行这个程序用的命令传入args[0]。这样这个问题就解开了。execlp第一个参数是让程序从PATH中找到指定程序运行,第二个参数将传入这个程序的args[0]。

    而execlp("ls","flw","--help",(char *)0)出现Usage: flw,是因为ls命令在显示帮助的时候会动用args[0], 这么设计很正常,因为如果用户打错了命令,总希望用最接近他命令的方式指导他怎么做才对,直接使用他的命令是最方便的。平时args[0]几乎总是等于 ls,这是因为ls在PATH中,没必要指示他的位置,但如果使用/bin/ls这样的命令,就可以看出来了。

    execlp -- Overlay Calling Process and Run New Program

    SYNOPSIS

     #include <unistd.h>
    
     int execlp(const char *path, const char *arg0, ..., NULL);
     

    DESCRIPTION

    Like all of the exec functions, execlp replaces the calling process image with a new process image. This has the effect of running a new program with the process ID of the calling process. Note that a new process is not started; the new process image simply overlays the original process image. The execlp function is most commonly used to overlay a process image that has been created by a call to the fork function.

    path
    identifies the location of the new process image within the hierarchical file system (HFS). If the path argument contains a slash (/), it is assumed that either an absolute or a relative pathname has been specified. If the path argument does not contain a slash, the directories specified by the PATH environment variable are searched in an attempt to locate the file.
    arg0, ..., NULL
    is a variable length list of arguments that are passed to the new process image. Each argument is specified as a null-terminated string, and the list must end with a NULL pointer. The first argument, arg0, is required and must contain the name of the executable file for the new process image. If the new process image is a normal SAS/C main program, the list of arguments will be passed to argv as a pointer to an array of strings. The number of strings in the array is passed to the main() function as argc.

    ARG_MAX specifies the maximum number of bytes, including the NULL terminator at the end of the string, that can be passed as arguments to the new process image. The value of ARG_MAX is obtained by calling the sysconf function with the _SC_ARG_MAX symbol.

    RETURN VALUE

    A successful call to execlp does not have a return value because the new process image overlays the calling process image. However, a -1 is returned if the call to execlp is unsuccessful.

    EXAMPLE

    The following example illustrates creating a new process and executing an HFS file called newShell. The path /u/userid/bin is added at the end of the PATH environment variable before calling execlp.

    Note: You must specify the posix option when compiling this example.

      #include <unistd.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
    
      main()
      {
         pid_t pid;
         char *pathvar;
         char newpath[1000];
    
         pathvar = getenv("PATH");
         strcpy(newpath, pathvar);
         strcat(newpath, ":u/userid/bin");
         setenv("PATH", newpath);
    
         if ((pid = fork()) == -1)
            perror("fork error");
         else if (pid == 0) {
            execlp("newShell", "newShell", NULL);
            printf("Return not expected. Must be an execlp error.n");
         }
      }

    RELATED FUNCTIONS

    execl, execvp

  • 相关阅读:
    力扣(LeetCode) 14. 最长公共前缀
    力扣(LeetCode)965. 单值二叉树
    力扣(LeetCode)258. 各位相加
    力扣(LeetCode)389. 找不同
    PTA 阶乘之和取模
    A. Sea Battle
    PTA 二叉树路径
    PTA 重构二叉树
    PTA 笛卡尔树
    绿豆蛙的归宿
  • 原文地址:https://www.cnblogs.com/fzzl/p/2859104.html
Copyright © 2011-2022 走看看