aboutsummaryrefslogtreecommitdiff
path: root/core/sys/posix/grp.odin
blob: 8e8e69fc21cf102940fda5defa289929e0865890 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix

import "core:c"

when ODIN_OS == .Darwin {
	foreign import lib "system:System"
} else {
	foreign import lib "system:c"
}

// grp.h - group structure

foreign lib {
	/*
	Closes the group database.

	Checking status would be done by setting errno to 0, calling this, and checking errno.

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/endgrent.html ]]
	*/
	endgrent :: proc() ---

	/*
	Rewinds the group database so getgrent() returns the first entry again.

	Checking status would be done by setting errno to 0, calling this, and checking errno.

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/endgrent.html ]]
	*/
	setgrent :: proc() ---

	/*
	Returns a pointer to an entry of the group database.

	Opens the group database if it isn't.

	Returns: nil on failure (setting errno) or EOF (not setting errno), the entry otherwise

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/endgrent.html ]]
	*/
	getgrent :: proc() -> ^group ---

	/*
	Searches for an entry with a matching gid in the group database.

	Returns: nil (setting errno) on failure, a pointer to the entry on success

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgrgid.html ]]
	*/
	getgrgid :: proc(gid: gid_t) -> ^group ---

	/*
	Searches for an entry with a matching gid in the group database.

	Updates grp with the matching entry and stores it (or a nil pointer (setting errno)) into result.

	Strings are allocated into the given buffer, you can call `sysconf(._GETGR_R_SIZE_MAX)` for an appropriate size.

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgrgid.html ]]
	*/
	getgrgid_r :: proc(gid: gid_t, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno ---

	/*
	Searches for an entry with a matching gid in the group database.

	Returns: nil (setting errno) on failure, a pointer to the entry on success

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgrnam.html ]]
	*/
	getgrnam :: proc(name: cstring) -> ^group ---

	/*
	Searches for an entry with a matching gid in the group database.

	Updates grp with the matching entry and stores it (or a nil pointer (setting errno)) into result.

	Strings are allocated into the given buffer, you can call `sysconf(._GETGR_R_SIZE_MAX)` for an appropriate size.

	Example:
		length := posix.sysconf(._GETGR_R_SIZE_MAX)
		if length == -1 {
			length = 1024
		}

		result:  posix.group
		resultp: ^posix.group

		e: posix.Errno

		buffer: [dynamic]byte
		defer delete(buffer)

		for {
			mem_err := resize(&buffer, length)
			assert(mem_err == nil)

			e = posix.getgrnam_r("nobody", &result, raw_data(buffer), len(buffer), &resultp)
			if e != .ERANGE {
				break
			}

			length *= 2
			assert(length > 0)
		}

		if e != .NONE {
			panic(string(posix.strerror(e)))
		}

		fmt.println(result)

	[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgrnam.html ]]
	*/
	getgrnam_r :: proc(name: cstring, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno ---
}

when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku || ODIN_OS == .Linux {

	gid_t :: distinct c.uint32_t

	group :: struct {
		gr_name:   cstring,    /* [PSX] group name */
		gr_passwd: cstring,    /* group password */
		gr_gid:    gid_t,      /* [PSX] group id */
		gr_mem:    [^]cstring, /* [PSX] group members */
	}

}