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

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -