我已经开发了这个功能:
bool execc(char *cmd, char *r)
{
FILE *fp;
char t1[1024];
char *t2;
memset(r, 0, sizeof(r));
fp = popen(cmd, "r");
if (fp == NULL)
{
return false;
}
t1 = r;
while (fgets(t1, sizeof(t1), fp) != NULL)
{
r = &r[strlen(r)];
memcpy(r, t1, strlen(t1));
}
r = t2;
r[strlen(r)] = '\0';
pclose(fp);
return true;
}
int main()
{
char r[4096];
int i = 51;
execc("ls -l /", r);
printf("result of cmd: \n %s", r);
return 0;
}
当我执行这个程序时,我得到了一些奇怪的字符,如下所示:
result of command:
total xxx
drwxr-xr-x 7 1001 root 4096 août 25 16:06 xxx
drwxr-xr-x 3 root root 4096 juin 30 11:45 xxx
drwxr-xr-x 2 root root 12288 oct. 9 15:26 bin
drwxr-xr-x 3 root root 1024 août 28 11:48 boot
drwxr-xr-x 3 root root 4096 août 26 10:51 boot-files
drwxrwxr-x 2 root root 4096 janv. 12 2015 cdrom
drwxr-xr-x 7 xxxx xxxx 4096 juil. 14 16:43 data
drwxr-xr-x 20 root root 4640 oct. 20 15:06 dev
drwxr-xr-x 174 root root 12288 oct. 9 17:43 etc
drwxr-xr-x 5 root root 4096 sept. 28 17:19 home
lrwxrwxrwx 1 root root 33 août 26 10:50 initrd.img -> boot/initrd.img-xxxx-generic
lrwxrwxrwx 1 root root 33 août 26 10:49 initrd.img.old -> boot/initrd.img-xxxx-generic
drwxr-xr-x 27 root root 4096 avril 28 16:08 lib
drwxr-xr-x 2 root root 4096 mai 7 17:35 lib32
drwxr-xr-x 2 root root 4096 avril 28 15:33 lib64
drwx------ 2 root root 16384 janv. 12 2015 lost+found
drwxr-xr-x 3 root root 4096 janv. 16 2015 media
drwxr-xr-x 2 root root 4096 oct. 16 2014 mnt
drwxr-xr-x 7 root root 4096 août 24 13:18 opt
dr-xr-xr-x 299 root root 0 oct. 19 08:54 proc
drwx------ 10 root root 4096 oct. 5 18:03 root
drwxr-xr-x 27 root root 940 oct. 20 14:38 run
drwxr-xr-x 2 root root 12288 août 13 09:57 sbin
h�rwxr-xr-x 2 root root 4096 oct. 22 2014 srv
dr-xr-xr-x 13 root root 0 oct. 20 14:34 sys
drwxrwxrwx 2 nobody xxxx 4096 oct. 12 12:08 tftpboot
drwxrwxrwt 19 root root 20480 oct. 20 15:30 tmp
drwxr-xr-x 12 root root 4096 août 27 10:24 usr
drwxr-xr-x 14 root root 4096 avril 7 2015 var
lrwxrwxrwx 1 root root 30 août 26 10:46 vmlinuz -> boot/vmlinuz-xxxx-generic
3B�lrwxrwxrwx 1 root root 30 août 13 10:01 vmlinuz.old -> boot/vmlinuz-xxxx-generic
如何解决此错误?我找不到问题
答案 0 :(得分:4)
该行
memcpy(r, t1, strlen(t1));
正在复制t1
而终止\0
。所以这一行:
r[strlen(r)] = '\0';
无效,因为strlen(r)
不会返回正确的值,因为r
未正确终止。
如果r
区域用零填充到整个操作范围,可以工作。但它不是
memset(r, 0, sizeof(r));
将无法正常工作。 sizeof(r)
只是一个指针大小,大概是几个字节。
答案 1 :(得分:1)
sizeof(r)
返回指针的大小,最简单的空r
方法是将main更改为...
char r[4096] = ""; /* initialize to '\0' */
代码应该可以读取读取的数据量,而不是缓冲区的溢出量。
memcpy(r, t1, strlen(t1));
r = &r[strlen(t1)]; /* walk by amount added */
代码似乎搞砸了。
t1 = r; /* << == doesn't compile */
r = t2;
会创建未定义的行为,因为永远不会分配t2
。
r = t2;
r[strlen(r)] = '\0';
尝试循环。
memcpy(r, t1, strlen(t1));
r = &r[strlen(t1)]; /* walk by amount added */
r[0] = '\0'; /* terminate the string */
一般来说,如果你获得超过4k的数据,就会发生不好的事情。
bool execc(char *cmd, char *r)
{
FILE *fp;
char t1[1024];
fp = popen(cmd, "r");
if (fp == NULL)
{
return false;
}
while (fgets(t1, sizeof(t1), fp) != NULL)
{
memcpy(r, t1, strlen(t1));
r = &r[strlen(t1)]; /* walk by amount added */
r[0] = '\0'; /* terminate the string */
}
pclose(fp);
return true;
}
答案 2 :(得分:1)
获得超过4k的数据我做了这个大修改:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
bool execc(char *cmd, char **value)
{
FILE *fp;
char buffer[128];
char *tmp;
int size;
fp = popen(cmd, "r");
if (fp == NULL)
{
return false;
}
while (size = fread (buffer,1,sizeof(buffer),fp))
{
buffer[size] = '\0';
if(*value == NULL)
{
*value = strdup(buffer);
}
else
{
tmp = *value;
*value = (char*)calloc(strlen(tmp)+strlen(buffer), sizeof(char));
memcpy(*value, tmp, strlen(tmp));
memcpy(*value+strlen(tmp), buffer, strlen(buffer));
free(tmp);
}
}
pclose(fp);
return true;
}
int main()
{
char *r = NULL;
execc("ls -l /", &r);
if(r!= NULL)
{
printf("result of cmd: \n %s", r);
free(r);
}
return 0;
}