如何高效地从文件中读取环境参数,以便与exec一起使用
我希望能够保存到进程的argv和environ文件中,然后在以后能够如何高效地从文件中读取环境参数,以便与exec一起使用,c,linux,environment-variables,exec,command-line-arguments,C,Linux,Environment Variables,Exec,Command Line Arguments,我希望能够保存到进程的argv和environ文件中,然后在以后能够fork和exec 使用保存到文件中的参数 我能想到的唯一设计是将参数列表作为一个长字符串写入文件,但随后我需要将其从字符串转换为字符串数组,这是可能的,但非常麻烦 有人能想出更好的方法吗?我对文件格式的建议 第一行是一个十进制数N,它等于argc 接下来的N行是argv字符串,每行一个字符串 然后还有一个十进制数M,它等于环境字符串的数量 接下来的M行是环境字符串,每行一个字符串 将文件读回内存 使用getline读取第
fork
和exec
使用保存到文件中的参数
我能想到的唯一设计是将参数列表作为一个长字符串写入文件,但随后我需要将其从字符串转换为字符串数组,这是可能的,但非常麻烦
有人能想出更好的方法吗?我对文件格式的建议
- 第一行是一个十进制数N,它等于
argc
- 接下来的N行是
字符串,每行一个字符串argv
- 然后还有一个十进制数M,它等于环境字符串的数量
- 接下来的M行是环境字符串,每行一个字符串
- 使用
读取第一行,并使用getline
sscanf
N+1指针数组malloc
- 使用
读取接下来的N行,将指针存储在getline
数组中argv
- 将空指针放在
数组的末尾argv
- 使用
读取下一行,并使用getline
sscanf
M+1指针数组malloc
- 使用
读取接下来的M行,将指针存储在getline
数组中env
- 将空指针放在
数组的末尾env
getline
时,有两件事要记住。首先,它将自动malloc
字符串的内存。其次,它将换行符放在字符串的末尾,因此您必须删除它
使用getline
int N = 5;
char **argv = malloc( (N + 1) * sizeof(char *) );
char *line;
size_t linecap, length;
for ( int i = 0; i < N; i++ )
{
line = NULL; // request that getline allocate memory
linecap = 0;
if ( (length = getline( &line, &linecap, fp )) <= 0 )
exit( 1 ); // file ended prematurely
line[length-1] = '\0'; // get rid of the pesky newline
argv[i] = line;
}
argv[N] = NULL;
int N=5;
字符**argv=malloc((N+1)*sizeof(字符*);
字符*行;
线头尺寸、长度;
对于(int i=0;i 如果((length=getline(&line,&linecap,fp))我解决这个问题的方法是编写一个具有以下结构的二进制文件:
begin file header:
0x00 :: 0x03 [ 4 bytes] number of entries
for each entry n at offset 0x04 + n * 4:
0x00 :: 0x03 [ 4 bytes] string length of entry (including terminating \0)
end file header
在头之后,将所有条目作为字符串写入文件,包括终止的\0
字节
要读取此文件,我将使用fopen
、fread
、fclose
从文件中读取偏移量数组,然后我将mmap
文件,并将偏移量数组转换为指向mmapped区域的指针数组
可移植性说明:
如果您希望能够在一个体系结构上读取该文件,并在另一个体系结构上读取该文件,则需要
- 确保使用固定宽度的数据类型(例如,
uint32\u t
,uint64\u t
)
- 确定字节顺序以避免尾数问题
比如说,如果您想在文件中写入uint32\t
,而不存在结尾问题,您可以使用
void
write_uint32 (FILE *f, uint32_t v)
{
unsigned char out[4] = { 0 };
out[0] = v & 0xff; v >>= 8;
out[1] = v & 0xff; v >>= 8;
out[2] = v & 0xff; v >>= 8;
out[3] = v
fwrite(out, 1, sizeof(out), f);
}
和读取相同的值
uint32_t
read_uint32 (FILE *f)
{
unsigned char in[4] = { 0 }
fread(in, 1, sizeof(in), f);
return in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];
}
uint32\u t
读取uint32(文件*f)
{
[4]={0}中的无符号字符
fread(in,1,sizeof(in,f);
返回[3]您是否需要该文件在体系结构之间可移植?不,不需要移植mmap解决方案看起来非常优雅,但这是我第一次遇到它,因此在提出任何进一步的问题之前,我可能应该先阅读相关书籍……这是我发现不清楚的部分:“然后我将mmap
文件,并将偏移数组转换为指针数组,并将其转换为mmapped区域。"具体怎么做?@yaloner如果你在一个文件中有一个偏移量数组,然后mmap
所说的文件,那么文件中的每个偏移量都可以通过将基址添加到mmap返回的区域中,映射到mmap区域的指针上。我仍然不确定我是否理解作为结果获取字符**的过程。你碰巧知道吗举个例子?我不理解你的问题-将偏移量的long
数组转换成一个文件,再转换成内存区域指针的char*
数组应该很简单?伪代码对于I=0到max:chars[I]=long[I]+base