• implement fcntl(2)-based advisory locking as an alternative iff flock(2)

is not found, from a suggestion by RT (LP: #912691)
• try harder (in a loop) to acquire a file lock if the locking mechanism
  documents EINTR is a possibility (fcntl always, flock on Linux not .Ox)
• use -std=c99 not -std=gnu99 if it must be at all
This commit is contained in:
tg 2012-03-27 22:36:53 +00:00
parent e3b9f14d88
commit 95a2c63096
6 changed files with 106 additions and 34 deletions

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.517 2012/03/27 21:23:50 tg Exp $' srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.518 2012/03/27 22:36:48 tg Exp $'
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 # 2011, 2012
@ -1335,7 +1335,7 @@ else
#define EXTERN #define EXTERN
#define MKSH_INCLUDES_ONLY #define MKSH_INCLUDES_ONLY
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.517 2012/03/27 21:23:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.518 2012/03/27 22:36:48 tg Exp $");
int main(void) { printf("Hello, World!\n"); return (0); } int main(void) { printf("Hello, World!\n"); return (0); }
EOF EOF
case $cm in case $cm in
@ -1399,19 +1399,18 @@ EOF
# #
# Environment: library functions # Environment: library functions
# #
ac_testn flock_ex '' 'flock and mmap' <<-'EOF' ac_test flock <<-'EOF'
#include <sys/types.h>
#if HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> int main(void) { return (flock(0, LOCK_EX | LOCK_UN)); }
int main(void) { return ((void *)mmap(NULL, (size_t)flock(0, LOCK_EX), EOF
PROT_READ, MAP_PRIVATE, 0, (off_t)0) == (void *)NULL ? 1 :
munmap(NULL, 0)); } ac_test lock_fcntl '!' flock 1 'whether we can lock files with fcntl' <<-'EOF'
#include <fcntl.h>
int main(void) {
struct flock lks;
lks.l_type = F_WRLCK | F_UNLCK;
return (fcntl(0, F_SETLKW, &lks));
}
EOF EOF
ac_test getrusage <<-'EOF' ac_test getrusage <<-'EOF'
@ -1446,6 +1445,20 @@ ac_test mkstemp <<-'EOF'
int main(void) { char tmpl[] = "X"; return (mkstemp(tmpl)); } int main(void) { char tmpl[] = "X"; return (mkstemp(tmpl)); }
EOF EOF
ac_test mmap lock_fcntl 0 'for mmap and munmap' <<-'EOF'
#include <sys/types.h>
#if HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <stdlib.h>
int main(void) { return ((void *)mmap(NULL, (size_t)0,
PROT_READ, MAP_PRIVATE, 0, (off_t)0) == (void *)NULL ? 1 :
munmap(NULL, 0)); }
EOF
ac_test nice <<-'EOF' ac_test nice <<-'EOF'
#include <unistd.h> #include <unistd.h>
int main(void) { return (nice(4)); } int main(void) { return (nice(4)); }
@ -1536,7 +1549,7 @@ EOF
# #
save_CC=$CC; save_LDFLAGS=$LDFLAGS; save_LIBS=$LIBS save_CC=$CC; save_LDFLAGS=$LDFLAGS; save_LIBS=$LIBS
CC="$CC -c -o $tcfn"; LDFLAGS=; LIBS= CC="$CC -c -o $tcfn"; LDFLAGS=; LIBS=
ac_test '!' flock_decl flock_ex 1 'if flock() does not need to be declared' <<-'EOF' ac_test '!' flock_decl flock 1 'if flock() does not need to be declared' <<-'EOF'
#define MKSH_INCLUDES_ONLY #define MKSH_INCLUDES_ONLY
#include "sh.h" #include "sh.h"
long flock(void); /* this clashes if defined before */ long flock(void); /* this clashes if defined before */
@ -1559,7 +1572,9 @@ CC=$save_CC; LDFLAGS=$save_LDFLAGS; LIBS=$save_LIBS
# other checks # other checks
# #
fd='if to use persistent history' fd='if to use persistent history'
ac_cache PERSISTENT_HISTORY || test 0 = $HAVE_FLOCK_EX || fv=1 ac_cache PERSISTENT_HISTORY || case $HAVE_MMAP$HAVE_FLOCK$HAVE_LOCL_FCNTL in
11*|101) fv=1 ;;
esac
test 1 = $fv || check_categories="$check_categories no-histfile" test 1 = $fv || check_categories="$check_categories no-histfile"
ac_testdone ac_testdone
ac_cppflags ac_cppflags

View File

@ -1,6 +1,7 @@
# $MirOS: src/bin/mksh/Makefile,v 1.94 2012/03/27 21:23:51 tg Exp $ # $MirOS: src/bin/mksh/Makefile,v 1.95 2012/03/27 22:36:49 tg Exp $
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012
# Thorsten Glaser <tg@mirbsd.org> # Thorsten Glaser <tg@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
@ -39,7 +40,8 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_CAN_INTTYPES=1 -DHAVE_CAN_UCBINTS=1 \ -DHAVE_CAN_INTTYPES=1 -DHAVE_CAN_UCBINTS=1 \
-DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=1 \ -DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=1 \
-DHAVE_SIG_T=1 -DHAVE_SYS_SIGNAME=1 -DHAVE_SYS_SIGLIST=1 \ -DHAVE_SIG_T=1 -DHAVE_SYS_SIGNAME=1 -DHAVE_SYS_SIGLIST=1 \
-DHAVE_STRSIGNAL=0 -DHAVE_GETRUSAGE=1 -DHAVE_KILLPG=1 \ -DHAVE_STRSIGNAL=0 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 \
-DHAVE_MMAP=1 -DHAVE_GETRUSAGE=1 -DHAVE_KILLPG=1 \
-DHAVE_MKNOD=0 -DHAVE_MKSTEMP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=1 \ -DHAVE_MKNOD=0 -DHAVE_MKSTEMP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=1 \
-DHAVE_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 \ -DHAVE_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 \
-DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 \ -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 \
@ -49,7 +51,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
# probably differs between i386 and sparc # probably differs between i386 and sparc
CPPFLAGS+= -DHAVE_SILENT_IDIVWRAPV=0 CPPFLAGS+= -DHAVE_SILENT_IDIVWRAPV=0
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U} CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
COPTS+= -std=gnu99 -Wall COPTS+= -std=c99 -Wall
.endif .endif
USE_PRINTF_BUILTIN?= 0 USE_PRINTF_BUILTIN?= 0

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.523 2012/03/26 21:10:38 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.524 2012/03/27 22:36:49 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -29,7 +29,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R40 2012/03/26 @(#)MIRBSD KSH R40 2012/03/27
description: description:
Check version of shell. Check version of shell.
stdin: stdin:

View File

@ -2,7 +2,8 @@
/* $OpenBSD: trap.c,v 1.23 2010/05/19 17:36:08 jasper Exp $ */ /* $OpenBSD: trap.c,v 1.23 2010/05/19 17:36:08 jasper Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012
* Thorsten Glaser <tg@mirbsd.org> * Thorsten Glaser <tg@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
@ -26,7 +27,7 @@
#include <sys/file.h> #include <sys/file.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.117 2011/12/31 00:47:45 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.118 2012/03/27 22:36:52 tg Exp $");
Trap sigtraps[NSIG + 1]; Trap sigtraps[NSIG + 1];
static struct sigaction Sigact_ign; static struct sigaction Sigact_ign;
@ -723,7 +724,7 @@ hist_init(Source *s)
if (histfd != fd) if (histfd != fd)
close(fd); close(fd);
(void)flock(histfd, LOCK_EX); mksh_lockfd(histfd);
histfsize = lseek(histfd, (off_t)0, SEEK_END); histfsize = lseek(histfd, (off_t)0, SEEK_END);
if (histfsize > MKSH_MAXHISTFSIZE || hs == hist_init_restore) { if (histfsize > MKSH_MAXHISTFSIZE || hs == hist_init_restore) {
@ -815,7 +816,7 @@ hist_init(Source *s)
} }
histfsize = lseek(histfd, (off_t)0, SEEK_END); histfsize = lseek(histfd, (off_t)0, SEEK_END);
hist_init_tail: hist_init_tail:
(void)flock(histfd, LOCK_UN); mksh_unlkfd(histfd);
#endif #endif
} }
@ -880,7 +881,7 @@ writehistfile(int lno, const char *cmd)
size_t bytes; size_t bytes;
unsigned char *base, *news; unsigned char *base, *news;
(void)flock(histfd, LOCK_EX); mksh_lockfd(histfd);
sizenow = lseek(histfd, (off_t)0, SEEK_END); sizenow = lseek(histfd, (off_t)0, SEEK_END);
if (sizenow < histfsize) { if (sizenow < histfsize) {
/* the file has shrunk; give up */ /* the file has shrunk; give up */
@ -917,7 +918,7 @@ writehistfile(int lno, const char *cmd)
return; return;
} }
histfsize = lseek(histfd, (off_t)0, SEEK_END); histfsize = lseek(histfd, (off_t)0, SEEK_END);
(void)flock(histfd, LOCK_UN); mksh_unlkfd(histfd);
} }
static int static int
@ -938,7 +939,7 @@ writehistline(int fd, int lno, const char *cmd)
void void
hist_finish(void) hist_finish(void)
{ {
(void)flock(histfd, LOCK_UN); mksh_unlkfd(histfd);
(void)close(histfd); (void)close(histfd);
histfd = -1; histfd = -1;
} }
@ -1419,3 +1420,53 @@ setexecsig(Trap *p, int restore)
break; break;
} }
} }
#if HAVE_PERSISTENT_HISTORY || defined(DF)
/*
* File descriptor locking and unlocking functions.
* Could use some error handling, but hey, this is only
* advisory locking anyway, will often not work over NFS,
* and you are SOL if this fails...
*/
void
mksh_lockfd(int fd)
{
#if defined(__OpenBSD__)
/* flock is not interrupted by signals */
(void)flock(fd, LOCK_EX);
#elif HAVE_FLOCK
int rv;
/* e.g. on Linux */
do {
rv = flock(fd, LOCK_EX);
} while (rv == 1 && errno == EINTR);
#elif HAVE_LOCK_FCNTL
int rv;
struct flock lks;
memset(&lks, 0, sizeof(lks));
lks.l_type = F_WRLCK;
do {
rv = fcntl(fd, F_SETLKW, &lks);
} while (rv == 1 && errno == EINTR);
#else
#error oops
#endif
}
void
mksh_unlkfd(int fd)
{
#if HAVE_FLOCK
(void)flock(fd, LOCK_UN);
#elif HAVE_LOCK_FCNTL
struct flock lks;
memset(&lks, 0, sizeof(lks));
lks.l_type = F_UNLCK;
(void)fcntl(fd, F_SETLKW, &lks);
#endif
}
#endif

6
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.211 2012/03/25 14:28:14 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.212 2012/03/27 22:36:52 tg Exp $");
extern char **environ; extern char **environ;
@ -1721,7 +1721,7 @@ DF(const char *fmt, ...)
va_list args; va_list args;
struct timeval tv; struct timeval tv;
(void)flock(shl_dbg_fd, LOCK_EX); mksh_lockfd(shl_dbg_fd);
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
shf_fprintf(shl_dbg, "[%d.%06d:%d] ", (int)tv.tv_sec, (int)tv.tv_usec, shf_fprintf(shl_dbg, "[%d.%06d:%d] ", (int)tv.tv_sec, (int)tv.tv_usec,
(int)getpid()); (int)getpid());
@ -1730,6 +1730,6 @@ DF(const char *fmt, ...)
va_end(args); va_end(args);
shf_putc('\n', shl_dbg); shf_putc('\n', shl_dbg);
shf_flush(shl_dbg); shf_flush(shl_dbg);
(void)flock(shl_dbg_fd, LOCK_UN); mksh_unlkfd(shl_dbg_fd);
} }
#endif #endif

8
sh.h
View File

@ -152,9 +152,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.530 2012/03/27 21:23:52 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.531 2012/03/27 22:36:53 tg Exp $");
#endif #endif
#define MKSH_VERSION "R40 2012/03/26" #define MKSH_VERSION "R40 2012/03/27"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -1663,6 +1663,10 @@ int block_pipe(void);
void restore_pipe(int); void restore_pipe(int);
int setsig(Trap *, sig_t, int); int setsig(Trap *, sig_t, int);
void setexecsig(Trap *, int); void setexecsig(Trap *, int);
#if HAVE_FLOCK || HAVE_LOCK_FCNTL
void mksh_lockfd(int);
void mksh_unlkfd(int);
#endif
/* jobs.c */ /* jobs.c */
void j_init(void); void j_init(void);
void j_exit(void); void j_exit(void);