Quoting the book "The Linux Programming Interface" from Micheal Kerrisk: "the RLIMIT_NPROC limit, which places a limit on the number of processes that can be created, is measured against not just that process’s consumption of the corresponding resource, but also against the sum of resources consumed by all processes with the same real user ID."
This leads quark to easily fail on Linux when launched with the same userid of a logged user. For example if the user 'giulio' has an active desktop session, the following command: $ sudo ./quark -p 8080 -u giulio -g giulio -l fails with the following error: $ ./quark: pthread_create: Resource temporarily unavailable No error occour if instead quark is launched with an userid that does not have a session, such as the 'http' user, usually reserved for web servers. I don't know if this is expected or this could be considered a bug: in the end for production servers we could expect that the limit works correctly. In any case, the least invasive way that I have found to solve the issue is to introduce a config switch to disable the limit, retaining it enabled by default. --- Makefile | 2 +- config.def.h | 2 ++ main.c | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index da0e458..61da150 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ all: quark data.o: data.c data.h http.h util.h config.mk http.o: http.c config.h http.h util.h config.mk -main.o: main.c arg.h data.h http.h queue.h sock.h util.h config.mk +main.o: config.h main.c arg.h data.h http.h queue.h sock.h util.h config.mk sock.o: sock.c sock.h util.h config.mk util.o: util.c util.h config.mk diff --git a/config.def.h b/config.def.h index 56f62aa..7cccad2 100644 --- a/config.def.h +++ b/config.def.h @@ -4,6 +4,8 @@ #define BUFFER_SIZE 4096 #define FIELD_MAX 200 +#define ENABLE_NPROC_LIMIT 1 + /* mime-types */ static const struct { char *ext; diff --git a/main.c b/main.c index 86b2d0c..f09b5db 100644 --- a/main.c +++ b/main.c @@ -19,6 +19,7 @@ #include "arg.h" #include "data.h" +#include "config.h" #include "http.h" #include "queue.h" #include "sock.h" @@ -646,6 +647,7 @@ main(int argc, char *argv[]) } /* set the thread limit (2 + nthreads) */ +#if ENABLE_NPROC_LIMIT rlim.rlim_cur = rlim.rlim_max = 2 + nthreads; if (setrlimit(RLIMIT_NPROC, &rlim) < 0) { if (errno == EPERM) { @@ -655,6 +657,7 @@ main(int argc, char *argv[]) die("setrlimit:"); } } +#endif /* limit ourselves to reading the servedir and block further unveils */ eunveil(servedir, "r"); -- 2.30.0