В вашем коде есть несколько fl aws:
char *lsl(){
char *stringts=malloc(1024);
chdir("/Users/file/path");
char * lsargs[] = { "/bin/ls" , "-l", NULL};
stringts="The result of ls-l in the created directory is:"+ execv(lsargs[0], lsargs);
return stringts;
}
- Если вы
malloc(3)
1024-байтовый буфер в указатель stringts
, но затем вы назначаете другое значение указатель, делающий ваш буфер потерянным в объеме вашей оперативной памяти. - Когда вы делаете вызов
execv(2)
, вся память вашего процесса освобождается ядром и перезагружается при выполнении команды ls -l
, вы получите вывод в стандартном выводе процесса, а затем получите подсказку оболочки. Это делает остальную часть вашей программы бесполезной, так как после того, как вы запустите c, пути назад уже нет, и ваша программа выгружена и освобождена. - Вы можете добавить (
+
) к значению указателя (вы действительно добавьте к адресу, указывающему на строку "The result of the ls -l..."
и --- в результате выполнения exe c - ничто, поскольку новая программа загружена - вы ничего не получите) Если execv
завершится неудачей, то вы получите указатель, указывающий на предыдущий символ этой строки, который является допустимым выражением в C, но заставляет вашу программу работать непредсказуемо в неопределенном поведении. Используйте strcpy(3)
, strcat(3)
или snprintf(3)
, в зависимости от того, какой именно текст вы хотите скопировать в пространство выделенного буфера. - Ваш
return
неверный адрес в результате. Проблема в том, что, если execv(2)
работает, он не возвращается. Только в случае неудачи вы получаете неверный указатель, который вы не можете использовать (по вышеуказанной причине), и, конечно, ls -l
не был выполнен. Ну, вы не говорите, что вы получили, как выход, так что мне трудно догадаться, действительно ли вы exec()
d программа или нет.
С другой стороны, у вас есть popen(3)
библиотечная функция, которая позволяет вам выполнять подпрограмму и позволяет вам читать из файлового дескриптора его вывод (я рекомендую вам не chdir
безвозмездно в вашей программе, так как это глобальное изменение в вашей программной среде, IMHO, это лучше передать ls(1)
каталог, который вы хотите перечислить в качестве параметра)
#include <stdio.h>
FILE *lsl() {
/* the call creates a FILE * descriptor that you can use as input and
* read the output of the ls command. It's bad resources use to try to
* read all in a string and return the string instead. Better read as
* much as you can/need and then pclose() the descriptor. */
return popen("/bin/ls -l /Users/file/path|", "rt");
}
и тогда вы сможете прочитать (так как это может быть очень длинный вывод, у вас, вероятно, нет достаточно буферного пространства для обработки все это в памяти, если у вас огромный каталог)
FILE *dir = lsl();
if (dir) {
char buffer[1024];
while (fgets(buffer, sizeof buffer, dir)) {
process_line_of_lsl(buffer);
}
pclose(dir); /* you have to use pclose(3) with popen(3) */
}
Если вы не хотите использовать popen(3)
, то вы не можете использовать execv(2)
в одиночку, и сначала вам нужно fork(2)
, создать новый процесс и exec()
в дочернем процессе (после монтирования перенаправления самостоятельно). Прочитайте хорошее введение в fork()
/ exec()
и как перенаправить ввод-вывод между fork()
и exec()
, так как здесь намного длиннее и подробнее, чтобы поместить его здесь (снова)