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_IFMT) == S_IFDIR)
30 #define S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
31 #define S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
32 #define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
33 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
34 #define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
35 #define S_ISSOCK(mode) (((mode) & S_IFMT) == 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 #define FD_SETIDXMASK (8 * sizeof(unsigned long))
93 #define FD_SETBITMASK (8 * sizeof(unsigned long)-1)
94 
95 /* for select() */
96 typedef struct {
97 	unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK];
98 } fd_set;
99 
100 #define FD_CLR(fd, set) do {						\
101 		fd_set *__set = (set);					\
102 		int __fd = (fd);					\
103 		if (__fd >= 0)						\
104 			__set->fds[__fd / FD_SETIDXMASK] &=		\
105 				~(1U << (__fd & FX_SETBITMASK));	\
106 	} while (0)
107 
108 #define FD_SET(fd, set) do {						\
109 		fd_set *__set = (set);					\
110 		int __fd = (fd);					\
111 		if (__fd >= 0)						\
112 			__set->fds[__fd / FD_SETIDXMASK] |=		\
113 				1 << (__fd & FD_SETBITMASK);		\
114 	} while (0)
115 
116 #define FD_ISSET(fd, set) ({						\
117 			fd_set *__set = (set);				\
118 			int __fd = (fd);				\
119 		int __r = 0;						\
120 		if (__fd >= 0)						\
121 			__r = !!(__set->fds[__fd / FD_SETIDXMASK] &	\
122 1U << (__fd & FD_SET_BITMASK));						\
123 		__r;							\
124 	})
125 
126 #define FD_ZERO(set) do {						\
127 		fd_set *__set = (set);					\
128 		int __idx;						\
129 		int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\
130 		for (__idx = 0; __idx < __size; __idx++)		\
131 			__set->fds[__idx] = 0;				\
132 	} while (0)
133 
134 /* for poll() */
135 #define POLLIN          0x0001
136 #define POLLPRI         0x0002
137 #define POLLOUT         0x0004
138 #define POLLERR         0x0008
139 #define POLLHUP         0x0010
140 #define POLLNVAL        0x0020
141 
142 struct pollfd {
143 	int fd;
144 	short int events;
145 	short int revents;
146 };
147 
148 /* for getdents64() */
149 struct linux_dirent64 {
150 	uint64_t       d_ino;
151 	int64_t        d_off;
152 	unsigned short d_reclen;
153 	unsigned char  d_type;
154 	char           d_name[];
155 };
156 
157 /* needed by wait4() */
158 struct rusage {
159 	struct timeval ru_utime;
160 	struct timeval ru_stime;
161 	long   ru_maxrss;
162 	long   ru_ixrss;
163 	long   ru_idrss;
164 	long   ru_isrss;
165 	long   ru_minflt;
166 	long   ru_majflt;
167 	long   ru_nswap;
168 	long   ru_inblock;
169 	long   ru_oublock;
170 	long   ru_msgsnd;
171 	long   ru_msgrcv;
172 	long   ru_nsignals;
173 	long   ru_nvcsw;
174 	long   ru_nivcsw;
175 };
176 
177 /* The format of the struct as returned by the libc to the application, which
178  * significantly differs from the format returned by the stat() syscall flavours.
179  */
180 struct stat {
181 	dev_t     st_dev;     /* ID of device containing file */
182 	ino_t     st_ino;     /* inode number */
183 	mode_t    st_mode;    /* protection */
184 	nlink_t   st_nlink;   /* number of hard links */
185 	uid_t     st_uid;     /* user ID of owner */
186 	gid_t     st_gid;     /* group ID of owner */
187 	dev_t     st_rdev;    /* device ID (if special file) */
188 	off_t     st_size;    /* total size, in bytes */
189 	blksize_t st_blksize; /* blocksize for file system I/O */
190 	blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
191 	time_t    st_atime;   /* time of last access */
192 	time_t    st_mtime;   /* time of last modification */
193 	time_t    st_ctime;   /* time of last status change */
194 };
195 
196 /* WARNING, it only deals with the 4096 first majors and 256 first minors */
197 #define makedev(major, minor) ((dev_t)((((major) & 0xfff) << 8) | ((minor) & 0xff)))
198 #define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff))
199 #define minor(dev) ((unsigned int)(((dev) & 0xff))
200 
201 #ifndef offsetof
202 #define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD)
203 #endif
204 
205 #ifndef container_of
206 #define container_of(PTR, TYPE, FIELD) ({			\
207 	__typeof__(((TYPE *)0)->FIELD) *__FIELD_PTR = (PTR);	\
208 	(TYPE *)((char *) __FIELD_PTR - offsetof(TYPE, FIELD));	\
209 })
210 #endif
211 
212 /* make sure to include all global symbols */
213 #include "nolibc.h"
214 
215 #endif /* _NOLIBC_TYPES_H */
216