From 68c55e2e366d55a657c43c1b519337a820ed2239 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 11 Jan 2000 01:11:12 +0000 Subject: [PATCH] dselect/baselist.cc: don't specify SA_INTERRUPT, since it's not portable and the default behaviour main/enquiry.c: include sys/termios.h (needed on Solaris) lib/lock.c: use EACCESS instead of EWOULDBLOCK dselect/main.cc: fix help for -D dselect/main.cc: try to lock admindir instead of using readwrite dselect/method.cc: switch to using fcntl for lock since that is more portable, and revamp lockingcode to reduce code duplication --- ChangeLog | 11 +++++++++ dselect/baselist.cc | 2 +- dselect/main.cc | 21 +++++++++++++---- dselect/method.cc | 56 ++++++++++++++++++++++----------------------- lib/lock.c | 4 ++-- main/enquiry.c | 1 + utils/Makefile.in | 2 +- 7 files changed, 60 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 26f1afa8..bfb681c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Tue Jan 11 02:02:00 CET 2000 Wichert Akkerman + + * dselect/baselist.cc: don't specify SA_INTERRUPT, since it's + not portable and the default behaviour + * main/enquiry.c: include sys/termios.h (needed on Solaris) + * lib/lock.c: use EACCESS instead of EWOULDBLOCK + * dselect/main.cc: fix help for -D + * dselect/main.cc: try to lock admindir instead of using readwrite + * dselect/method.cc: switch to using fcntl for lock since that is more + portable, and revamp lockingcode to reduce code duplication + Sun Jan 9 16:11:39 CET 2000 Wichert Akkerman * Merge patches from Josip Rodin: diff --git a/dselect/baselist.cc b/dselect/baselist.cc index b4d13a17..3f326c6e 100644 --- a/dselect/baselist.cc +++ b/dselect/baselist.cc @@ -77,7 +77,7 @@ void baselist::setupsigwinch() { memset(&nsigact,0,sizeof(nsigact)); nsigact.sa_handler= sigwinchhandler; sigemptyset(&nsigact.sa_mask); - nsigact.sa_flags= SA_INTERRUPT; +//nsigact.sa_flags= SA_INTERRUPT; if (sigaction(SIGWINCH,&nsigact,0)) ohshite(_("failed to set new SIGWINCH sigact")); } diff --git a/dselect/main.cc b/dselect/main.cc index 59d0b00f..ca30400d 100644 --- a/dselect/main.cc +++ b/dselect/main.cc @@ -47,6 +47,10 @@ extern "C" { #include "bindings.h" #include "pkglist.h" +#include +#include +#include + const char thisname[]= DSELECT; const char printforhelp[]= N_("Type dselect --help for help."); @@ -94,7 +98,7 @@ static void usage(void) { _("Usage: dselect [options]\n" " dselect [options] action ...\n" "Options: --admindir (default is /var/lib/dpkg)\n" - " --help --version --licence --expert --debug | -D | -D\n" + " --help --version --licence --expert --debug | -D\n" "Actions: access update select install config remove quit menu\n"), stdout)) werr("stdout"); } @@ -233,6 +237,9 @@ void dme(int i, int so) { int refreshmenu(void) { char buf[2048]; + static int l,lockfd; + static char *lockfile; + curseson(); cbreak(); noecho(); nonl(); keypad(stdscr,TRUE); int y,x; @@ -257,10 +264,14 @@ int refreshmenu(void) { sprintf(buf,gettext(copyrightstring),DPKG_VERSION_ARCH); addstr(buf); - if (!readwrite) { - addstr(_("\n\n" - "Read-only access: only preview of selections is available!")); - } + l = strlen(admindir); + lockfile = new char[l+sizeof(LOCKFILE)+2]; + strcpy(lockfile,admindir); + strcpy(lockfile+l, "/" LOCKFILE); + lockfd = open(lockfile, O_RDWR|O_CREAT|O_TRUNC, 0660); + if (errno == EACCES || errno == EPERM) + addstr(_("\n\n" + "Read-only access: only preview of selections is available!")); return i; } diff --git a/dselect/method.cc b/dselect/method.cc index 69b372f8..01756a34 100644 --- a/dselect/method.cc +++ b/dselect/method.cc @@ -55,11 +55,27 @@ static const char *const methoddirectories[]= { static char *methodlockfile= 0; static int methlockfd= -1; +void sthfailed(const char * reasoning) { + char buf[2048]; + + curseson(); + clear(); + sprintf(buf,_("\n\n%s: %s\n"),DSELECT,reasoning); + addstr(buf); + attrset(A_BOLD); + addstr(_("\nPress to continue.")); + attrset(A_NORMAL); + refresh(); getch(); +} + static void cu_unlockmethod(int, void**) { + struct flock fl; + assert(methodlockfile); assert(methlockfd); - if (flock(methlockfd,LOCK_UN)) - ohshite(_("unable to unlock access method area")); + fl.l_type=F_UNLCK; fl.l_whence= SEEK_SET; fl.l_start=fl.l_len=0; + if (fcntl(methlockfd,F_SETLK,&fl) == -1) + sthfailed("unable to unlock access method area"); } static enum urqresult ensureoptions(void) { @@ -73,10 +89,7 @@ static enum urqresult ensureoptions(void) { for (ccpp= methoddirectories; *ccpp; ccpp++) readmethods(*ccpp, &newoptions, &nread); if (!newoptions) { - curseson(); - addstr(_("No access methods are available.\n\n" - "Press to continue.")); - refresh(); getch(); + sthfailed("no access methods are available"); return urqr_fail; } options= newoptions; @@ -85,20 +98,9 @@ static enum urqresult ensureoptions(void) { return urqr_normal; } -static void lockfailed(const char * reasoning) { - char buf[2048]; - - curseson(); - clear(); - sprintf(buf,_("\n\n%s: %s\n"),DSELECT,reasoning); - addstr(buf); - attrset(A_BOLD); - addstr(_("\nPress to continue.")); - attrset(A_NORMAL); - refresh(); getch(); -} - static enum urqresult lockmethod(void) { + struct flock fl; + if (!methodlockfile) { int l; l= strlen(admindir); @@ -110,19 +112,20 @@ static enum urqresult lockmethod(void) { methlockfd= open(methodlockfile, O_RDWR|O_CREAT|O_TRUNC, 0660); if (methlockfd == -1) { if ((errno == EPERM) || (errno == EACCES)) { - lockfailed("requested operation requires superuser privilege"); + sthfailed("requested operation requires superuser privilege"); return urqr_fail; } - lockfailed("unable to open/create access method lockfile"); + sthfailed("unable to open/create access method lockfile"); return urqr_fail; } } - if (flock(methlockfd,LOCK_EX|LOCK_NB)) { + fl.l_type=F_WRLCK; fl.l_whence=SEEK_SET; fl.l_start=fl.l_len=0; + if (fcntl(methlockfd,F_SETLK,&fl) == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) { - lockfailed("the access method area is already locked"); + sthfailed("the access method area is already locked"); return urqr_fail; } - lockfailed("unable to lock access method area"); + sthfailed("unable to lock access method area"); return urqr_fail; } push_cleanup(cu_unlockmethod,~0, 0,0, 0); @@ -219,10 +222,7 @@ static urqresult runscript(const char *exepath, const char *name) { }; ur= falliblesubprocess(coption->meth->path,name,fallibleargs); } else { - curseson(); - addstr(_("No access method is selected/configured.\n\n" - "Press to continue.")); - refresh(); getch(); + sthfailed("no access method is selected/configured"); ur= urqr_fail; } pop_cleanup(ehflag_normaltidy); diff --git a/lib/lock.c b/lib/lock.c index b4b0e601..ae95df34 100644 --- a/lib/lock.c +++ b/lib/lock.c @@ -74,8 +74,8 @@ void lockdatabase(const char *admindir) { fl.l_start= 0; fl.l_len= 0; if (fcntl(dblockfd,F_SETLK,&fl) == -1) { - if (errno == EWOULDBLOCK || errno == EAGAIN) - ohshit(_("status database area is locked - another dpkg/dselect is running")); + if (errno == EACCES || errno == EAGAIN) + ohshit(_("status database area is locked by another process")); ohshite(_("unable to lock dpkg status database")); } push_cleanup(cu_unlockdb,~0, 0,0, 0); diff --git a/main/enquiry.c b/main/enquiry.c index af502ba0..296cba6c 100644 --- a/main/enquiry.c +++ b/main/enquiry.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/utils/Makefile.in b/utils/Makefile.in index 09cbf464..b55ff420 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -5,7 +5,7 @@ top_srcdir = @top_srcdir@ include ../Makefile.conf -CFLAGS += $(top_srcdir)/optlib +CFLAGS += -I$(top_srcdir)/optlib SSD_SOURCES = start-stop-daemon.c SSD_OBJECTS = $(patsubst %.c, %.o, $(SSD_SOURCES)) -- 2.39.5