ca7cb65c005c41bd965cdcc5e1e396dfb4e7a173
[sxemacs] / m4 / sxe-fs-funs.m4
1 dnl sxe-fs-funs.m4 -- Functions for file system access
2
3 AC_DEFUN([SXE_CHECK_REALPATH], [dnl
4         ## defines have_realpath
5
6         ## for the dirname proto
7         AC_CHECK_DECLS([realpath], [], [], [
8 #ifdef HAVE_STDLIB_H
9 #  include <stdlib.h>
10 #endif
11                 ])
12         AC_CHECK_FUNCS([realpath])
13         AC_CHECK_LIB([c], [realpath])
14
15         if test "$ac_cv_func_realpath" = "yes"; then
16                 SXE_CHECK_BROKEN_REALPATH
17         elif test "$ac_cv_lib_c_realpath" = "yes"; then
18                 LDFLAGS="$LDFLAGS -lc"
19                 SXE_CHECK_BROKEN_REALPATH
20         else
21                 have_realpath=no
22         fi
23
24         if test "$sxe_func_realpath_broken" != "no"; then
25                 SXE_ADD_CORE_OBJS([realpath.o])
26         fi
27 ])dnl SXE_CHECK_REALPATH
28
29 AC_DEFUN([_SXE_CHECK_REALPATH_RETVAL], [dnl
30         ## arg #1 is the return type, char* by default
31         ## arg #2 is the final test,
32         ##        pass something that is expected to be true here
33         ##        the return value is stored in a variable `r'
34         ## defines sxe_func_realpath_returns_<ret_t> and
35         ## sxe_func_realpath_returns=$1 if true
36         pushdef([ret_t], ifelse($1, [], [char*],$1))
37         pushdef([resvar_body], [sxe_func_realpath_returns])
38         pushdef([resvar], resvar_body[_]translit(ret_t, [ -*], [__X]))
39         pushdef([rettest], ifelse($2, [], [[[[r[0] == '/']]]],$2))
40
41         AC_MSG_CHECKING([whether realpath returns ]ret_t)
42         AC_RUN_IFELSE([AC_LANG_SOURCE([[
43 #ifdef HAVE_STDLIB_H
44 #  include <stdlib.h>
45 #endif
46
47 #ifndef PATH_MAX
48 #define PATH_MAX 4096
49 #endif
50
51 int realpath_returns_]]ret_t[[() {
52         ]]ret_t[[ r;
53         char p[8] = "/bin/sh\000";
54         char resv[PATH_MAX];
55         int res;
56
57         resv[0] = '\0';
58         r = realpath(p, resv);
59         if (r) {
60                 res = ((]]rettest[[) == 0);
61         } else {
62                 res = 0;
63         }
64         return res;
65 }
66
67 int main()
68 {
69         return realpath_returns_]]ret_t[[();
70 }
71                 ]])],
72                 resvar[=yes],
73                 resvar[=no],
74                 resvar[=no])
75         AC_MSG_RESULT([$]resvar)
76
77         if test "$[]resvar[]" = "yes"; then
78                 resvar_body[=]ret_t
79                 AC_DEFINE_UNQUOTED([REALPATH_RET_T], ret_t,
80                         [return type of realpath()])
81         fi
82
83         popdef([resvar_body])
84         popdef([resvar])
85         popdef([ret_t])
86         popdef([rettest])
87 ])dnl _SXE_CHECK_REALPATH_RETVAL
88
89 AC_DEFUN([_SXE_CHECK_REALPATH_RETVAL_OWNER], [dnl
90         ## defines sxe_func_realpath_retval_owner,
91         ## values are either "sys" or "user"
92         pushdef([resvar], [sxe_func_realpath_retval_owner])
93
94         ## this test is especially critical, because some systems do not
95         ## allocate memory for the user when the return value is "."
96         ## instead they point to a static const char somewhere in their
97         ## guts which, of course, must not be furtherly modified, free'd or
98         ## anything ... took me fucking ages to find out what's going on
99         ## so let's drink to the morons responsible for THAT!
100         AC_MSG_CHECKING([to whom belongs the object returned by realpath])
101         if test "$opsys" = "darwin"; then
102            resvar=user
103         else
104         AC_RUN_IFELSE([AC_LANG_SOURCE([[
105 #ifdef HAVE_STDLIB_H
106 #  include <stdlib.h>
107 #endif
108
109 #ifndef PATH_MAX
110 #define PATH_MAX 4096
111 #endif
112
113 #define FOLLOW_FREE_STRATEGY            1
114 #define FOLLOW_REALLOC_STRATEGY         1
115
116 int owner_of_object_returned_by_realpath()
117 {
118         void *r;  /* any pointer is just fine */
119         char p[8] = "/bin/sh\000";
120
121         r = (void*)realpath(p, NULL);
122 #if FOLLOW_REALLOC_STRATEGY
123         /* reallocation would help already */
124         r = realloc(r, 4096);
125 #endif
126 #if FOLLOW_FREE_STRATEGY
127         /* if r was ours we should be able to free it */
128         free(r);
129 #endif
130 #if FOLLOW_FREE_STRATEGY || FOLLOW_REALLOC_STRATEGY
131         return 0;
132 #else
133         return 1;
134 #endif
135 }
136
137 int main()
138 {
139         return owner_of_object_returned_by_realpath();
140 }
141                 ]])],
142                 resvar[=user],
143                 resvar[=sys],
144                 resvar[=sys])
145         fi
146         AC_MSG_RESULT([$]resvar)
147
148         if test "$[]resvar[]" = "user"; then
149                 AC_DEFINE([REALPATH_USER_OWNS_RETVAL], [1],
150                         [Whether the user space owns the retval of realpath()])
151         elif test "$[]resvar[]" = "sys"; then
152                 AC_DEFINE([REALPATH_SYS_OWNS_RETVAL], [1],
153                         [Whether the system owns the retval of realpath()])
154         fi
155
156         popdef([resvar])
157 ])dnl _SXE_CHECK_REALPATH_RETVAL_OWNER
158
159 AC_DEFUN([_SXE_CHECK_REALPATH_ON_PROTECTED_MEMORY], [dnl
160         ## defines sxe_func_realpath_accepts_protmem
161         pushdef([resvar], [sxe_func_realpath_accepts_protmem])
162
163         AC_MSG_CHECKING([whether realpath can operate on protected mem blocks])
164         if test "$opsys" = "darwin"; then
165            resvar=no
166         else
167         AC_RUN_IFELSE([AC_LANG_SOURCE([[
168 #ifdef HAVE_STDLIB_H
169 #  include <stdlib.h>
170 #endif
171
172 #ifndef PATH_MAX
173 #define PATH_MAX 4096
174 #endif
175
176 int realpath_can_operate_on_protected_mem_blocks()
177 {
178         char resv[PATH_MAX];
179         realpath("/bin/sh", NULL);
180         realpath("/bin/sh", resv);
181         return 0;
182 }
183
184 int main()
185 {
186         return realpath_can_operate_on_protected_mem_blocks();
187 }
188                 ]])],
189                 resvar[=yes],
190                 resvar[=no],
191                 resvar[=no])
192         fi
193         AC_MSG_RESULT([$]resvar)
194
195         if test "$[]resvar[]" = "yes"; then
196                 AC_DEFINE([REALPATH_ACCEPTS_PROTMEM], [1],
197                         [Whether realpath() accepts protected memory blocks])
198         fi
199
200         popdef([resvar])
201 ])dnl _SXE_CHECK_REALPATH_ON_PROTECTED_MEMORY
202
203 AC_DEFUN([_SXE_CHECK_REALPATH_SANE_ON_NON_EXISTENT], [dnl
204         ## defines sxe_func_realpath_
205         pushdef([resvar], [sxe_func_realpath_sane_on_non_existent])
206
207         AC_MSG_CHECKING([whether realpath survives if we pass non-existent stuff])
208         AC_RUN_IFELSE([AC_LANG_SOURCE([[
209 #ifdef HAVE_STDLIB_H
210 #  include <stdlib.h>
211 #endif
212
213 #ifndef PATH_MAX
214 #define PATH_MAX 4096
215 #endif
216
217 static char p[24] = "/nobody/has/this/file\000";
218
219 int realpath_survives_non_existent_path()
220 {
221         char *r;
222         char resv[PATH_MAX];
223         r = realpath((char*)p, resv);
224
225         return ((r == NULL) == 0);
226 }
227
228 int main()
229 {
230         return realpath_survives_non_existent_path();
231 }
232                 ]])],
233                 resvar[=yes],
234                 resvar[=no],
235                 resvar[=no])
236         AC_MSG_RESULT([$]resvar)
237
238         if test "$[]resvar[]" = "yes"; then
239                 AC_DEFINE([REALPATH_SANE_ON_NON_EXISTENT], [1],
240                         [Whether realpath() accepts and handles non-existent files])
241         fi
242
243         popdef([resvar])
244 ])dnl _SXE_CHECK_REALPATH_SANE_ON_NON_EXISTENT
245
246 AC_DEFUN([SXE_CHECK_BROKEN_REALPATH], [dnl
247         ## defines 3 vars, look in the sub macros to see which ones
248         _SXE_CHECK_REALPATH_ON_PROTECTED_MEMORY
249         _SXE_CHECK_REALPATH_SANE_ON_NON_EXISTENT
250         _SXE_CHECK_REALPATH_RETVAL
251         _SXE_CHECK_REALPATH_RETVAL_OWNER
252
253         AC_MSG_CHECKING([if realpath is considered broken])
254         if test "$sxe_func_realpath_returns" = "char*" -a \
255                 "$sxe_func_realpath_sane_on_non_existent" = "yes" -a \
256                 "$sxe_func_realpath_retval_owner" = "user"; then
257                 sxe_func_realpath_broken="no"
258         else
259                 sxe_func_realpath_broken="yes"
260         fi
261         AC_MSG_RESULT([$sxe_func_realpath_broken])
262 ])dnl SXE_CHECK_BROKEN_REALPATH
263
264
265 AC_DEFUN([SXE_CHECK_DIRNAME], [dnl
266         ## defines have_dirname
267
268         ## of course posix standards are just rough draughts
269         ## and by no means obliging in any way ...
270         ## and since we all hate working systems we do our best
271         ## to break these so called standards wherever we can
272         ##
273         ## Passage from coreutils:
274         ## In general, we can't use the builtin `dirname' function if available,
275         ## since it has different meanings in different environments. In some
276         ## environments the builtin `dirname' modifies its argument.
277
278         ## for the dirname proto
279         SXE_CHECK_HEADERS([libgen.h])
280         AC_CHECK_DECLS([dirname], [], [], [
281 #ifdef HAVE_LIBGEN_H
282 #  include <libgen.h>
283 #endif
284                 ])
285         AC_CHECK_FUNCS([dirname])       dnl should be part of glibc
286         AC_CHECK_LIB([c], [dirname])
287
288         if test "$ac_cv_func_dirname" = "yes"; then
289                 SXE_CHECK_BROKEN_DIRNAME
290         elif test "$ac_cv_lib_c_dirname" = "yes"; then
291                 LDFLAGS="$LDFLAGS -lc"
292                 SXE_CHECK_BROKEN_DIRNAME
293         else
294                 have_dirname=no
295         fi
296 ])dnl SXE_CHECK_DIRNAME
297
298 AC_DEFUN([_SXE_CHECK_DIRNAME_SIDE_EFFECT], [dnl
299         ## defines sxe_func_dirname_side_effect
300         ## and DIRNAME_SIDE_EFFECT
301         pushdef([resvar], [sxe_func_dirname_side_effect])
302
303         AC_MSG_CHECKING([whether dirname modifies its argument by side-effect])
304         AC_RUN_IFELSE([AC_LANG_SOURCE([[
305 #ifdef HAVE_LIBGEN_H
306 #  include <libgen.h>
307 #endif
308
309 int dirname_modifies_argument()
310 {
311         char p[11] = "somefile\000";
312         dirname(p);
313         return ((p[0] == '.' && p[1] == '\0') == 0);
314 }
315
316 int main()
317 {
318         return dirname_modifies_argument();
319 }
320                 ]])],
321                 resvar[=yes],
322                 resvar[=no],
323                 resvar[=no])
324         AC_MSG_RESULT([$]resvar)
325
326         if test "$[]resvar[]" = "yes"; then
327                 AC_DEFINE([DIRNAME_SIDE_EFFECT], [1],
328                         [Whether dirname() operates by side effect])
329         fi
330
331         popdef([resvar])
332 ])dnl _SXE_CHECK_DIRNAME_SIDE_EFFECT
333
334 AC_DEFUN([_SXE_CHECK_DIRNAME_RETVAL], [dnl
335         ## arg #1 is the return type, char* by default
336         ## arg #2 is the final test,
337         ##        pass something that is expected to be true here
338         ##        the return value is stored in a variable `r'
339         ## defines sxe_func_dirname_returns_<ret_t> and
340         ## sxe_func_dirname_returns=$1 if true
341         pushdef([ret_t], ifelse($1, [], [char*],$1))
342         pushdef([resvar_body], [sxe_func_dirname_returns])
343         pushdef([resvar], resvar_body[_]translit(ret_t, [ -*], [__X]))
344         pushdef([rettest], ifelse($2, [], [[[[r[0] == '.' && r[1] == '\000']]]],$2))
345
346         AC_MSG_CHECKING([whether dirname returns ]ret_t)
347         AC_RUN_IFELSE([AC_LANG_SOURCE([[
348 #ifdef HAVE_LIBGEN_H
349 #  include <libgen.h>
350 #endif
351
352 int main()
353 {
354         ]]ret_t[[ r;
355         char p[11] = "somefile\000";
356         int res;
357
358         r = dirname(p);
359         res = ((]]rettest[[) == 0);
360         return res;
361 }
362                 ]])],
363                 resvar[=yes],
364                 resvar[=no],
365                 resvar[=no])
366         AC_MSG_RESULT([$]resvar)
367
368         if test "$[]resvar[]" = "yes"; then
369                 resvar_body[=]ret_t
370                 AC_DEFINE_UNQUOTED([DIRNAME_RET_T], ret_t,
371                         [return type of dirname()])
372         fi
373
374         popdef([resvar_body])
375         popdef([resvar])
376         popdef([ret_t])
377         popdef([rettest])
378 ])dnl _SXE_CHECK_DIRNAME_RETVAL
379
380 AC_DEFUN([_SXE_CHECK_DIRNAME_RETVAL_OWNER], [dnl
381         ## defines sxe_func_dirname_retval_owner,
382         ## values are either "sys" or "user"
383         pushdef([resvar], [sxe_func_dirname_retval_owner])
384
385         malloc_check=${MALLOC_CHECK_}
386         ## Turn off the stupid glibc 2.5 stack trace check. We *know* we may
387         ## do something bad here :-)
388         MALLOC_CHECK_=0
389         export MALLOC_CHECK_
390         ## this test is especially critical, because some systems do not
391         ## allocate memory for the user when the return value is "."
392         ## instead they point to a static const char somewhere in their
393         ## guts which, of course, must not be furtherly modified, free'd or
394         ## anything ... took me fucking ages to find out what's going on
395         ## so let's drink to the morons responsible for THAT!
396         AC_MSG_CHECKING([to whom belongs the object returned by dirname])
397         if test "$opsys" = "darwin" ; then
398            resvar=sys
399         else
400         AC_RUN_IFELSE([AC_LANG_SOURCE([[
401 #ifdef HAVE_LIBGEN_H
402 #  include <libgen.h>
403 #endif
404
405 #define FOLLOW_FREE_STRATEGY            1
406 #define FOLLOW_REALLOC_STRATEGY         1
407
408 int owner_of_object_returned_by_dirname()
409 {
410         void *r;  /* any pointer is just fine */
411         char p[11] = "./somefile\000";
412
413         r = (void*)dirname(p);
414 #if FOLLOW_REALLOC_STRATEGY
415         /* reallocation would help already */
416         r = realloc(r, 4096);
417 #endif
418 #if FOLLOW_FREE_STRATEGY
419         /* if r was ours we should be able to free it */
420         free(r);
421 #endif
422 #if FOLLOW_FREE_STRATEGY || FOLLOW_REALLOC_STRATEGY
423         return 0;
424 #else
425         return 1;
426 #endif
427 }
428
429 int main()
430 {
431         return owner_of_object_returned_by_dirname();
432 }
433                 ]])],
434                 resvar[=user],
435                 resvar[=sys],
436                 resvar[=sys])
437         fi
438         if test "${malloc_check}" = "" ; then
439                 unset MALLOC_CHECK_
440         else
441                 MALLOC_CHECK_=${malloc_check}
442         fi
443         AC_MSG_RESULT([$]resvar)
444
445         if test "$[]resvar[]" = "user"; then
446                 AC_DEFINE([DIRNAME_USER_OWNS_RETVAL], [1],
447                         [Whether the user space owns the retval of dirname()])
448         elif test "$[]resvar[]" = "sys"; then
449                 AC_DEFINE([DIRNAME_SYS_OWNS_RETVAL], [1],
450                         [Whether the system owns the retval of dirname()])
451         fi
452
453         popdef([resvar])
454 ])dnl _SXE_CHECK_DIRNAME_RETVAL_OWNER
455
456 AC_DEFUN([_SXE_CHECK_DIRNAME_ON_PROTECTED_MEMORY], [dnl
457         ## defines sxe_func_dirname_accepts_protmem
458         pushdef([resvar], [sxe_func_dirname_accepts_protmem])
459
460         AC_MSG_CHECKING([whether dirname can operate on protected mem blocks])
461         AC_RUN_IFELSE([AC_LANG_SOURCE([[
462 #ifdef HAVE_LIBGEN_H
463 #  include <libgen.h>
464 #endif
465
466 int dirname_can_operate_on_protected_mem_blocks()
467 {
468         dirname("./somefile");
469         return 0;
470 }
471
472 int main()
473 {
474         return dirname_can_operate_on_protected_mem_blocks();
475 }
476                 ]])],
477                 resvar[=yes],
478                 resvar[=no],
479                 resvar[=no])
480         AC_MSG_RESULT([$]resvar)
481
482         if test "$[]resvar[]" = "yes"; then
483                 AC_DEFINE([DIRNAME_ACCEPTS_PROTMEM], [1],
484                         [Whether dirname() accepts protected memory blocks])
485         fi
486
487         popdef([resvar])
488 ])dnl _SXE_CHECK_DIRNAME_ON_PROTECTED_MEMORY
489
490 AC_DEFUN([_SXE_CHECK_DIRNAME_ON_C99_RESTRICT_MEMORY], [dnl
491         ## defines sxe_func_dirname_accepts_restrmem
492         pushdef([resvar], [sxe_func_dirname_accepts_restrmem])
493
494         AC_MSG_CHECKING([whether dirname can operate on C99 restrict mem blocks])
495         AC_RUN_IFELSE([AC_LANG_SOURCE([[
496 #ifdef HAVE_STDIO_H
497 #  inlcude <stdio.h>
498 #endif
499 #ifdef HAVE_LIBGEN_H
500 #  include <libgen.h>
501 #endif
502
503 static char f[11] = "./somefile\000";
504
505 int dirname_can_operate_on_c99_restrict()
506 {
507         const char *restrict p = &f;
508         dirname((char*)p);
509         return 0;
510 }
511
512 int main()
513 {
514         return dirname_can_operate_on_c99_restrict();
515 }
516                 ]])],
517                 resvar[=yes],
518                 resvar[=no],
519                 resvar[=no])
520         AC_MSG_RESULT([$]resvar)
521
522         if test "$[]resvar[]" = "yes"; then
523                 AC_DEFINE([DIRNAME_ACCEPTS_RESTRMEM], [1],
524                         [Whether dirname() accepts restricted memory blocks])
525         fi
526
527         popdef([resvar])
528 ])dnl _SXE_CHECK_DIRNAME_ON_C99_RESTRICT_MEMORY
529
530 AC_DEFUN([SXE_CHECK_BROKEN_DIRNAME], [dnl
531         ## defines 3 vars, look in the sub macros to see which ones
532         _SXE_CHECK_DIRNAME_SIDE_EFFECT
533         _SXE_CHECK_DIRNAME_ON_PROTECTED_MEMORY
534         _SXE_CHECK_DIRNAME_ON_C99_RESTRICT_MEMORY
535         _SXE_CHECK_DIRNAME_RETVAL
536         _SXE_CHECK_DIRNAME_RETVAL_OWNER
537 ])dnl SXE_CHECK_BROKEN_DIRNAME
538
539
540 AC_DEFUN([SXE_CHECK_FILE_LOCK], [dnl
541         ## Determine type of mail locking from configure args and s&m headers
542         AC_MSG_CHECKING([for a type of mail spool file locking])
543         AC_MSG_RESULT([])
544
545         AC_CHECK_FUNCS([lockf flock locking])
546         ## The mail_use_xxx variables are set according to the s&m headers.
547         if test "$with_mail_locking" != "no" -a \
548                 "$mail_use_flock" = "yes"; then
549                 with_mail_locking=flock
550         elif test "$with_mail_locking" != "no" -a \
551                 "$mail_use_lockf" = "yes"; then
552                 with_mail_locking=lockf
553         elif test "$with_mail_locking" != "no" -a \
554                 "$mail_use_locking" = "yes"; then
555                 with_mail_locking=locking
556         fi
557
558         if test "$with_mail_locking" = "lockf"; then
559                 AC_DEFINE([MAIL_LOCK_LOCKF], [1], [Description here!])
560         elif test "$with_mail_locking" = "flock"; then
561                 AC_DEFINE([MAIL_LOCK_FLOCK], [1], [Description here!])
562         elif test "$with_mail_locking" = "locking"; then
563                 AC_DEFINE([MAIL_LOCK_LOCKING], [1], [Description here!])
564         elif test "$with_mail_locking" = "pop"; then
565                 with_pop=yes
566                 with_mail_locking=
567         elif test "$with_mail_locking" = "mmdf"; then
568                 AC_DEFINE([MAIL_LOCK_MMDF], [1], [Description here!])
569         else
570                 with_mail_locking="file"
571                 AC_DEFINE([MAIL_LOCK_DOT], [1], [Description here!])
572         fi
573
574         if test "$with_mail_locking" = "lockf" -a \
575                 "$ac_cv_func_lockf" != "yes"; then
576                 SXE_DIE([lockf mail locking requested but not available.])
577         elif test "$with_mail_locking" = "flock" -a \
578                 "$ac_cv_func_flock" != "yes"; then
579                 SXE_DIE([flock mail locking requested but not available.])
580         elif test "$with_mail_locking" = "locking" -a \
581                 "$ac_cv_func_locking" != "yes"; then
582                 SXE_DIE([locking mail locking requested but not available.])
583         fi
584 ])dnl SXE_CHECK_FILE_LOCK
585
586
587 dnl sxe-fs-funs.m4 ends here