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/mman.h>
12  #include <linux/reboot.h> /* for LINUX_REBOOT_* */
13  #include <linux/stat.h>
14  #include <linux/time.h>
15  #include <linux/wait.h>
16  #include <linux/resource.h>
17  
18  
19  /* Only the generic macros and types may be defined here. The arch-specific
20   * ones such as the O_RDONLY and related macros used by fcntl() and open()
21   * must not be defined here.
22   */
23  
24  /* stat flags (WARNING, octal here). We need to check for an existing
25   * definition because linux/stat.h may omit to define those if it finds
26   * that any glibc header was already included.
27   */
28  #if !defined(S_IFMT)
29  #define S_IFDIR        0040000
30  #define S_IFCHR        0020000
31  #define S_IFBLK        0060000
32  #define S_IFREG        0100000
33  #define S_IFIFO        0010000
34  #define S_IFLNK        0120000
35  #define S_IFSOCK       0140000
36  #define S_IFMT         0170000
37  
38  #define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
39  #define S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
40  #define S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
41  #define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
42  #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
43  #define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
44  #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
45  
46  #define S_IRWXU 00700
47  #define S_IRUSR 00400
48  #define S_IWUSR 00200
49  #define S_IXUSR 00100
50  
51  #define S_IRWXG 00070
52  #define S_IRGRP 00040
53  #define S_IWGRP 00020
54  #define S_IXGRP 00010
55  
56  #define S_IRWXO 00007
57  #define S_IROTH 00004
58  #define S_IWOTH 00002
59  #define S_IXOTH 00001
60  #endif
61  
62  /* dirent types */
63  #define DT_UNKNOWN     0x0
64  #define DT_FIFO        0x1
65  #define DT_CHR         0x2
66  #define DT_DIR         0x4
67  #define DT_BLK         0x6
68  #define DT_REG         0x8
69  #define DT_LNK         0xa
70  #define DT_SOCK        0xc
71  
72  /* commonly an fd_set represents 256 FDs */
73  #ifndef FD_SETSIZE
74  #define FD_SETSIZE     256
75  #endif
76  
77  /* PATH_MAX and MAXPATHLEN are often used and found with plenty of different
78   * values.
79   */
80  #ifndef PATH_MAX
81  #define PATH_MAX       4096
82  #endif
83  
84  #ifndef MAXPATHLEN
85  #define MAXPATHLEN     (PATH_MAX)
86  #endif
87  
88  /* flags for mmap */
89  #ifndef MAP_FAILED
90  #define MAP_FAILED ((void *)-1)
91  #endif
92  
93  /* whence values for lseek() */
94  #define SEEK_SET       0
95  #define SEEK_CUR       1
96  #define SEEK_END       2
97  
98  /* flags for reboot */
99  #define RB_AUTOBOOT     LINUX_REBOOT_CMD_RESTART
100  #define RB_HALT_SYSTEM  LINUX_REBOOT_CMD_HALT
101  #define RB_ENABLE_CAD   LINUX_REBOOT_CMD_CAD_ON
102  #define RB_DISABLE_CAD  LINUX_REBOOT_CMD_CAD_OFF
103  #define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF
104  #define RB_SW_SUSPEND   LINUX_REBOOT_CMD_SW_SUSPEND
105  #define RB_KEXEC        LINUX_REBOOT_CMD_KEXEC
106  
107  /* Macros used on waitpid()'s return status */
108  #define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
109  #define WIFEXITED(status)   (((status) & 0x7f) == 0)
110  #define WTERMSIG(status)    ((status) & 0x7f)
111  #define WIFSIGNALED(status) ((status) - 1 < 0xff)
112  
113  /* standard exit() codes */
114  #define EXIT_SUCCESS 0
115  #define EXIT_FAILURE 1
116  
117  #define FD_SETIDXMASK (8 * sizeof(unsigned long))
118  #define FD_SETBITMASK (8 * sizeof(unsigned long)-1)
119  
120  /* for select() */
121  typedef struct {
122  	unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK];
123  } fd_set;
124  
125  #define FD_CLR(fd, set) do {						\
126  		fd_set *__set = (set);					\
127  		int __fd = (fd);					\
128  		if (__fd >= 0)						\
129  			__set->fds[__fd / FD_SETIDXMASK] &=		\
130  				~(1U << (__fd & FX_SETBITMASK));	\
131  	} while (0)
132  
133  #define FD_SET(fd, set) do {						\
134  		fd_set *__set = (set);					\
135  		int __fd = (fd);					\
136  		if (__fd >= 0)						\
137  			__set->fds[__fd / FD_SETIDXMASK] |=		\
138  				1 << (__fd & FD_SETBITMASK);		\
139  	} while (0)
140  
141  #define FD_ISSET(fd, set) ({						\
142  			fd_set *__set = (set);				\
143  			int __fd = (fd);				\
144  		int __r = 0;						\
145  		if (__fd >= 0)						\
146  			__r = !!(__set->fds[__fd / FD_SETIDXMASK] &	\
147  1U << (__fd & FD_SET_BITMASK));						\
148  		__r;							\
149  	})
150  
151  #define FD_ZERO(set) do {						\
152  		fd_set *__set = (set);					\
153  		int __idx;						\
154  		int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\
155  		for (__idx = 0; __idx < __size; __idx++)		\
156  			__set->fds[__idx] = 0;				\
157  	} while (0)
158  
159  /* for poll() */
160  #define POLLIN          0x0001
161  #define POLLPRI         0x0002
162  #define POLLOUT         0x0004
163  #define POLLERR         0x0008
164  #define POLLHUP         0x0010
165  #define POLLNVAL        0x0020
166  
167  struct pollfd {
168  	int fd;
169  	short int events;
170  	short int revents;
171  };
172  
173  /* for getdents64() */
174  struct linux_dirent64 {
175  	uint64_t       d_ino;
176  	int64_t        d_off;
177  	unsigned short d_reclen;
178  	unsigned char  d_type;
179  	char           d_name[];
180  };
181  
182  /* The format of the struct as returned by the libc to the application, which
183   * significantly differs from the format returned by the stat() syscall flavours.
184   */
185  struct stat {
186  	dev_t     st_dev;     /* ID of device containing file */
187  	ino_t     st_ino;     /* inode number */
188  	mode_t    st_mode;    /* protection */
189  	nlink_t   st_nlink;   /* number of hard links */
190  	uid_t     st_uid;     /* user ID of owner */
191  	gid_t     st_gid;     /* group ID of owner */
192  	dev_t     st_rdev;    /* device ID (if special file) */
193  	off_t     st_size;    /* total size, in bytes */
194  	blksize_t st_blksize; /* blocksize for file system I/O */
195  	blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
196  	union { time_t st_atime; struct timespec st_atim; }; /* time of last access */
197  	union { time_t st_mtime; struct timespec st_mtim; }; /* time of last modification */
198  	union { time_t st_ctime; struct timespec st_ctim; }; /* time of last status change */
199  };
200  
201  /* WARNING, it only deals with the 4096 first majors and 256 first minors */
202  #define makedev(major, minor) ((dev_t)((((major) & 0xfff) << 8) | ((minor) & 0xff)))
203  #define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff))
204  #define minor(dev) ((unsigned int)(((dev) & 0xff))
205  
206  #ifndef offsetof
207  #define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD)
208  #endif
209  
210  #ifndef container_of
211  #define container_of(PTR, TYPE, FIELD) ({			\
212  	__typeof__(((TYPE *)0)->FIELD) *__FIELD_PTR = (PTR);	\
213  	(TYPE *)((char *) __FIELD_PTR - offsetof(TYPE, FIELD));	\
214  })
215  #endif
216  
217  /* make sure to include all global symbols */
218  #include "nolibc.h"
219  
220  #endif /* _NOLIBC_TYPES_H */
221