簡體   English   中英

如何在C中設置與父級相同的子級環境變量以使用execve?

[英]How to set the environment variable of child same as parent to use execve in C?

我試圖設置類似於父進程的子進程的環境,我需要用字符串填充名為envp的數組,如下所示:

char *envp = malloc(sizeof(args) / sizeof(char *));
strcpy(envp[0], strcat("HOME=", getenv("HOME")));
envp[1] = strcat("PATH=", getenv("PATH"));
envp[2] = strcat("TZ=", getenv("TZ"));
envp[3] = strcat("USER=", getenv("USER"));
envp[4] = strcat("LOGNAME=", getenv("LOGNAME"));
envp[5] = 0;

內部if(fork()== 0)

setenv("parent", cwd, 1);
if((execve(args[0], &args[0], envp)) < 0 ){
            perror(*args);
            exit(EXIT_FAILURE);
}

我這樣做是因為我不知道這些環境變量的值,所以我想復制父變量以便在將替換子進程的execve()中使用它們! 我使用execve()而不是execvp(),因為我想在執行命令之前處理cwd的搜索並搜索cwd的shell路徑名稱的目錄。

所以我的問題是:如何以正確的方式設置數組的值? 另外,我是否誤解了任何概念?

我在這里看了很多帖子,但是很明顯我迷路了! 提前致謝,

您沒有為envp [x]指向的字符串分配內存。 相反,您嘗試將strcatstrcpy為常量或未分配的字符串,這是不行的(您的編譯器很可能已警告您)

一般概念是

  1. 您需要為指向環境字符串的指針數組分配內存(您已經這樣做了)。
  2. 您還需要為這些指針指向的每個字符串分配內存(您沒有這樣做)。 請注意,在大多數操作系統中,內存屬於流程環境的所有權,因此您不能使用局部變量,並且可能無法free此內存。
  3. 您需要將從(2)檢索到的指針保存到在(1)處分配的數組位置中(您已經這樣做了)

您的代碼應類似於(僅用於“ HOME”的示例,可能需要調整/檢查envbuff長度):

char envBuff [100];

strcpy (envBuff, "HOME=");
strcat (envBuff, getenv ("HOME));
envp [0] = strdup (envBuff);

strdup實際分配其占用的內存, strcat為你做什么或簡單的賦值envp[0]不- strcat假設有足夠的空間供原始和附加部分和內存可寫,這既是不正確在你的情況下。

  • strcat()是一個可怕的函數
  • 每個“名稱=值”對的單獨strdup()也可以作為一種選擇。
  • 將所有字符串都放在一個內存塊中會更好
  • snprintf()永遠不會寫超出允許的大小; 相反,它會為您提供所需的尺寸
  • getenv()可以返回NULL,這個必須被處理

注意:我省略了對realloc()返回NULL的檢查,您應該添加這些檢查。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define COUNTOF(a) (sizeof a / sizeof a[0])
char * names[] = {"HOME", "PATH", "TZ", "USER", "LOGNAME", NULL};

int main(void)
{
char *all=NULL;
char *array[COUNTOF(names) ];
size_t size, used, idx, envc, len;

for (idx=envc=size=used= 0; names[idx] ; idx++ ) {
        char *cp;
        cp = getenv(names[idx] );
        if (!cp) {
                fprintf(stderr, "%s not found\n", names[idx] );
                continue;
                }
        fprintf(stderr, "%s found: \"%s\"\n", names[idx], cp );
        while(1) {
                len = snprintf(all+used, size-used, "%s=%s", names[idx], cp);
                        /* enough space for the "NAME=val\0" pair */
                if (len+1 < size-used) break;
                fprintf(stderr, "Len=%zu; realloc %zu += %zu\n" , len, size, 2*len+1 );
                all = realloc(all, size += 2*len+1);
                }
        array[envc++] = all+used; used += len+1;
        }

fprintf(stderr, "Final realloc %zu -->> %zu\n" , size, used+1 );
all = realloc(all, used+1);
array[envc] = NULL;

for (idx=0; idx < envc; idx++) {
        printf("[%zu] -> %s\n", idx, array[idx] );
        }

return 0;
}

順便說一句:如果您的OS /環境允許,您可以將main()定義為

int main(int argc, char **argv, char **envp) { ... }

,並使用父進程的現有env指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM