about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dirent/posix_getdents.c11
-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
5 files changed, 37 insertions, 3 deletions
diff --git a/src/dirent/posix_getdents.c b/src/dirent/posix_getdents.c
new file mode 100644
index 00000000..26c16ac6
--- /dev/null
+++ b/src/dirent/posix_getdents.c
@@ -0,0 +1,11 @@
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
+#include "syscall.h"
+
+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;
+	return syscall(SYS_getdents, fd, buf, len);
+}
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);
 }