1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /*
3  * Special types used by various syscalls for NOLIBC
4  * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
5  */
6 
7 #ifndef _NOLIBC_TYPES_H
8 #define _NOLIBC_TYPES_H
9 
10 #include "std.h"
11 #include <linux/time.h>
12 
13 
14 /* Only the generic macros and types may be defined here. The arch-specific
15  * ones such as the O_RDONLY and related macros used by fcntl() and open(), or
16  * the layout of sys_stat_struct must not be defined here.
17  */
18 
19 /* stat flags (WARNING, octal here) */
20 #define S_IFDIR        0040000
21 #define S_IFCHR        0020000
22 #define S_IFBLK        0060000
23 #define S_IFREG        0100000
24 #define S_IFIFO        0010000
25 #define S_IFLNK        0120000
26 #define S_IFSOCK       0140000
27 #define S_IFMT         0170000
28 
29 #define S_ISDIR(mode)  (((mode) & S_IFDIR)  == S_IFDIR)
30 #define S_ISCHR(mode)  (((mode) & S_IFCHR)  == S_IFCHR)
31 #define S_ISBLK(mode)  (((mode) & S_IFBLK)  == S_IFBLK)
32 #define S_ISREG(mode)  (((mode) & S_IFREG)  == S_IFREG)
33 #define S_ISFIFO(mode) (((mode) & S_IFIFO)  == S_IFIFO)
34 #define S_ISLNK(mode)  (((mode) & S_IFLNK)  == S_IFLNK)
35 #define S_ISSOCK(mode) (((mode) & S_IFSOCK) == S_IFSOCK)
36 
37 /* dirent types */
38 #define DT_UNKNOWN     0x0
39 #define DT_FIFO        0x1
40 #define DT_CHR         0x2
41 #define DT_DIR         0x4
42 #define DT_BLK         0x6
43 #define DT_REG         0x8
44 #define DT_LNK         0xa
45 #define DT_SOCK        0xc
46 
47 /* commonly an fd_set represents 256 FDs */
48 #ifndef FD_SETSIZE
49 #define FD_SETSIZE     256
50 #endif
51 
52 /* PATH_MAX and MAXPATHLEN are often used and found with plenty of different
53  * values.
54  */
55 #ifndef PATH_MAX
56 #define PATH_MAX       4096
57 #endif
58 
59 #ifndef MAXPATHLEN
60 #define MAXPATHLEN     (PATH_MAX)
61 #endif
62 
63 /* Special FD used by all the *at functions */
64 #ifndef AT_FDCWD
65 #define AT_FDCWD       (-100)
66 #endif
67 
68 /* whence values for lseek() */
69 #define SEEK_SET       0
70 #define SEEK_CUR       1
71 #define SEEK_END       2
72 
73 /* cmd for reboot() */
74 #define LINUX_REBOOT_MAGIC1         0xfee1dead
75 #define LINUX_REBOOT_MAGIC2         0x28121969
76 #define LINUX_REBOOT_CMD_HALT       0xcdef0123
77 #define LINUX_REBOOT_CMD_POWER_OFF  0x4321fedc
78 #define LINUX_REBOOT_CMD_RESTART    0x01234567
79 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xd000fce2
80 
81 /* Macros used on waitpid()'s return status */
82 #define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
83 #define WIFEXITED(status)   (((status) & 0x7f) == 0)
84 
85 /* waitpid() flags */
86 #define WNOHANG      1
87 
88 /* standard exit() codes */
89 #define EXIT_SUCCESS 0
90 #define EXIT_FAILURE 1
91 
92 /* for select() */
93 typedef struct {
94 	uint32_t fd32[(FD_SETSIZE + 31) / 32];
95 } fd_set;
96 
97 #define FD_CLR(fd, set) do {                                            \
98 		fd_set *__set = (set);                                  \
99 		int __fd = (fd);                                        \
100 		if (__fd >= 0)                                          \
101 			__set->fd32[__fd / 32] &= ~(1U << (__fd & 31)); \
102 	} while (0)
103 
104 #define FD_SET(fd, set) do {                                            \
105 		fd_set *__set = (set);                                  \
106 		int __fd = (fd);                                        \
107 		if (__fd >= 0)                                          \
108 			__set->fd32[__fd / 32] |= 1U << (__fd & 31);    \
109 	} while (0)
110 
111 #define FD_ISSET(fd, set) ({                                                  \
112 		fd_set *__set = (set);                                        \
113 		int __fd = (fd);                                              \
114 		int __r = 0;                                                  \
115 		if (__fd >= 0)                                                \
116 			__r = !!(__set->fd32[__fd / 32] & 1U << (__fd & 31)); \
117 		__r;                                                          \
118 	})
119 
120 #define FD_ZERO(set) do {                                               \
121 		fd_set *__set = (set);                                  \
122 		int __idx;                                              \
123 		for (__idx = 0; __idx < (FD_SETSIZE+31) / 32; __idx ++) \
124 			__set->fd32[__idx] = 0;                         \
125 	} while (0)
126 
127 /* for poll() */
128 #define POLLIN          0x0001
129 #define POLLPRI         0x0002
130 #define POLLOUT         0x0004
131 #define POLLERR         0x0008
132 #define POLLHUP         0x0010
133 #define POLLNVAL        0x0020
134 
135 struct pollfd {
136 	int fd;
137 	short int events;
138 	short int revents;
139 };
140 
141 /* for getdents64() */
142 struct linux_dirent64 {
143 	uint64_t       d_ino;
144 	int64_t        d_off;
145 	unsigned short d_reclen;
146 	unsigned char  d_type;
147 	char           d_name[];
148 };
149 
150 /* needed by wait4() */
151 struct rusage {
152 	struct timeval ru_utime;
153 	struct timeval ru_stime;
154 	long   ru_maxrss;
155 	long   ru_ixrss;
156 	long   ru_idrss;
157 	long   ru_isrss;
158 	long   ru_minflt;
159 	long   ru_majflt;
160 	long   ru_nswap;
161 	long   ru_inblock;
162 	long   ru_oublock;
163 	long   ru_msgsnd;
164 	long   ru_msgrcv;
165 	long   ru_nsignals;
166 	long   ru_nvcsw;
167 	long   ru_nivcsw;
168 };
169 
170 /* The format of the struct as returned by the libc to the application, which
171  * significantly differs from the format returned by the stat() syscall flavours.
172  */
173 struct stat {
174 	dev_t     st_dev;     /* ID of device containing file */
175 	ino_t     st_ino;     /* inode number */
176 	mode_t    st_mode;    /* protection */
177 	nlink_t   st_nlink;   /* number of hard links */
178 	uid_t     st_uid;     /* user ID of owner */
179 	gid_t     st_gid;     /* group ID of owner */
180 	dev_t     st_rdev;    /* device ID (if special file) */
181 	off_t     st_size;    /* total size, in bytes */
182 	blksize_t st_blksize; /* blocksize for file system I/O */
183 	blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
184 	time_t    st_atime;   /* time of last access */
185 	time_t    st_mtime;   /* time of last modification */
186 	time_t    st_ctime;   /* time of last status change */
187 };
188 
189 /* WARNING, it only deals with the 4096 first majors and 256 first minors */
190 #define makedev(major, minor) ((dev_t)((((major) & 0xfff) << 8) | ((minor) & 0xff)))
191 #define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff))
192 #define minor(dev) ((unsigned int)(((dev) & 0xff))
193 
194 #ifndef offsetof
195 #define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD)
196 #endif
197 
198 #ifndef container_of
199 #define container_of(PTR, TYPE, FIELD) ({			\
200 	__typeof__(((TYPE *)0)->FIELD) *__FIELD_PTR = (PTR);	\
201 	(TYPE *)((char *) __FIELD_PTR - offsetof(TYPE, FIELD));	\
202 })
203 #endif
204 
205 #endif /* _NOLIBC_TYPES_H */
206