xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/open_limit.c (revision 16d67a18c4cbb2d3cb426b01120f4938ca6dbbf9)
1*16d67a18Stron /*	$NetBSD: open_limit.c,v 1.1.1.2 2014/07/06 19:27:58 tron Exp $	*/
241fbaed0Stron 
341fbaed0Stron /*++
441fbaed0Stron /* NAME
541fbaed0Stron /*	open_limit 3
641fbaed0Stron /* SUMMARY
741fbaed0Stron /*	set/get open file limit
841fbaed0Stron /* SYNOPSIS
941fbaed0Stron /*	#include <iostuff.h>
1041fbaed0Stron /*
1141fbaed0Stron /*	int	open_limit(int limit)
1241fbaed0Stron /* DESCRIPTION
1341fbaed0Stron /*	The \fIopen_limit\fR() routine attempts to change the maximum
1441fbaed0Stron /*	number of open files to the specified limit.  Specify a null
1541fbaed0Stron /*	argument to effect no change. The result is the actual open file
1641fbaed0Stron /*	limit for the current process. The number can be smaller or larger
1741fbaed0Stron /*	than the requested limit.
1841fbaed0Stron /* DIAGNOSTICS
1941fbaed0Stron /*	open_limit() returns -1 in case of problems. The errno
2041fbaed0Stron /*	variable gives hints about the nature of the problem.
2141fbaed0Stron /* LICENSE
2241fbaed0Stron /* .ad
2341fbaed0Stron /* .fi
2441fbaed0Stron /*	The Secure Mailer license must be distributed with this software.
2541fbaed0Stron /* AUTHOR(S)
2641fbaed0Stron /*	Wietse Venema
2741fbaed0Stron /*	IBM T.J. Watson Research
2841fbaed0Stron /*	P.O. Box 704
2941fbaed0Stron /*	Yorktown Heights, NY 10598, USA
3041fbaed0Stron /*--*/
3141fbaed0Stron 
3241fbaed0Stron /* System libraries. */
3341fbaed0Stron 
3441fbaed0Stron #include "sys_defs.h"
3541fbaed0Stron #include <sys/time.h>
3641fbaed0Stron #include <sys/resource.h>
3741fbaed0Stron #include <errno.h>
3841fbaed0Stron 
39*16d67a18Stron #ifdef USE_MAX_FILES_PER_PROC
40*16d67a18Stron #include <sys/sysctl.h>
41*16d67a18Stron #define MAX_FILES_PER_PROC      "kern.maxfilesperproc"
42*16d67a18Stron #endif
43*16d67a18Stron 
4441fbaed0Stron /* Application-specific. */
4541fbaed0Stron 
4641fbaed0Stron #include "iostuff.h"
4741fbaed0Stron 
4841fbaed0Stron  /*
4941fbaed0Stron   * 44BSD compatibility.
5041fbaed0Stron   */
5141fbaed0Stron #ifndef RLIMIT_NOFILE
5241fbaed0Stron #ifdef RLIMIT_OFILE
5341fbaed0Stron #define RLIMIT_NOFILE RLIMIT_OFILE
5441fbaed0Stron #endif
5541fbaed0Stron #endif
5641fbaed0Stron 
5741fbaed0Stron /* open_limit - set/query file descriptor limit */
5841fbaed0Stron 
open_limit(int limit)5941fbaed0Stron int     open_limit(int limit)
6041fbaed0Stron {
6141fbaed0Stron #ifdef RLIMIT_NOFILE
6241fbaed0Stron     struct rlimit rl;
6341fbaed0Stron #endif
6441fbaed0Stron 
6541fbaed0Stron     if (limit < 0) {
6641fbaed0Stron 	errno = EINVAL;
6741fbaed0Stron 	return (-1);
6841fbaed0Stron     }
6941fbaed0Stron #ifdef RLIMIT_NOFILE
7041fbaed0Stron     if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
7141fbaed0Stron 	return (-1);
7241fbaed0Stron     if (limit > 0) {
73*16d67a18Stron 
74*16d67a18Stron 	/*
75*16d67a18Stron 	 * MacOSX incorrectly reports rlim_max as RLIM_INFINITY. The true
76*16d67a18Stron 	 * hard limit is finite and equals the kern.maxfilesperproc value.
77*16d67a18Stron 	 */
78*16d67a18Stron #ifdef USE_MAX_FILES_PER_PROC
79*16d67a18Stron 	int     max_files_per_proc;
80*16d67a18Stron 	size_t  len = sizeof(max_files_per_proc);
81*16d67a18Stron 
82*16d67a18Stron 	if (sysctlbyname(MAX_FILES_PER_PROC, &max_files_per_proc, &len,
83*16d67a18Stron 			 (void *) 0, (size_t) 0) < 0)
84*16d67a18Stron 	    return (-1);
85*16d67a18Stron 	if (limit > max_files_per_proc)
86*16d67a18Stron 	    limit = max_files_per_proc;
87*16d67a18Stron #endif
8841fbaed0Stron 	if (limit > rl.rlim_max)
8941fbaed0Stron 	    rl.rlim_cur = rl.rlim_max;
9041fbaed0Stron 	else
9141fbaed0Stron 	    rl.rlim_cur = limit;
9241fbaed0Stron 	if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
9341fbaed0Stron 	    return (-1);
9441fbaed0Stron     }
9541fbaed0Stron     return (rl.rlim_cur);
9641fbaed0Stron #endif
9741fbaed0Stron 
9841fbaed0Stron #ifndef RLIMIT_NOFILE
9941fbaed0Stron     return (getdtablesize());
10041fbaed0Stron #endif
10141fbaed0Stron }
10241fbaed0Stron 
103