• 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
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,
# 2011, 2012
@ -1335,7 +1335,7 @@ else
#define EXTERN
#define MKSH_INCLUDES_ONLY
#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); }
EOF
case $cm in
@ -1399,19 +1399,18 @@ EOF
#
# Environment: library functions
#
ac_testn flock_ex '' 'flock and mmap' <<-'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
ac_test flock <<-'EOF'
#include <fcntl.h>
#include <stdlib.h>
int main(void) { return ((void *)mmap(NULL, (size_t)flock(0, LOCK_EX),
PROT_READ, MAP_PRIVATE, 0, (off_t)0) == (void *)NULL ? 1 :
munmap(NULL, 0)); }
int main(void) { return (flock(0, LOCK_EX | LOCK_UN)); }
EOF
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
ac_test getrusage <<-'EOF'
@ -1446,6 +1445,20 @@ ac_test mkstemp <<-'EOF'
int main(void) { char tmpl[] = "X"; return (mkstemp(tmpl)); }
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'
#include <unistd.h>
int main(void) { return (nice(4)); }
@ -1536,7 +1549,7 @@ EOF
#
save_CC=$CC; save_LDFLAGS=$LDFLAGS; save_LIBS=$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
#include "sh.h"
long flock(void); /* this clashes if defined before */
@ -1559,7 +1572,9 @@ CC=$save_CC; LDFLAGS=$save_LDFLAGS; LIBS=$save_LIBS
# other checks
#
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"
ac_testdone
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>
#
# 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_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=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_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 \
-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
CPPFLAGS+= -DHAVE_SILENT_IDIVWRAPV=0
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
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: 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 $
@ -29,7 +29,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout:
@(#)MIRBSD KSH R40 2012/03/26
@(#)MIRBSD KSH R40 2012/03/27
description:
Check version of shell.
stdin:

View File

@ -2,7 +2,8 @@
/* $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>
*
* Provided that these terms and disclaimer and all copyright notices
@ -26,7 +27,7 @@
#include <sys/file.h>
#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];
static struct sigaction Sigact_ign;
@ -723,7 +724,7 @@ hist_init(Source *s)
if (histfd != fd)
close(fd);
(void)flock(histfd, LOCK_EX);
mksh_lockfd(histfd);
histfsize = lseek(histfd, (off_t)0, SEEK_END);
if (histfsize > MKSH_MAXHISTFSIZE || hs == hist_init_restore) {
@ -815,7 +816,7 @@ hist_init(Source *s)
}
histfsize = lseek(histfd, (off_t)0, SEEK_END);
hist_init_tail:
(void)flock(histfd, LOCK_UN);
mksh_unlkfd(histfd);
#endif
}
@ -880,7 +881,7 @@ writehistfile(int lno, const char *cmd)
size_t bytes;
unsigned char *base, *news;
(void)flock(histfd, LOCK_EX);
mksh_lockfd(histfd);
sizenow = lseek(histfd, (off_t)0, SEEK_END);
if (sizenow < histfsize) {
/* the file has shrunk; give up */
@ -917,7 +918,7 @@ writehistfile(int lno, const char *cmd)
return;
}
histfsize = lseek(histfd, (off_t)0, SEEK_END);
(void)flock(histfd, LOCK_UN);
mksh_unlkfd(histfd);
}
static int
@ -938,7 +939,7 @@ writehistline(int fd, int lno, const char *cmd)
void
hist_finish(void)
{
(void)flock(histfd, LOCK_UN);
mksh_unlkfd(histfd);
(void)close(histfd);
histfd = -1;
}
@ -1419,3 +1420,53 @@ setexecsig(Trap *p, int restore)
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>
#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;
@ -1721,7 +1721,7 @@ DF(const char *fmt, ...)
va_list args;
struct timeval tv;
(void)flock(shl_dbg_fd, LOCK_EX);
mksh_lockfd(shl_dbg_fd);
gettimeofday(&tv, NULL);
shf_fprintf(shl_dbg, "[%d.%06d:%d] ", (int)tv.tv_sec, (int)tv.tv_usec,
(int)getpid());
@ -1730,6 +1730,6 @@ DF(const char *fmt, ...)
va_end(args);
shf_putc('\n', shl_dbg);
shf_flush(shl_dbg);
(void)flock(shl_dbg_fd, LOCK_UN);
mksh_unlkfd(shl_dbg_fd);
}
#endif

8
sh.h
View File

@ -152,9 +152,9 @@
#endif
#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
#define MKSH_VERSION "R40 2012/03/26"
#define MKSH_VERSION "R40 2012/03/27"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -1663,6 +1663,10 @@ int block_pipe(void);
void restore_pipe(int);
int setsig(Trap *, sig_t, int);
void setexecsig(Trap *, int);
#if HAVE_FLOCK || HAVE_LOCK_FCNTL
void mksh_lockfd(int);
void mksh_unlkfd(int);
#endif
/* jobs.c */
void j_init(void);
void j_exit(void);