close(env->stderr[0]);
}
+ // Reset open file limit (http://0pointer.net/blog/file-descriptor-limits.html)
+ int r = pakfire_rlimit_reset_nofile(pakfire);
+ if (r)
+ return r;
+
// exec() command
- int r = execvpe(env->argv[0], (char**)env->argv, env->envp);
+ r = execvpe(env->argv[0], (char**)env->argv, env->envp);
if (r < 0) {
ERROR(pakfire, "Could not execve(): %s\n", strerror(errno));
}
int timespec_lt(struct timespec* t1, struct timespec* t2);
+// Resource Limits
+
+#define PAKFIRE_RLIMIT_NOFILE_MAX (512 * 1024)
+
+int pakfire_rlimit_set(Pakfire pakfire, int limit);
+int pakfire_rlimit_reset_nofile(Pakfire pakfire);
+
#endif
#endif /* PAKFIRE_UTIL_H */
if (r && errno != ENOENT)
goto ERROR;
+ // Bump RLIMIT_NOFILE to maximum
+ r = pakfire_rlimit_set(p, PAKFIRE_RLIMIT_NOFILE_MAX);
+ if (r)
+ goto ERROR;
+
DEBUG(p, "Pakfire initialized at %p\n", p);
DEBUG(p, " arch = %s\n", pakfire_get_arch(p));
DEBUG(p, " path = %s\n", pakfire_get_path(p));
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
(t1->tv_sec == t2->tv_sec && t1->tv_nsec < t2->tv_nsec)
);
}
+
+// Resource Limits
+
+int pakfire_rlimit_set(Pakfire pakfire, int limit) {
+ struct rlimit rl;
+
+ // Sanity check
+ if (limit < 3) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ // Fetch current configuration
+ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
+ ERROR(pakfire, "Could not read RLIMIT_NOFILE: %s\n", strerror(errno));
+ return 1;
+ }
+
+ // Do not attempt to set higher than maximum
+ if ((long unsigned int)limit > rl.rlim_max)
+ limit = rl.rlim_max;
+
+ rl.rlim_cur = limit;
+
+ // Set the new limit
+ if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
+ ERROR(pakfire, "Could not set RLIMIT_NOFILE to %lu: %s\n",
+ rl.rlim_cur, strerror(errno));
+ return 1;
+ }
+
+ DEBUG(pakfire, "RLIMIT_NOFILE set to %d\n", limit);
+
+ return 0;
+}
+
+/*
+ Resets RLIMIT_NOFILE to FD_SETSIZE (e.g. 1024)
+ for compatibility with software that uses select()
+*/
+int pakfire_rlimit_reset_nofile(Pakfire pakfire) {
+ return pakfire_rlimit_set(pakfire, FD_SETSIZE);
+}