[英]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"
(相對於當前工作目錄)的文件的請求。 ,當然),並且由於沒有這樣的文件,因此失敗並將errno
為ENOENT
。 在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
則可以直接使用snprintf
和malloc
進行滾動。如果沒有snprintf
可以使用一台真正的計算機。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.