现在就从linux kernel的源代码的角度来分析该。
二:fork()与execve()中stderr,stdio.stdout的继承关系
其实用继承这个词好像不太准确,要准确一点,可能复制更适合.
首先有二点:
1:父进程fork出子进程后,是共享所有文件描述符的(实际上也包括socket)
2:进程在execve后,除了用O_CLOEXEC标志打开的文件外,其它的文件描述符都是会复制到下个执行序列(注意这里不会产生一个新进程,只是将旧的进程替换了)
下面我们从代码中找依据来论证以上的两个观点.
对于第一点:
我们在分析进程创建的时候,已经说过,如果父过程在创建子进程的时候带了CLONE_FILES标志的时候,会和父进程共享task->files.如果没有定义,就会复制父进程的task->files.无论是哪种情况,父子进程的环境都是相同的.
代码如下:
static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
{
struct files_struct *oldf, *newf;
int error = 0;
oldf = current->files;
if (!oldf)
goto out;
if (clone_flags & CLONE_FILES) {
atomic_inc(&oldf->count);
goto out;
}
tsk->files = NULL;
newf = dup_fd(oldf, &error);
if (!newf)
goto out;
tsk->files = newf;
error = 0;
out:
return error;
}
从上面的代码可以看出.如果带CLONE_FILES标志,只是会增加它的引用计数.否则,打开的文件描符述会全部复制.
对于二:
我们之前同样也分析过sys_execve().如果有不太熟悉的,到本站找到相关文章进行阅读.在这里不再详细说明整个流程.相关代码如下:
static void flush_old_files(struct files_struct * files)
{
long j = -1;
struct fdtable *fdt;
spin_lock(&files->file_lock);
for (;;) {
unsigned long set, i;
j++;
i = j * __NFDBITS;
fdt = files_fdtable(files);
if (i >= fdt->max_fds)
break;
set = fdt->close_on_exec->fds_bits[j];
if (!set)
continue;
fdt->close_on_exec->fds_bits[j] = 0;
spin_unlock(&files->file_lock);
for ( ; set ; i++,set >>= 1) {
if (set & 1) {
sys_close(i);
}
}
spin_lock(&files->file_lock);
}
spin_unlock(
Linux 下 stdin stdout stderr 的由来
最新推荐文章于 2022-04-29 15:47:56 发布
本文深入分析Linux中stdin, stdout, stderr的由来,探讨fork()与execve()如何影响它们,并讲解用户空间初始化这些标准流的过程,以及内核创建用户进程时的文件描述符处理。通过源代码分析,揭示了进程间文件描述符的共享和复制机制。"
136089968,461481,深度学习入门:理解神经网络的数学基础,"['神经网络', '深度学习', 'Python', '数学基础', '机器学习']
摘要由CSDN通过智能技术生成