Reset the limits unconditionally.
authorDaniel Hokka Zakrisson <daniel@hozac.com>
Sun, 5 Nov 2006 17:46:33 +0000 (17:46 +0000)
committerDaniel Hokka Zakrisson <daniel@hozac.com>
Sun, 5 Nov 2006 17:46:33 +0000 (17:46 +0000)
Treat RLIMIT_NOFILE specially, since the kernel does.
Fix dietlibc'isms, and handle sys_old_getrlimit's values.

git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2371 94cd875c-1c1d-0410-91d2-eb244daf1a30

src/exec-ulimit.c

index 7219a9e..37f0b44 100644 (file)
 #define ENSC_WRAPPERS_RESOURCE 1
 #include <wrappers.h>
 
+/* dietlibc specifies this as (~0UL>>1), which is what's returned from
+ * sys_old_getrlimit, called on some arches for getrlimit.
+ * Reset it here so the kernel will have the correct values when we set it. */
+#undef RLIM_INFINITY
+#define RLIM_INFINITY (~0UL)
+#define OLD_RLIM_INFINITY (~0UL>>1)
+
 #define DECLARE_LIMIT(RES,FNAME) { #FNAME, RLIMIT_##RES }
 
 int    wrapper_exit_code = 255;
@@ -159,6 +166,7 @@ int main(int argc, char *argv[])
 {
   size_t               i;
   int                  cur_fd = Eopen(".", O_RDONLY, 0);
+  bool                 in_dir = false;
 
   if (argc==2) {
     if (strcmp(argv[1], "--help")==0)    showHelp(1,argv[0],0);
@@ -171,19 +179,29 @@ int main(int argc, char *argv[])
   }
 
   if (chdir(argv[1])!=-1) {
-    for (i=0; i<sizeof(LIMITS)/sizeof(LIMITS[0]); ++i) {
-      struct rlimit    limit;
-
-      Egetrlimit(LIMITS[i].code, &limit);
-      if (readSingleLimit(&limit, LIMITS[i].fname))
-       Esetrlimit(LIMITS[i].code, &limit);
-      else {
-       limit.rlim_cur = limit.rlim_max = RLIM_INFINITY;
-       Esetrlimit(LIMITS[i].code, &limit);
-      }
+    in_dir = true;
+  }
+  for (i=0; i<sizeof(LIMITS)/sizeof(LIMITS[0]); ++i) {
+    struct rlimit      limit;
+
+    Egetrlimit(LIMITS[i].code, &limit);
+    /* if this arch uses sys_old_getrlimit... */
+    if (limit.rlim_cur == OLD_RLIM_INFINITY)
+      limit.rlim_cur = RLIM_INFINITY;
+    if (in_dir && readSingleLimit(&limit, LIMITS[i].fname))
+      Esetrlimit(LIMITS[i].code, &limit);
+    else if (LIMITS[i].code != RLIMIT_NOFILE) {
+      limit.rlim_max = RLIM_INFINITY;
+      Esetrlimit(LIMITS[i].code, &limit);
+    }
+    else {
+      /* RLIMIT_NOFILE can't be set to infinity, 1024*1024 seems to be the limit in most kernels */
+      limit.rlim_max = 1024*1024;
+      setrlimit(LIMITS[i].code, &limit);
     }
-    Efchdir(cur_fd);
   }
+  if (in_dir)
+    Efchdir(cur_fd);
   Eclose(cur_fd);
 
   Eexecv(argv[2], argv+2);