Serious concern about suid and sgid bit

Hi guys, I am writing to you today, because following some previous post I did, I have some worries about the crystal behavior with the suid and sgid bit. I did some tests, and the result look quite random. Is it normal the first time in my example, when I call setuid, the file is created with root:root owner, but when I perform setuid(1000), only the user but not the group change ?
Something more mysterious is the last call. I setuid again to 0, but now only the group is set as root ???

#Libc functions to deal with SUID and SGID bit
lib LibC
    fun seteuid(uid : UidT): Int
    fun setegid(uid : UidT): Int
    fun setgid(uid : UidT): Int
    fun getgid : UidT
    fun getegid : UidT
    fun geteuid : UidT
end

LibC.setuid(0)

Process.run("/usr/bin/touch",
            args: ["filetest"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)

LibC.setuid(1000)

Process.run("/usr/bin/touch",
                args: ["filetest1"],
                input: Process::Redirect::Inherit,
                output: Process::Redirect::Inherit,
                error: Process::Redirect::Inherit,
                shell: false)

LibC.setuid(0)

Process.run("/usr/bin/touch",
            args: ["filetest2"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)

Result:

[fulgurance@alienware-m17-r3 Downloads]$ ls -la
-rw-r--r-- 1 root       root                0 Mar 27 18:47  filetest
-rw-r--r-- 1 fulgurance root                0 Mar 27 18:47  filetest1
-rw-r--r-- 1 fulgurance root                0 Mar 27 18:47  filetest2

Any logic in this ???

Another test that will blow your mind guys. Really I am lost.

#Libc functions to deal with SUID and SGID bit
lib LibC
    fun seteuid(uid : UidT): Int
    fun setegid(uid : UidT): Int
    fun setgid(uid : UidT): Int
    fun getgid : UidT
    fun getegid : UidT
    fun geteuid : UidT
end

LibC.setuid(1000)
LibC.setgid(1000)
LibC.seteuid(0)
LibC.setegid(0)

Process.run("/usr/bin/touch",
            args: ["filetest"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)

LibC.setuid(1000)
LibC.setgid(1000)
LibC.seteuid(1000)
LibC.setegid(1000)

Process.run("/usr/bin/touch",
                args: ["filetest1"],
                input: Process::Redirect::Inherit,
                output: Process::Redirect::Inherit,
                error: Process::Redirect::Inherit,
                shell: false)

LibC.setuid(1000)
LibC.setgid(1000)
LibC.seteuid(0) 
LibC.setegid(0)

Process.run("/usr/bin/touch",
            args: ["filetest2"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)

Result:

-rw-r--r-- 1 fulgurance root                0 Mar 27 19:07  filetest
-rw-r--r-- 1 fulgurance fulgurance          0 Mar 27 19:07  filetest1
-rw-r--r-- 1 fulgurance root                0 Mar 27 19:07  filetest2

And this one. Is it buggy ?

LibC.seteuid(0)
LibC.setegid(0)
LibC.setuid(0)
LibC.setgid(0)

puts LibC.getuid
puts LibC.getgid
puts LibC.geteuid
puts LibC.getegid

LibC.seteuid(1000)
LibC.setegid(1000)
LibC.setuid(1000)
LibC.setgid(1000)

puts LibC.getuid
puts LibC.getgid
puts LibC.geteuid
puts LibC.getegid

Result:

0
0
0
0
0
0
1000
0

So what I understood from my final test (I will paste below), is basically,

seteuid and setegid are the user who when it create a file, will be the creator (owner), but it don’t change who is the command launcher.

setuid and setgid is the opposite, it determine as which user something is run/executed, but it don’t alter the file owners.

#Libc functions to deal with SUID and SGID bit
lib LibC
    fun seteuid(uid : UidT): Int
    fun setegid(uid : UidT): Int
    fun setgid(uid : UidT): Int
    fun getgid : UidT
    fun getegid : UidT
    fun geteuid : UidT
end

LibC.seteuid(0)
LibC.setegid(0)

Process.run("/usr/bin/touch",
            args: ["filetest"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)

LibC.seteuid(1000)
LibC.setegid(1000)

Process.run("/usr/bin/touch",
                args: ["filetest1"],
                input: Process::Redirect::Inherit,
                output: Process::Redirect::Inherit,
                error: Process::Redirect::Inherit,
                shell: false)

LibC.seteuid(0)
LibC.setegid(0)

Process.run("/usr/bin/touch",
            args: ["filetest2"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)
#####################################################

LibC.setuid(0)
LibC.setgid(0)

Process.run("/usr/bin/umount",
            args: ["/dev/nvme0n1p2"],
            input: Process::Redirect::Inherit,
            output: Process::Redirect::Inherit,
            error: Process::Redirect::Inherit,
            shell: false)

As a hobbyist level programmer, I certainly can’t address this issue but could you write these as specs? I can’t tell what you find wrong and what your expectations for behavior are.