关于 os.Setenv() 和 os.Unsetenv() 函数引发错误的简单问题。

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

Simple question about inducing errors for os.Setenv() and os.Unsetenv()

问题

我正在尝试找出如何使os.Setenv()和os.Unsetenv()失败,以便我可以编写一个_test.go文件来测试调用这些函数的代码的失败条件。

当然,它们的签名是:func Setenv(key, value string) errorfunc Unsetenv(key) error

我查看了源代码,它们有测试,但似乎没有测试这些函数失败的情况。

是的,我可以忽略错误返回,但这有点违背了有错误返回的初衷。
所以,有人知道如何使它们失败吗?

提前感谢...

英文:

I'm trying to figure out how too make os.Setenv() and os.Unsetenv() fail so I can write a _test.go around some code which calls these. I want to be complete and test the failure conditions.

Of course, the signatures are: func Setenv(key, value string) error and func Unsetenv(key) error

I looked thru the source code and they had tests, but it doesn't look like they had a test where these failed.

Yeah, I could just ignore the error return, but that kinda defeats having an error return.
So, anyone have a lead to how to make these fail?

Thanks in advance...

答案1

得分: 1

os.Setenv是对syscall.Setenv的一个非常薄的包装,它只是返回syscall.Setenv返回的任何错误,用NewSyscallError包装。

错误情况在源代码中很明显,源代码只有18行:

func Setenv(key, value string) error {
	envOnce.Do(copyenv)
	if len(key) == 0 {
		return EINVAL
	}
	for i := 0; i < len(key); i++ {
		if key[i] == '=' || key[i] == 0 {
			return EINVAL
		}
	}
	// On Plan 9, null is used as a separator, eg in $path.
	if runtime.GOOS != "plan9" {
		for i := 0; i < len(value); i++ {
			if value[i] == 0 {
				return EINVAL
			}
		}
	}
}

因此,要引发错误,您需要满足以下任何条件:

  • len(key) == 0
  • key[i] == '=' || key[i] == 0
  • runtime.GOOS != "plan9" 并且 value[i] == 0

另一方面,syscall.Unsetenv从不返回错误,它只能返回nil

func Unsetenv(key string) error {
	envOnce.Do(copyenv)

	envLock.Lock()
	defer envLock.Unlock()

	if i, ok := env[key]; ok {
		envs[i] = ""
		delete(env, key)
	}
	unsetenv_c(key)
	return nil
}

我猜测它被写成返回错误是为了与Setenv保持一致,并为将来可能在某些条件下产生错误的某些平台或环境提供支持。

英文:

os.Setenv is a very thin wrapper around syscall.Setenv, and simply returns whichever error syscall.Setenv returns, wrapped with NewSyscallError.

The error cases are evident in the source, which is only 18 lines long:

func Setenv(key, value string) error {
	envOnce.Do(copyenv)
	if len(key) == 0 {
		return EINVAL
	}
	for i := 0; i &lt; len(key); i++ {
		if key[i] == &#39;=&#39; || key[i] == 0 {
			return EINVAL
		}
	}
	// On Plan 9, null is used as a separator, eg in $path.
	if runtime.GOOS != &quot;plan9&quot; {
		for i := 0; i &lt; len(value); i++ {
			if value[i] == 0 {
				return EINVAL
			}
		}
	}
}

So to provoke an error, you need to satisfy any of the following:

  • len(key) == 0
  • key[i] == &#39;=&#39; || key[i] == 0
  • runtime.GOOS != &quot;plan9&quot; and value[i] == 0

syscall.Unsetenv on the other hand never returns an error, it can only return nil.

func Unsetenv(key string) error {
	envOnce.Do(copyenv)

	envLock.Lock()
	defer envLock.Unlock()

	if i, ok := env[key]; ok {
		envs[i] = &quot;&quot;
		delete(env, key)
	}
	unsetenv_c(key)
	return nil
}

I would speculate that it is written as returning an error for consistency with the Setenv, and to provide support for some future platform or environment where it may produce an error under certain conditions.

huangapple
  • 本文由 发表于 2021年9月16日 09:06:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/69201304.html
匿名

发表评论

匿名网友

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

确定