Check-in [fdf89fd103]
Overview
Comment:Cleaned up code in preparation for Windows build
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:fdf89fd103aeacbfb6114a7c8827763449d296b1
User & Date: rkeene on 2019-12-13 00:33:36
Other Links: manifest | tags
Context
2019-12-13
00:34
AppFS 1.12 check-in: d7fb4b713a user: rkeene tags: trunk, 1.12
00:33
Cleaned up code in preparation for Windows build check-in: fdf89fd103 user: rkeene tags: trunk
00:11
Updated root CA certificate, the previous one expired, and made errors about this more informative check-in: 7241c0986c user: rkeene tags: trunk
Changes

Modified appfsd.c from [b7dddfc0b8] to [0494c72e1d].

    17     17    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18     18    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19     19    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    20     20    * THE SOFTWARE.
    21     21    */
    22     22   #define FUSE_USE_VERSION 26
    23     23   
    24         -#include <sys/resource.h>  
    25     24   #include <sys/fsuid.h>
    26     25   #include <sys/types.h>
    27     26   #include <sys/time.h>
    28     27   #include <pthread.h>
    29         -#include <signal.h>
    30     28   #include <limits.h>
    31     29   #include <string.h>
    32     30   #include <stdarg.h>
    33     31   #include <stdlib.h>
    34     32   #include <unistd.h>
    35     33   #include <errno.h>
    36     34   #include <fcntl.h>
................................................................................
    44     42    */
    45     43   #ifndef APPFS_CACHEDIR
    46     44   #define APPFS_CACHEDIR "/var/cache/appfs"
    47     45   #endif
    48     46   
    49     47   /* Debugging macros */
    50     48   #ifdef DEBUG
    51         -int appfs_debug_fd = STDERR_FILENO;
           49  +FILE *appfs_debug_fd = NULL;
    52     50   #define APPFS_DEBUG(x...) { \
    53     51   	char buf[8192]; \
    54     52   	int bufoff = 0; \
    55         -	if (appfs_debug_fd == -1) { \
    56         -		appfs_debug_fd = open("/tmp/appfsd.log", O_WRONLY | O_APPEND | O_CREAT, 0600); \
           53  +	if (appfs_debug_fd == NULL) { \
           54  +		appfs_debug_fd = fopen("/tmp/appfsd.log", "a"); \
    57     55   	}; \
           56  +	if (appfs_debug_fd == NULL) { appfs_debug_fd = stderr; } \
    58     57   	bufoff = snprintf(buf, sizeof(buf), "[debug] [t=%llx] %s:%i:%s: ", (unsigned long long) pthread_self(), __FILE__, __LINE__, __func__); \
    59     58   	if (bufoff < sizeof(buf)) { \
    60     59   		bufoff += snprintf(buf + bufoff, sizeof(buf) - bufoff, x); \
    61     60   	}; \
    62     61   	if (bufoff < sizeof(buf)) { \
    63     62   		bufoff += snprintf(buf + bufoff, sizeof(buf) - bufoff, "\n");\
    64     63   	} \
    65     64   	if (bufoff > sizeof(buf)) { \
    66     65   		bufoff = sizeof(buf); \
    67     66   	}; \
    68         -	write(appfs_debug_fd, buf, bufoff); \
           67  +	fprintf(appfs_debug_fd, "%.*s", bufoff, buf); \
           68  +	fflush(appfs_debug_fd); \
    69     69   }
           70  +#define APPFS_ERROR(x...) APPFS_DEBUG(x)
    70     71   #else
    71     72   #define APPFS_DEBUG(x...) /**/
           73  +#define APPFS_ERROR(x...) fprintf(stderr, x); fprintf(stderr, "\n");
    72     74   #endif
    73     75   
    74     76   /*
    75     77    * SHA1 Tcl Package initializer, from sha1.o
    76     78    */
    77     79   int Sha1_Init(Tcl_Interp *interp);
    78     80   
................................................................................
    93     95   /*
    94     96    * Global variables for AppFS caching
    95     97    */
    96     98   pthread_mutex_t appfs_path_info_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
    97     99   int appfs_path_info_cache_size = 8209;
    98    100   struct appfs_pathinfo *appfs_path_info_cache = NULL;
    99    101   
   100         -#ifndef TCL_THREADS
          102  +#if !defined(TCL_THREADS) || TCL_THREADS != 1
   101    103   /*
   102    104    * Handle unthreaded Tcl
   103    105    */
   104    106   pthread_mutex_t appfs_tcl_big_global_lock = PTHREAD_MUTEX_INITIALIZER;
   105    107   #define appfs_call_libtcl_enter pthread_mutex_lock(&appfs_tcl_big_global_lock);
   106    108   #define appfs_call_libtcl_exit pthread_mutex_unlock(&appfs_tcl_big_global_lock);
   107    109   #else
................................................................................
   170    172   
   171    173   	APPFS_DEBUG("Creating new Tcl interpreter for TID = 0x%llx", (unsigned long long) pthread_self());
   172    174   
   173    175   	appfs_call_libtcl(
   174    176   		interp = Tcl_CreateInterp();
   175    177   	)
   176    178   	if (interp == NULL) {
   177         -		fprintf(stderr, "Unable to create Tcl Interpreter.  Aborting.\n");
          179  +		APPFS_ERROR("Unable to create Tcl Interpreter.  Aborting.");
   178    180   
   179    181   		if (error_string) {
   180    182   			*error_string = strdup("Unable to create Tcl interpreter.");
   181    183   		}
   182    184   
   183    185   		return(NULL);
   184    186   	}
................................................................................
   185    187   
   186    188   	appfs_call_libtcl(Tcl_Preserve(interp);)
   187    189   
   188    190   	appfs_call_libtcl(
   189    191   		tcl_ret = Tcl_Init(interp);
   190    192   	)
   191    193   	if (tcl_ret != TCL_OK) {
   192         -		fprintf(stderr, "Unable to initialize Tcl.  Aborting.\n");
          194  +		APPFS_ERROR("Unable to initialize Tcl.  Aborting.");
   193    195   		appfs_call_libtcl(
   194         -			fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
          196  +			APPFS_ERROR("Tcl Error is: %s", Tcl_GetStringResult(interp));
   195    197   		)
   196    198   
   197    199   		if (error_string) {
   198    200   			appfs_call_libtcl(
   199    201   				*error_string = strdup(Tcl_GetStringResult(interp));
   200    202   			)
   201    203   		}
................................................................................
   209    211   		return(NULL);
   210    212   	}
   211    213   
   212    214   	appfs_call_libtcl(
   213    215   		tcl_ret = Tcl_Eval(interp, "package ifneeded sha1 1.0 [list load {} sha1]");
   214    216   	)
   215    217   	if (tcl_ret != TCL_OK) {
   216         -		fprintf(stderr, "Unable to initialize Tcl SHA1.  Aborting.\n");
          218  +		APPFS_ERROR("Unable to initialize Tcl SHA1.  Aborting.");
   217    219   		appfs_call_libtcl(
   218         -			fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
          220  +			APPFS_ERROR("Tcl Error is: %s", Tcl_GetStringResult(interp));
   219    221   		)
   220    222   
   221    223   		if (error_string) {
   222    224   			appfs_call_libtcl(
   223    225   				*error_string = strdup(Tcl_GetStringResult(interp));
   224    226   			)
   225    227   		}
................................................................................
   233    235   		return(NULL);
   234    236   	}
   235    237   
   236    238   	appfs_call_libtcl(
   237    239   		tcl_ret = Tcl_Eval(interp, "package ifneeded appfsd 1.0 [list load {} appfsd]");
   238    240   	)
   239    241   	if (tcl_ret != TCL_OK) {
   240         -		fprintf(stderr, "Unable to initialize Tcl AppFS Package.  Aborting.\n");
          242  +		APPFS_ERROR("Unable to initialize Tcl AppFS Package.  Aborting.");
   241    243   		appfs_call_libtcl(
   242         -			fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
          244  +			APPFS_ERROR("Tcl Error is: %s", Tcl_GetStringResult(interp));
   243    245   		)
   244    246   
   245    247   		if (error_string) {
   246    248   			appfs_call_libtcl(
   247    249   				*error_string = strdup(Tcl_GetStringResult(interp));
   248    250   			)
   249    251   		}
................................................................................
   262    264   	 */
   263    265   	appfs_call_libtcl_enter
   264    266   		tcl_ret = Tcl_Eval(interp, ""
   265    267   #include "pki.tcl.h"
   266    268   		"");
   267    269   	appfs_call_libtcl_exit
   268    270   	if (tcl_ret != TCL_OK) {
   269         -		fprintf(stderr, "Unable to initialize Tcl PKI.  Aborting.\n");
          271  +		APPFS_ERROR("Unable to initialize Tcl PKI.  Aborting.");
   270    272   		appfs_call_libtcl(
   271         -			fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
          273  +			APPFS_ERROR("Tcl Error is: %s", Tcl_GetStringResult(interp));
   272    274   		)
   273    275   
   274    276   		if (error_string) {
   275    277   			appfs_call_libtcl(
   276    278   				*error_string = strdup(Tcl_GetStringResult(interp));
   277    279   			)
   278    280   		}
................................................................................
   293    295   	 */
   294    296   	appfs_call_libtcl_enter
   295    297   		tcl_ret = Tcl_Eval(interp, ""
   296    298   #include "appfsd.tcl.h"
   297    299   		"");
   298    300   	appfs_call_libtcl_exit
   299    301   	if (tcl_ret != TCL_OK) {
   300         -		fprintf(stderr, "Unable to initialize Tcl AppFS script.  Aborting.\n");
          302  +		APPFS_ERROR("Unable to initialize Tcl AppFS script.  Aborting.");
   301    303   		appfs_call_libtcl(
   302         -			fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
          304  +			APPFS_ERROR("Tcl Error is: %s", Tcl_GetStringResult(interp));
   303    305   		)
   304    306   
   305    307   		if (error_string) {
   306    308   			appfs_call_libtcl(
   307    309   				*error_string = strdup(Tcl_GetStringResult(interp));
   308    310   			)
   309    311   		}
................................................................................
   320    322   	/*
   321    323   	 * Set global variables from C to Tcl
   322    324   	 */
   323    325   	appfs_call_libtcl(
   324    326   		tcl_setvar_ret = Tcl_SetVar(interp, "::appfs::cachedir", appfs_cachedir, TCL_GLOBAL_ONLY);
   325    327   	)
   326    328   	if (tcl_setvar_ret == NULL) {
   327         -		fprintf(stderr, "Unable to set cache directory.  This should never fail.\n");
          329  +		APPFS_ERROR("Unable to set cache directory.  This should never fail.");
   328    330   
   329    331   		if (error_string) {
   330    332   			appfs_call_libtcl(
   331    333   				*error_string = strdup(Tcl_GetStringResult(interp));
   332    334   			)
   333    335   		}
   334    336   
................................................................................
   345    347   	 * Initialize the "appfsd.tcl" environment, which must be done after
   346    348   	 * global variables are set.
   347    349   	 */
   348    350   	appfs_call_libtcl(
   349    351   		tcl_ret = Tcl_Eval(interp, "::appfs::init");
   350    352   	)
   351    353   	if (tcl_ret != TCL_OK) {
   352         -		fprintf(stderr, "Unable to initialize Tcl AppFS script (::appfs::init).  Aborting.\n");
          354  +		APPFS_ERROR("Unable to initialize Tcl AppFS script (::appfs::init).  Aborting.");
   353    355   		appfs_call_libtcl(
   354         -			fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp));
          356  +			APPFS_ERROR("Tcl Error is: %s", Tcl_GetStringResult(interp));
   355    357   		)
   356    358   
   357    359   		if (error_string) {
   358    360   			appfs_call_libtcl(
   359    361   				*error_string = strdup(Tcl_GetStringResult(interp));
   360    362   			)
   361    363   		}
................................................................................
   562    564   }
   563    565   
   564    566   static void appfs_simulate_user_fs_leave(void) {
   565    567   	setfsuid(0);
   566    568   	setfsgid(0);
   567    569   }
   568    570   
          571  +#ifdef APPFS_NO_GETPWUID
          572  +static char *appfs_get_homedir(uid_t fsuid) {
          573  +	return(NULL);
          574  +}
          575  +#else
   569    576   /*
   570    577    * Look up the home directory for a given UID
   571    578    *        Returns a C string containing the user's home directory or NULL if
   572    579    *        the user's home directory does not exist or is not correctly
   573    580    *        configured
   574    581    */
   575    582   static char *appfs_get_homedir(uid_t fsuid) {
................................................................................
   614    621   		return(NULL);
   615    622   	}
   616    623   
   617    624   	retval = strdup(result->pw_dir);
   618    625   
   619    626   	return(retval);
   620    627   }
          628  +#endif
   621    629   
   622    630   /*
   623    631    * Generate an inode for a given path.  The inode should be computed in such
   624    632    * a way that it is unlikely to be duplicated and remains the same for a given
   625    633    * file
   626    634    *
   627    635    * Current implementation is an FNV-1a 32-bit
................................................................................
  1517   1525   	int retval;
  1518   1526   
  1519   1527   	APPFS_DEBUG("Enter (path = %s, buf, size = %lli, offset = %lli, fd = %lli)", path, (long long) size, (long long) offset, (long long) fi->fh);
  1520   1528   
  1521   1529   	retval = 0;
  1522   1530   
  1523   1531   	while (size != 0) {
         1532  +#ifdef APPFS_NO_PREAD /* XXX:TODO: Write a wrapper function */
         1533  +		off_t seek_ret;
         1534  +
         1535  +		seek_ret = lseek(fi->fh, offset, SEEK_SET);
         1536  +		if (seek_ret == offset) {
         1537  +			read_ret = read(fi->fh, buf, size);
         1538  +		} else {
         1539  +			read_ret = -1;
         1540  +		}
         1541  +#else
  1524   1542   		read_ret = pread(fi->fh, buf, size, offset);
         1543  +#endif
  1525   1544   
  1526   1545   		if (read_ret < 0) {
  1527   1546   			APPFS_DEBUG("error: read failed");
  1528   1547   
  1529   1548   			return(errno * -1);
  1530   1549   		}
  1531   1550   
................................................................................
  1563   1582   #endif
  1564   1583   
  1565   1584   	appfs_get_path_info_cache_rm(path, appfs_get_fsuid());
  1566   1585   
  1567   1586   	retval = 0;
  1568   1587   
  1569   1588   	while (size != 0) {
         1589  +#ifdef APPFS_NO_PWRITE /* XXX:TODO: Write a wrapper function */
         1590  +#  if 1
         1591  +		/* XXX:TODO: Still fails on win32 */
         1592  +		write_ret = -1;
         1593  +#else
         1594  +		off_t seek_ret;
         1595  +
         1596  +		seek_ret = lseek(fi->fh, offset, SEEK_SET);
         1597  +		if (seek_ret == offset) {
         1598  +			write_ret = write(fi->fh, buf, size); 
         1599  +		} else {
         1600  +			write_ret = -1;
         1601  +		}
         1602  +#  endif
         1603  +#else
  1570   1604   		write_ret = pwrite(fi->fh, buf, size, offset);
         1605  +#endif
  1571   1606   
  1572   1607   		if (write_ret < 0) {
  1573   1608   			APPFS_DEBUG("error: write failed");
  1574   1609   
  1575   1610   			return(errno * -1);
  1576   1611   		}
  1577   1612   
................................................................................
  1835   1870   static int appfs_sqlite3(const char *sql) {
  1836   1871   	Tcl_Interp *interp;
  1837   1872   	const char *sql_ret;
  1838   1873   	int tcl_ret;
  1839   1874   
  1840   1875   	interp = appfs_create_TclInterp(NULL);
  1841   1876   	if (interp == NULL) {
  1842         -		fprintf(stderr, "Unable to create a Tcl interpreter.  Aborting.\n");
         1877  +		APPFS_ERROR("Unable to create a Tcl interpreter.  Aborting.");
  1843   1878   
  1844   1879   		return(1);
  1845   1880   	}
  1846   1881   
  1847   1882   	tcl_ret = appfs_Tcl_Eval(interp, 5, "::appfs::db", "eval", sql, "row", "unset -nocomplain row(*); parray row; puts \"----\"");
  1848   1883   	sql_ret = Tcl_GetStringResult(interp);
  1849   1884   
  1850   1885   	if (tcl_ret != TCL_OK) {
  1851         -		fprintf(stderr, "[error] %s\n", sql_ret);
         1886  +		APPFS_ERROR("[error] %s", sql_ret);
  1852   1887   
  1853   1888   		return(1);
  1854   1889   	}
  1855   1890   
  1856   1891   	if (sql_ret && sql_ret[0] != '\0') {
  1857   1892   		printf("%s\n", sql_ret);
  1858   1893   	}
................................................................................
  1866   1901   static int appfs_tcl(const char *tcl) {
  1867   1902   	Tcl_Interp *interp;
  1868   1903   	const char *tcl_result;
  1869   1904   	int tcl_ret;
  1870   1905   
  1871   1906   	interp = appfs_create_TclInterp(NULL);
  1872   1907   	if (interp == NULL) {
  1873         -		fprintf(stderr, "Unable to create a Tcl interpreter.  Aborting.\n");
         1908  +		APPFS_ERROR("Unable to create a Tcl interpreter.  Aborting.");
  1874   1909   
  1875   1910   		return(1);
  1876   1911   	}
  1877   1912   
  1878   1913   	tcl_ret = Tcl_Eval(interp, tcl);
  1879   1914   	tcl_result = Tcl_GetStringResult(interp);
  1880   1915   
  1881   1916   	if (tcl_ret != TCL_OK) {
  1882         -		fprintf(stderr, "[error] %s\n", Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY));
         1917  +		APPFS_ERROR("[error] %s", Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY));
  1883   1918   
  1884   1919   		return(1);
  1885   1920   	}
  1886   1921   
  1887   1922   	if (tcl_result && tcl_result[0] != '\0') {
  1888   1923   		printf("%s\n", tcl_result);
  1889   1924   	}
................................................................................
  2016   2051   	Tcl_CreateObjCommand(interp, "appfsd::get_path_info_cache_flush", tcl_appfs_get_path_info_cache_flush, NULL, NULL);
  2017   2052   
  2018   2053   	Tcl_PkgProvide(interp, "appfsd", "1.0");
  2019   2054   
  2020   2055   	return(TCL_OK);
  2021   2056   }
  2022   2057   
         2058  +#ifdef APPFS_NO_SIGNALS
         2059  +static void appfs_set_sighandler(void) {
         2060  +	return;
         2061  +}
         2062  +#else
         2063  +#include <signal.h>
         2064  +
  2023   2065   /*
  2024   2066    * Hot-restart support
  2025   2067    */
  2026   2068   /* Initiate a hot-restart */
  2027   2069   static void appfs_hot_restart(void) {
  2028   2070   	APPFS_DEBUG("Asked to initiate hot restart");
  2029   2071   
................................................................................
  2048   2090   	if (sig == SIGHUP) {
  2049   2091   		appfs_hot_restart();
  2050   2092   	}
  2051   2093   
  2052   2094   	return;
  2053   2095   }
  2054   2096   
         2097  +static void appfs_set_sighandler(void) {
         2098  +	void *signal_ret;
         2099  +
         2100  +	/*
         2101  +	 * Register a signal handler for hot-restart requests
         2102  +	 */
         2103  +	signal_ret = signal(SIGHUP, appfs_signal_handler);
         2104  +	if (signal_ret == SIG_ERR) {
         2105  +		APPFS_ERROR("Unable to install signal handler for hot-restart");
         2106  +		APPFS_ERROR("Hot-restart will not be available.");
         2107  +	}
         2108  +}
         2109  +#endif
  2055   2110   /*
  2056   2111    * Terminate a thread
  2057   2112    */
  2058   2113   static void appfs_terminate_interp_and_thread(void *_interp) {
  2059   2114   	Tcl_Interp *interp;
  2060   2115   
  2061   2116   	APPFS_DEBUG("Called: _interp = %p", _interp);
................................................................................
  2101   2156   	int ch;
  2102   2157   	char *optstr, *optstr_next, *optstr_s;
  2103   2158   	char fake_arg[3] = {'-', 0, 0};
  2104   2159   
  2105   2160   	/*
  2106   2161   	 * Default values
  2107   2162   	 */
  2108         -#ifdef TCL_THREADS
         2163  +#if defined(TCL_THREADS) && TCL_THREADS == 1
  2109   2164   	appfs_threaded_tcl = 1;
  2110   2165   #else
  2111   2166   	appfs_threaded_tcl = 0;
  2112   2167   #endif
  2113   2168   
  2114   2169   	/**
  2115   2170   	 ** Add FUSE arguments which we always supply
................................................................................
  2160   2215   						APPFS_DEBUG("Passing option to FUSE: -o allow_other");
  2161   2216   
  2162   2217   						fuse_opt_parse(args, NULL, NULL, NULL);
  2163   2218   						fuse_opt_add_arg(args, "-oallow_other");
  2164   2219   					} else if (strcmp(optstr, "rw") == 0) {
  2165   2220   						/* Ignored */
  2166   2221   					} else {
  2167         -						fprintf(stderr, "appfsd: invalid option: \"-o %s\"\n", optstr);
         2222  +						APPFS_ERROR("appfsd: invalid option: \"-o %s\"", optstr);
  2168   2223   
  2169   2224   						free(optstr_s);
  2170   2225   
  2171   2226   						return(1);
  2172   2227   					}
  2173   2228   				}
  2174   2229   
................................................................................
  2200   2255   
  2201   2256   				return(1);
  2202   2257   		}
  2203   2258   	}
  2204   2259   
  2205   2260   	if ((optind + 2) != argc) {
  2206   2261   		if ((optind + 2) < argc) {
  2207         -			fprintf(stderr, "Too many arguments\n");
         2262  +			APPFS_ERROR("Too many arguments");
  2208   2263   		} else {
  2209         -			fprintf(stderr, "Missing cachedir or mountpoint\n");
         2264  +			APPFS_ERROR("Missing cachedir or mountpoint");
  2210   2265   		}
  2211   2266   
  2212   2267   		appfs_print_help(stderr);
  2213   2268   
  2214   2269   		return(1);
  2215   2270   	}
  2216   2271   
................................................................................
  2246   2301   	.unlink    = appfs_fuse_unlink_rmdir,
  2247   2302   	.rmdir     = appfs_fuse_unlink_rmdir,
  2248   2303   	.mkdir     = appfs_fuse_mkdir,
  2249   2304   	.chmod     = appfs_fuse_chmod,
  2250   2305   	.symlink   = appfs_fuse_symlink,
  2251   2306   };
  2252   2307   
         2308  +
         2309  +#ifdef APPFS_NO_RLIMIT
         2310  +static void appfs_set_resource_limits(void) {
         2311  +	return;
         2312  +}
         2313  +#else
         2314  +#include <sys/resource.h>  
         2315  +
         2316  +static void appfs_set_resource_limits(void) {
         2317  +	struct rlimit number_open_files;
         2318  +	rlim_t number_open_files_max;
         2319  +	int rlimit_ret;
         2320  +
         2321  +	/*
         2322  +	 * Increase resource limits for number of open files
         2323  +	 * to the maximum values, since we may be asked to
         2324  +	 * hold open many files on behalf of many other processes
         2325  +	 */
         2326  +	number_open_files.rlim_cur = number_open_files.rlim_max = RLIM_INFINITY;
         2327  +
         2328  +	rlimit_ret = setrlimit(RLIMIT_NOFILE, &number_open_files);
         2329  +
         2330  +	if (rlimit_ret != 0) {
         2331  +		rlimit_ret = getrlimit(RLIMIT_NOFILE, &number_open_files);
         2332  +		if (rlimit_ret == 0) {
         2333  +			number_open_files_max = number_open_files.rlim_max;
         2334  +
         2335  +			if (number_open_files_max < (1024 * 1024)) {
         2336  +				number_open_files.rlim_cur = number_open_files.rlim_max = 1024 * 1024;
         2337  +
         2338  +				rlimit_ret = setrlimit(RLIMIT_NOFILE, &number_open_files);
         2339  +			} else {
         2340  +				number_open_files.rlim_cur = number_open_files.rlim_max;
         2341  +			}
         2342  +
         2343  +			rlimit_ret = setrlimit(RLIMIT_NOFILE, &number_open_files);
         2344  +
         2345  +			if (rlimit_ret != 0 && number_open_files.rlim_cur != number_open_files_max) {
         2346  +				number_open_files.rlim_cur = number_open_files.rlim_max = number_open_files_max;
         2347  +
         2348  +				setrlimit(RLIMIT_NOFILE, &number_open_files);
         2349  +			}
         2350  +		}
         2351  +	}
         2352  +
         2353  +	return;
         2354  +}
         2355  +#endif
         2356  +
  2253   2357   /*
  2254   2358    * Entry point into this program.
  2255   2359    */
  2256   2360   int main(int argc, char **argv) {
  2257   2361   	Tcl_Interp *test_interp;
  2258   2362   	char *test_interp_error;
  2259   2363   	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
  2260         -	struct rlimit number_open_files;
  2261         -	int pthread_ret, aop_ret, rlimit_ret;
  2262         -	void *signal_ret;
         2364  +	int pthread_ret, aop_ret;
  2263   2365   	char *argv0;
  2264         -	rlim_t number_open_files_max;
         2366  +int i;
  2265   2367   
  2266   2368   	/*
  2267   2369   	 * Skip passed program name
  2268   2370   	 */
  2269   2371   	if (argc == 0 || argv == NULL) {
  2270   2372   		return(1);
  2271   2373   	}
................................................................................
  2302   2404   	/*
  2303   2405   	 * Create a thread-specific-data (TSD) key for each thread to refer
  2304   2406   	 * to its own Tcl interpreter.  Tcl interpreters must be unique per
  2305   2407   	 * thread and new threads are dynamically created by FUSE.
  2306   2408   	 */
  2307   2409   	pthread_ret = pthread_key_create(&interpKey, appfs_terminate_interp_and_thread);
  2308   2410   	if (pthread_ret != 0) {
  2309         -		fprintf(stderr, "Unable to create TSD key for Tcl.  Aborting.\n");
         2411  +		APPFS_ERROR("Unable to create TSD key for Tcl.  Aborting.");
  2310   2412   
  2311   2413   		return(1);
  2312   2414   	}
  2313   2415   
  2314   2416   	/*
  2315   2417   	 * Manually specify cache directory, without FUSE callback
  2316   2418   	 * This option only works when not using FUSE, since we
................................................................................
  2336   2438   	 * Tcl mode, for running raw Tcl in the same environment AppFSd would
  2337   2439   	 * run code.
  2338   2440   	 */
  2339   2441   	if (argc == 2 && strcmp(argv[0], "--tcl") == 0) {
  2340   2442   		return(appfs_tcl(argv[1]));
  2341   2443   	}
  2342   2444   
  2343         -	/*
  2344         -	 * Register a signal handler for hot-restart requests
  2345         -	 */
  2346         -	signal_ret = signal(SIGHUP, appfs_signal_handler);
  2347         -	if (signal_ret == SIG_ERR) {
  2348         -		fprintf(stderr, "Unable to install signal handler for hot-restart\n");
  2349         -		fprintf(stderr, "Hot-restart will not be available.\n");
  2350         -	}
  2351         -
  2352   2445   	/*
  2353   2446   	 * Parse command line arguments
  2354   2447   	 */
  2355   2448   	/**
  2356   2449   	 ** Restore argc/argv to original values, replacing argv[0] in case
  2357   2450   	 ** it was moified by --cachedir option.
  2358   2451   	 **/
................................................................................
  2378   2471   	 */
  2379   2472   	test_interp = appfs_create_TclInterp(&test_interp_error);
  2380   2473   	if (test_interp == NULL) {
  2381   2474   		if (test_interp_error == NULL) {
  2382   2475   			test_interp_error = "Unknown error";
  2383   2476   		}
  2384   2477   
  2385         -		fprintf(stderr, "Unable to initialize Tcl interpreter for AppFSd:\n");
  2386         -		fprintf(stderr, "%s\n", test_interp_error);
         2478  +		APPFS_ERROR("Unable to initialize Tcl interpreter for AppFSd:");
         2479  +		APPFS_ERROR("%s", test_interp_error);
  2387   2480   
  2388   2481   		return(1);
  2389   2482   	}
  2390   2483   
  2391   2484   	Tcl_DeleteInterp(test_interp);
  2392   2485   
  2393   2486   	if (appfs_threaded_tcl) {
  2394   2487   		Tcl_FinalizeNotifier(NULL);
  2395   2488   	}
  2396   2489   
  2397         -	/*
  2398         -	 * Increase resource limits for number of open files
  2399         -	 * to the maximum values, since we may be asked to
  2400         -	 * hold open many files on behalf of many other processes
  2401         -	 */
  2402         -	number_open_files.rlim_cur = number_open_files.rlim_max = RLIM_INFINITY;
  2403         -
  2404         -	rlimit_ret = setrlimit(RLIMIT_NOFILE, &number_open_files);
  2405         -
  2406         -	if (rlimit_ret != 0) {
  2407         -		rlimit_ret = getrlimit(RLIMIT_NOFILE, &number_open_files);
  2408         -		if (rlimit_ret == 0) {
  2409         -			number_open_files_max = number_open_files.rlim_max;
  2410         -
  2411         -			if (number_open_files_max < (1024 * 1024)) {
  2412         -				number_open_files.rlim_cur = number_open_files.rlim_max = 1024 * 1024;
  2413         -
  2414         -				rlimit_ret = setrlimit(RLIMIT_NOFILE, &number_open_files);
  2415         -			} else {
  2416         -				number_open_files.rlim_cur = number_open_files.rlim_max;
  2417         -			}
  2418         -
  2419         -			rlimit_ret = setrlimit(RLIMIT_NOFILE, &number_open_files);
  2420         -
  2421         -			if (rlimit_ret != 0 && number_open_files.rlim_cur != number_open_files_max) {
  2422         -				number_open_files.rlim_cur = number_open_files.rlim_max = number_open_files_max;
  2423         -
  2424         -				setrlimit(RLIMIT_NOFILE, &number_open_files);
  2425         -			}
  2426         -		}
  2427         -	}
  2428         -
         2490  +	appfs_set_resource_limits();
         2491  +	appfs_set_sighandler();
  2429   2492   
  2430   2493   	/*
  2431   2494   	 * Enter the FUSE main loop -- this will process any arguments
  2432   2495   	 * and start servicing requests.
  2433   2496   	 */
  2434   2497   	appfs_fuse_started = 1;
  2435   2498   	return(fuse_main(args.argc, args.argv, &appfs_operations, NULL));
  2436   2499   }