Home | History | Annotate | Line # | Download | only in util
      1 /*	$NetBSD: open_limit.c,v 1.2 2025/02/25 19:15:52 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	open_limit 3
      6 /* SUMMARY
      7 /*	set/get open file limit
      8 /* SYNOPSIS
      9 /*	#include <iostuff.h>
     10 /*
     11 /*	int	open_limit(int limit)
     12 /* DESCRIPTION
     13 /*	The \fIopen_limit\fR() routine attempts to change the maximum
     14 /*	number of open files to the specified limit.  Specify a null
     15 /*	argument to effect no change. The result is the actual open file
     16 /*	limit for the current process. The number can be smaller or larger
     17 /*	than the requested limit.
     18 /* DIAGNOSTICS
     19 /*	open_limit() returns -1 in case of problems. The errno
     20 /*	variable gives hints about the nature of the problem.
     21 /* LICENSE
     22 /* .ad
     23 /* .fi
     24 /*	The Secure Mailer license must be distributed with this software.
     25 /* AUTHOR(S)
     26 /*	Wietse Venema
     27 /*	IBM T.J. Watson Research
     28 /*	P.O. Box 704
     29 /*	Yorktown Heights, NY 10598, USA
     30 /*--*/
     31 
     32 /* System libraries. */
     33 
     34 #include "sys_defs.h"
     35 #include <sys/time.h>
     36 #include <sys/resource.h>
     37 #include <errno.h>
     38 
     39 #ifdef USE_MAX_FILES_PER_PROC
     40 #include <sys/sysctl.h>
     41 #define MAX_FILES_PER_PROC      "kern.maxfilesperproc"
     42 #endif
     43 
     44 /* Application-specific. */
     45 
     46 #include "iostuff.h"
     47 
     48  /*
     49   * 44BSD compatibility.
     50   */
     51 #ifndef RLIMIT_NOFILE
     52 #ifdef RLIMIT_OFILE
     53 #define RLIMIT_NOFILE RLIMIT_OFILE
     54 #endif
     55 #endif
     56 
     57 /* open_limit - set/query file descriptor limit */
     58 
     59 int     open_limit(int limit)
     60 {
     61 #ifdef RLIMIT_NOFILE
     62     struct rlimit rl;
     63 
     64 #endif
     65 
     66     if (limit < 0) {
     67 	errno = EINVAL;
     68 	return (-1);
     69     }
     70 #ifdef RLIMIT_NOFILE
     71     if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
     72 	return (-1);
     73     if (limit > 0) {
     74 
     75 	/*
     76 	 * MacOSX incorrectly reports rlim_max as RLIM_INFINITY. The true
     77 	 * hard limit is finite and equals the kern.maxfilesperproc value.
     78 	 */
     79 #ifdef USE_MAX_FILES_PER_PROC
     80 	int     max_files_per_proc;
     81 	size_t  len = sizeof(max_files_per_proc);
     82 
     83 	if (sysctlbyname(MAX_FILES_PER_PROC, &max_files_per_proc, &len,
     84 			 (void *) 0, (size_t) 0) < 0)
     85 	    return (-1);
     86 	if (limit > max_files_per_proc)
     87 	    limit = max_files_per_proc;
     88 #endif
     89 	if (limit > rl.rlim_max)
     90 	    rl.rlim_cur = rl.rlim_max;
     91 	else
     92 	    rl.rlim_cur = limit;
     93 	if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
     94 	    return (-1);
     95     }
     96     return (rl.rlim_cur);
     97 #endif
     98 
     99 #ifndef RLIMIT_NOFILE
    100     return (getdtablesize());
    101 #endif
    102 }
    103