“errno” 何时设置?

huangapple go评论54阅读模式
英文:

When is errno set

问题

errno in C is typically set when system calls encounter errors. In your code, errno can be set in the following places:

  1. When attempting to open the source file (PathFrom) using fopen(PathFrom, "r") if the file doesn't exist or if there are permission issues.
  2. When attempting to open the target file (PathTo) using fopen(PathTo, "w") if there are issues with permissions or if there's not enough space on the device.
  3. If there's an issue with reading or writing data to/from the file, it might set errno during the fgets or fputs operations.

So, in your example, errno can be set at any of these points if there are errors related to file operations.

英文:

In C I know that you can see the errors using errno in errno.h and I have the following code

int FS_copyFile(const char* PathFrom , const char* PathTo) {
	FILE* Source;
	FILE* Target;

	struct stat st;
	stat(PathFrom, &st);

	char SourceFileData[st.st_size];

	Source = fopen(PathFrom , "r");

	if(Source == NULL) {
		return errno;
	}

	Target = fopen(PathTo , "w");

	if(Target == NULL) {
		return errno;
	}

	fgets(SourceFileData, st.st_size + 1, Source); 

	fputs(SourceFileData , Target);

	fclose(Source);
	fclose(Target);
}

But I am unsure when errno is set. Let us say that the file foo.txt that cannot be written to. Will errno be set when opening the file for writing or attempting to write to it?

I have tried looking online but i can't find anything that actually says when errno is set. In which parts of my code will errno be set if an error happens?

答案1

得分: 2

以下是已翻译的内容:

标准C库中函数的规范是,函数的文档中明确提到会设置errno的函数会按文档设置errno,而文档中未提到errno的函数可能会将errno设置为非零值,即使没有错误发生。(这是因为该函数可能会调用其他例程执行某些工作,而这些例程可能会报告错误,随后父例程可能会以某种方式解决错误,以便成功完成其调用者请求的任务,但可能会保留errno的设置。)C 2018 7.5.2 规定:

... 初始线程中errno的值在程序启动时为零(其他线程中errno的初始值是不确定的),但不会被任何库函数设置为零。errno的值可能会在库函数调用时设置为非零,无论是否存在错误,只要在本文档中的函数描述中未记录使用errno

标准C库之外的函数可能会有不同的行为。例如,在macOS上,fts_read函数会清除errno以指示树遍历已完成:

... 如果层次结构的所有成员都已返回,fts_read() 返回NULL 并将外部变量errno设置为0...

在打开文件进行写入或尝试写入文件时,errno会被设置吗?

C标准中的fopenfwrite规范未提到errno,因此它们可能会或可能不会设置errno。这些例程的具体实现可能会记录它们是否设置了errno。例如,macOS的fopen文档指出,由于mallocopen(或等效操作)失败,它可能会失败并设置errno

请注意,fwrite通常是带有缓冲的,因此对文件的写入失败可能不会立即发生。如果fwrite没有报告错误,它们应该由fflushfclose报告。

英文:

The specification for functions in the standard C library is that functions whose documentation says they set errno set errno as documented and that functions whose documentation is silent about errno might set errno to non-zero, even if no error occurs. (This is because the function might call other routines to do some work, and those routines might report an error, after which the parent routine might resolve the error in some way, so it can successfully complete the task its caller requested, but it may leave errno set.) C 2018 7.5 2 says:

> … The value of errno in the initial thread is zero at program startup (the initial value of errno in other threads is an indeterminate value), but is never set to zero by any library function. The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this document.

Functions other than those in the standard C library may behave differently. For example, on macOS, the fts_read function will clear errno to indicate a tree traversal is complete:

> … If all the members of the hierarchy have been returned, fts_read() returns <tt>NULL</tt> and sets the external variable errno to 0…

> Will errno be set when opening the file for writing or attempting to write to it?

The C standard’s specifications for fopen and fwrite do not mention errno, so they may or may not set errno. Specific implementations of these routines might document that they set errno. For example, the macOS documentation for fopen indicates it may fail and set errno due to failures in malloc or open (or equivalent).

Note that fwrite is typically buffered, so any failures to write to a file might not occur immediately. If not reported by fwrite, they should be reported by fflush or fclose.

huangapple
  • 本文由 发表于 2023年4月7日 00:01:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定