簡體   English   中英

c unix execl無法與使用strcat構建的字符串一起使用

[英]c unix execl not working with string built with strcat

我正在嘗試使用通過命令行參數構建的路徑名運行execl。 它不起作用,所以我對連接的字符串進行了硬編碼,因此它仍然不起作用。 如果我提供一個char * path =“ some path name”並將其傳遞給execl,則它可以正常工作。

#include <stdio.h>

int main(int argc,char *argv[]){
//set char path name
 char pathname[256];
 strcat(pathname,"/bin/");
 strcat(pathname,"ls"); //"ls" will be replaced with arg[1]
 int pid=fork();
  if (pid==0){
     execl(pathname,"ls",(char *)0);
  }
  else{
  wait((int*)0);
  }
return 0;
}

我已經打印出路徑名,以確保它是“ / bin / ls”。

問題在這里:

char pathname[256];
strcat(pathname,"/bin/");

您沒有初始化pathname 因此,它的內容是“不確定的”,對strcat的調用具有正式稱為“未定義行為”的含義-允許其執行任何操作 可能發生的具體情況是,在分配給pathname的內存空間中有一些二進制垃圾, strcat將其視為字符串,因此兩次strcat調用后pathname的內容都類似於(十六進制)

01 02 03 2f 62 69 63 2f 6c 73 00

當您打印出字符串時,那些前導控制字符是不可見的,但是當您調用execl ,內核欣然接受了執行名為"\\001\\002\\003/bin/ls" (相對於當前工作目錄)的文件的請求。 ,當然),並且由於沒有這樣的文件,因此失敗並將errnoENOENT execl和使用./a.out 2>&1 | cat -v調用的程序之后立即使用perror(pathname) ./a.out 2>&1 | cat -v ./a.out 2>&1 | cat -v您會看到類似

^A^B^C/bin/ls: No such file or directory

將第一個strcat更改為strcpy可以解決此問題,因為strcpy總是復制到其目標緩沖區的開頭,而忽略了之前的內容。 完成后,直到第一個NUL(包括第一個NUL)的buf字節都將確定,並且strcat具有明確定義的行為...

...但是,如果您將程序改回從argv[1]讀取/bin/之后要復制的內容,並且第一個命令行參數的長度超過250個字節,砰,那么您將再次遇到未定義的行為。 編寫此程序的更好方法是使用asprintf

int main(int argc, char **argv)
{
    if (argc != 2) {
        fprintf(stderr, "usage: %s program\n", argv[0]);
        return 2;
    }
    char *pathname;
    if (asprintf(&pathname, "/bin/%s", argv[1]) == -1) {
        perror("asprintf");
        return 1;
    }

    execl(pathname, argv[1], (char *)0);
    perror(pathname);
    return 127;
}

(如果沒有asprintf則可以直接使用snprintfmalloc進行滾動。如果沒有snprintf可以使用一台真正的計算機。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM