about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/stdio.h7
-rw-r--r--include/sys/epoll.h12
-rw-r--r--include/syslog.h2
-rw-r--r--ldso/dynlink.c13
-rw-r--r--src/dirent/posix_getdents.c2
-rw-r--r--src/legacy/getusershell.c6
-rw-r--r--src/linux/renameat2.c11
-rw-r--r--src/network/inet_ntop.c7
-rw-r--r--src/signal/siglongjmp.c5
9 files changed, 51 insertions, 14 deletions
diff --git a/include/stdio.h b/include/stdio.h
index cb858618..4ea4c170 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -158,6 +158,13 @@ char *ctermid(char *);
 #define L_ctermid 20
 #endif
 
+#if defined(_GNU_SOURCE)
+#define RENAME_NOREPLACE (1 << 0)
+#define RENAME_EXCHANGE  (1 << 1)
+#define RENAME_WHITEOUT  (1 << 2)
+
+int renameat2(int, const char *, int, const char *, unsigned);
+#endif
 
 #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
  || defined(_BSD_SOURCE)
diff --git a/include/sys/epoll.h b/include/sys/epoll.h
index ac81a841..5f975c4a 100644
--- a/include/sys/epoll.h
+++ b/include/sys/epoll.h
@@ -7,6 +7,7 @@ extern "C" {
 
 #include <stdint.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <fcntl.h>
 
 #define __NEED_sigset_t
@@ -54,6 +55,17 @@ __attribute__ ((__packed__))
 #endif
 ;
 
+struct epoll_params {
+	uint32_t busy_poll_usecs;
+	uint16_t busy_poll_budget;
+	uint8_t prefer_busy_poll;
+
+	uint8_t __pad;
+};
+
+#define EPOLL_IOC_TYPE 0x8A
+#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params)
+#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params)
 
 int epoll_create(int);
 int epoll_create1(int);
diff --git a/include/syslog.h b/include/syslog.h
index 5b4d2964..57599e07 100644
--- a/include/syslog.h
+++ b/include/syslog.h
@@ -18,7 +18,7 @@ extern "C" {
 
 #define LOG_PRIMASK 7
 #define LOG_PRI(p) ((p)&LOG_PRIMASK)
-#define	LOG_MAKEPRI(f, p) (((f)<<3)|(p))
+#define	LOG_MAKEPRI(f, p) ((f)|(p))
 
 #define LOG_MASK(p) (1<<(p))
 #define LOG_UPTO(p) ((1<<((p)+1))-1)
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 42687da2..3b57c07f 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -362,19 +362,14 @@ static struct symdef get_lfs64(const char *name)
 		"pwritev\0readdir\0scandir\0sendfile\0setrlimit\0"
 		"stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0"
 		"__fxstat\0__fxstatat\0__lxstat\0__xstat\0";
-	size_t l;
-	char buf[16];
-	for (l=0; name[l]; l++) {
-		if (l >= sizeof buf) goto nomatch;
-		buf[l] = name[l];
-	}
 	if (!strcmp(name, "readdir64_r"))
 		return find_sym(&ldso, "readdir_r", 1);
-	if (l<2 || name[l-2]!='6' || name[l-1]!='4')
+	size_t l = strnlen(name, 18);
+	if (l<2 || name[l-2]!='6' || name[l-1]!='4' || name[l])
 		goto nomatch;
-	buf[l-=2] = 0;
 	for (p=lfs64_list; *p; p++) {
-		if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1);
+		if (!strncmp(name, p, l-2) && !p[l-2])
+			return find_sym(&ldso, p, 1);
 		while (*p) p++;
 	}
 nomatch:
diff --git a/src/dirent/posix_getdents.c b/src/dirent/posix_getdents.c
index b19e8127..26c16ac6 100644
--- a/src/dirent/posix_getdents.c
+++ b/src/dirent/posix_getdents.c
@@ -3,7 +3,7 @@
 #include <errno.h>
 #include "syscall.h"
 
-int posix_getdents(int fd, void *buf, size_t len, int flags)
+ssize_t posix_getdents(int fd, void *buf, size_t len, int flags)
 {
 	if (flags) return __syscall_ret(-EOPNOTSUPP);
 	if (len>INT_MAX) len = INT_MAX;
diff --git a/src/legacy/getusershell.c b/src/legacy/getusershell.c
index 5fecdec2..1c5d98ec 100644
--- a/src/legacy/getusershell.c
+++ b/src/legacy/getusershell.c
@@ -25,8 +25,10 @@ char *getusershell(void)
 	ssize_t l;
 	if (!f) setusershell();
 	if (!f) return 0;
-	l = getline(&line, &linesize, f);
-	if (l <= 0) return 0;
+	do {
+		l = getline(&line, &linesize, f);
+		if (l <= 0) return 0;
+	} while (line[0] == '#' || line[0] == '\n');
 	if (line[l-1]=='\n') line[l-1]=0;
 	return line;
 }
diff --git a/src/linux/renameat2.c b/src/linux/renameat2.c
new file mode 100644
index 00000000..b8060388
--- /dev/null
+++ b/src/linux/renameat2.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include "syscall.h"
+
+int renameat2(int oldfd, const char *old, int newfd, const char *new, unsigned flags)
+{
+#ifdef SYS_renameat
+	if (!flags) return syscall(SYS_renameat, oldfd, old, newfd, new);
+#endif
+	return syscall(SYS_renameat2, oldfd, old, newfd, new, flags);
+}
diff --git a/src/network/inet_ntop.c b/src/network/inet_ntop.c
index 4bfef2c5..f442f47d 100644
--- a/src/network/inet_ntop.c
+++ b/src/network/inet_ntop.c
@@ -34,7 +34,12 @@ const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen
 		for (i=best=0, max=2; buf[i]; i++) {
 			if (i && buf[i] != ':') continue;
 			j = strspn(buf+i, ":0");
-			if (j>max) best=i, max=j;
+			/* The leading sequence of zeros (best==0) is
+			 * disadvantaged compared to sequences elsewhere
+			 * as it doesn't have a leading colon. One extra
+			 * character is required for another sequence to
+			 * beat it fairly. */
+			if (j>max+(best==0)) best=i, max=j;
 		}
 		if (max>3) {
 			buf[best] = buf[best+1] = ':';
diff --git a/src/signal/siglongjmp.c b/src/signal/siglongjmp.c
index bc317acc..53789b23 100644
--- a/src/signal/siglongjmp.c
+++ b/src/signal/siglongjmp.c
@@ -5,5 +5,10 @@
 
 _Noreturn void siglongjmp(sigjmp_buf buf, int ret)
 {
+	/* If sigsetjmp was called with nonzero savemask flag, the address
+	 * longjmp will return to is inside of sigsetjmp. The signal mask
+	 * will then be restored in the returned-to context instead of here,
+	 * which matters if the context we are returning from may not have
+	 * sufficient stack space for signal delivery. */
 	longjmp(buf, ret);
 }