# How to use Base.Libc.errno

**URL:** https://discourse.julialang.org/t/how-to-use-base-libc-errno/118832
**Category:** General Usage
**Tags:** question, multithreading, c
**Created:** [August 31, 2024, 4:18am UTC](https://discourse.julialang.org/t/how-to-use-base-libc-errno/118832 "2024-08-31T04:18:06Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![nhz2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhz2/32/44428_2.png) [@nhz2](https://discourse.julialang.org/u/nhz2)
#### Post date: [August 31, 2024, 4:18am UTC](https://discourse.julialang.org/t/how-to-use-base-libc-errno/118832/1 "2024-08-31T04:18:06Z")

</div>

[The docs for `errno` in Julia states:](https://docs.julialang.org/en/v1/base/libc/#Base.Libc.errno)

> The value of `errno` is only valid immediately after a `ccall` to a C library routine that sets it. Specifically, you cannot call `errno` at the next prompt in a REPL, because lots of code is executed between prompts.

What does “immediately after” mean? Isn’t the compiler generally free to reorder things or interrupt a task to run GC, finalizers, or other tasks wherever it wants?

Is there some special way to force the compiler to run `errno` “immediately” after a `ccall`, or should the `errno` function just be avoided in Julia?

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [August 31, 2024, 6:38am UTC](https://discourse.julialang.org/t/how-to-use-base-libc-errno/118832/2 "2024-08-31T06:38:42Z")

</div>

> [@nhz2](#):
>
> What does “immediately after” mean? Isn’t the compiler generally free to reorder things or interrupt a task to run GC, finalizers, or other tasks wherever it wants?

No not quite there are some rules.  
The task scheduler is cooperative, so a task has to call yield (either explicitly or implicitly through calling into the runtime, or calling wait) to be switched away from.

Similar with GC, you have to perform an allocation or hit a safepoint (which actually could be an issue since every function has a safepoint at the beginning)

And the compiler can’t reorder things that have arbitrary effects. So since errno and the ccall are not “pure” they have to be executed in order and the compiler can’t move things past them.

One potential issue might be interrupts, but that’s also an issue on C afaik.

So immediately really means:

```julia
call()
errno()

```

Any expression in between could cause the issue you are worried about.

---

<div class="post-metadata">

### Author: ![nhz2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhz2/32/44428_2.png) [@nhz2](https://discourse.julialang.org/u/nhz2)
#### Post date: [August 31, 2024, 3:57pm UTC](https://discourse.julialang.org/t/how-to-use-base-libc-errno/118832/3 "2024-08-31T15:57:29Z")

</div>

Thank you for the explanation, I didn’t know about the not “pure” thing.

Okay, so something like the following is good?  
I initially tried to do `e = Base.Libc.errno()`, but that adds a call to `Base.getproperty`

```julia
@noinline function rename(oldpath::AbstractString, newpath::AbstractString)
    errno = Base.Libc.errno
    e = @ccall rename(oldpath::Cstring, newpath::Cstring)::Cint
    er = errno()
    if !iszero(e)
        error("rename error $(Base.Libc.strerror(er))")
    end
    newpath
end

```

```julia-repl
julia> @code_lowered rename("","")
CodeInfo(
1 ─ nothing
│ %2 = Base.Libc
│ errno = Base.getproperty(%2, :errno)
│ %4 = Base.cconvert(Main.Cstring, oldpath)
│ %5 = Base.cconvert(Main.Cstring, newpath)
│ %6 = Base.unsafe_convert(Main.Cstring, %4)
│ %7 = Base.unsafe_convert(Main.Cstring, %5)
│ e = $(Expr(:foreigncall, :(:rename), Int32, svec(Cstring, Cstring), 0, :(:ccall), :(%6), :(%7), :(%5), :(%4)))
│ er = (errno)()
│ %10 = Main.iszero(e)
│ %11 = !%10
└── goto #3 if not %11
2 ─ %13 = Base.Libc
│ %14 = Base.getproperty(%13, :strerror)
│ %15 = (%14)(er)
│ %16 = Base.string("rename error ", %15)
└── Main.error(%16)
3 ┄ return newpath
)

```

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [September 1, 2024, 7:20am UTC](https://discourse.julialang.org/t/how-to-use-base-libc-errno/118832/4 "2024-09-01T07:20:21Z")

</div>

Yeah that’s correct.

I would simply `import Base.Libc: errno`, but thats a matter of style.

Also check `code_typed` since we actually need to inline errno
