c unix execl not working with string built with strcat -
i trying run execl pathname built command line arguments. not working hardcoded strings being concatenated still did not work. if supply char *path = "some path name" , pass execl, works correctly.
#include <stdio.h> int main(int argc,char *argv[]){ //set char path name char pathname[256]; strcat(pathname,"/bin/"); strcat(pathname,"ls"); //"ls" replaced arg[1] int pid=fork(); if (pid==0){ execl(pathname,"ls",(char *)0); } else{ wait((int*)0); } return 0; }
i've printed out pathname make sure "/bin/ls" is.
the problem here:
char pathname[256]; strcat(pathname,"/bin/");
you did not initialize pathname
. therefore, contents "indeterminate" , call strcat
has officially known undefined behavior -- allowed literally anything. concrete thing happened was, there binary garbage in memory space allocated pathname
, , strcat
cheerfully treated string, contents of pathname
after both strcat
calls (hexadecimal)
01 02 03 2f 62 69 63 2f 6c 73 00
when printed out string, leading control characters not visible, when called execl
kernel cheerfully accepted request execute file named "\001\002\003/bin/ls"
(relative current working directory, of course), , since there no such file, failed , set errno
enoent
. perror(pathname)
after execl
, program invoked ./a.out 2>&1 | cat -v
have seen like
^a^b^c/bin/ls: no such file or directory
changing first strcat
strcpy
corrects problem because strcpy
copies beginning of destination buffer, ignoring whatever there beforehand; once that's done, bytes of buf
, including first nul determinate , strcat
has well-defined behavior ...
... however, if change program reading thing copy after /bin/
argv[1]
, , first command-line argument more 250 bytes long, bang, have undefined behavior again. better way write program using 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; }
(if don't have asprintf
straightforward roll using snprintf
, malloc
. if don't have snprintf
real computer.)
Comments
Post a Comment