调用多个 _popen 失败

标签 c windows popen

我在使用 _popen(const char *, const char *) 时遇到问题

我正在尝试使用 awk 从 adb 获取信息,但我的程序在第二次 _popen 调用时崩溃(该方法被调用两次)。

这是有问题的代码(sysinf_getvalue() 在主程序中被多次调用)。


丑陋的代码

int deviceadbinfowritten = 0;
int devicebootloaderinfowritten = 0;
int adbinit = 0;

int initadb()
{
    if(!adbinit)
    {
        system("adb kill-server && adb start-server");
        adbinit = 1;
    }
    return 0;
}

int sysinfo_getadbinfofile()
{
    if(!deviceadbinfowritten)
    {
        system("echo Please connect your device && adb wait-for-device && adb.exe shell getprop > deviceinfo");
        deviceadbinfowritten = 1;
    }

    return 0;
}

int sysinfo_getbootloaderinfofile()
{
    if(!devicebootloaderinfowritten)
    {
        system("adb wait-for-device && adb reboot bootloader && fastboot getvar all > bootloaderinfo && fastboot reboot");
        devicebootloaderinfowritten = 1;
    }
    return 0;
}

char *sysinfo_getvalue(char *key, int bootloader)
{
    initadb();
    if(bootloader) sysinfo_getbootloaderinfofile();
    else sysinfo_getadbinfofile();
    char *file = (bootloader)?"bootloaderinfo":"deviceinfo";

    char *command = malloc(sizeof(char) * (strlen("awk.exe -F\":\" \" { print $2 }\" < ") + strlen(key) + (bootloader)?0:2 + strlen(file)));
    char *adbkey = malloc((strlen(key)+2)* (sizeof(char)));
    if(!bootloader) sprintf(adbkey, "/%s/", key);
    sprintf(command, "awk.exe -F\":\" \"%s { print $2 }\" < %s", ((bootloader)?key:adbkey), file);

    printf("%s\n", command);
    char *pointer = exe(command);
    if(!bootloader)
    {
        pointer += 2;
        pointer[strlen(pointer)-3] = 0;
    }

    return pointer;
}

char *exe(char *exe)
{
    char buffer[1024];
    FILE *f;

    printf("debug %s\n", exe);

    f = _popen(exe, "r");

    printf("debug\n");

    char *res = NULL;

    printf("debug\n");

    if (f == NULL) {
        printf("[-] Failed to run command\n" );
        return NULL;
}
    printf("debug\n");

    while (fgets(buffer, sizeof(buffer), f) != NULL) {
        if(res == NULL) {res = malloc(strlen(buffer) * sizeof(char)); strcpy(res, buffer);}
        else {res = realloc(res, strlen(res) * sizeof(char) + sizeof(buffer));sprintf(res, "%s%s", res, buffer);}
}

    printf("debug\n");

    _pclose(f);

    return res;
}

注意:如果我使用提供的相同字符串在主程序中直接调用 exe(),则 _popen 不会崩溃。

注意 2:调试器显示 "warning: HEAP[program.exe]: 警告:002D2EC0 处的堆 block 已在 002D2EC9 处修改,过去请求的大小为 1"

最佳答案

看起来好像您缺少为 0 终止符分配空间。

这是每个字符数组需要的最后一个附加字节,如果用作字符串以通过值为 NUL(十进制 0)的字符指示字符串的结尾。

至少这一行:

char *command = malloc(sizeof(char) * (strlen("awk.exe -F\":\" \" { print $2 }\" < ") + strlen(key) + (bootloader)?0:2 + strlen(file)));

再分配一个字符:

char *command = malloc(
  sizeof(char) * (
    strlen("awk.exe -F\":\" \" { print $2 }\" < ") + 
    strlen(key) + 
    (bootloader)?0:2 + strlen(file)) + 
    1
  )
);

(对于此类问题,我没有检查您代码中字符数组的所有分配/分配。)

关于调用多个 _popen 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14424141/

相关文章:

windows - 如何在 Windows 命令提示符下获取文件?

windows - JRuby on Rails 无法与在 Windows Server 2008 上作为服务运行的 Tomcat 一起使用

Python Popen 找不到指定的文件

php - 使用 popen 执行多处理脚本时输出困惑

c - 在与原子加载和存储同步的线程之间共享变量是否安全?

编译器在包含其他库后不接受外部变量

c++ - 我可以平滑 3 channel 图像中的 1 个 channel 吗?

c++ - 如何判断 Qt (C/C++) 程序中是否正在运行屏幕保护程序? (微软 Windows )

SQL CE 复制

python - 使用 subprocess.Popen 恢复进程?