Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37515809
en ru br
Репозитории ALT
S:1.29-alt3
5.1: 1.12.2-alt1
4.1: 1.9.4-alt2
4.0: 1.9.4-alt2.M40.1
3.0: 1.2-alt3
www.altlinux.org/Changes

Группа :: Разработка/Прочее
Пакет: fakeroot

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: fakeroot-1.9.6-alt2.patch
Скачать


 Makefile.am         |    9 ++-
 communicate.c       |   23 ++++---
 configure.ac        |   10 ++--
 faked.c             |  187 ++++++++++++++++++++++++++++++++-------------------
 libfakeroot.c       |   11 +++-
 scripts/fakeroot.in |   49 ++++++++------
 symver.awk          |   26 +++++++
 test/compare-tar    |    4 +-
 wrapawk             |    6 +-
 9 files changed, 212 insertions(+), 113 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 66e21e3..945654c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,10 +17,10 @@ faked_LDADD = libcommunicate.la
 simple_SOURCES=simple.c
 noinst_PROGRAMS=simple
 
-CLEANFILES= wrapdef.h wrapstruct.h wrapped.h wraptmpf.h
+CLEANFILES= wrapdef.h wrapstruct.h wrapped.h wraptmpf.h symver.h
 DISTCLEANFILES = fakerootconfig.h
 
-EXTRA_DIST=wrapawk wrapfunc.inp                        \
+EXTRA_DIST=wrapawk wrapfunc.inp symver.awk             \
            debian/rules debian/changelog debian/control  \
 	   message.h \
 	   DEBUG BUGS \
@@ -31,7 +31,10 @@ CLEAN_FILES=fakerootconfig.h
 wrapped.h wrapdef.h wrapstruct.h wraptmpf.h:wrapawk wrapfunc.inp
 	awk -f $(srcdir)/wrapawk < $(srcdir)/wrapfunc.inp  
 
-libfakeroot.lo:libfakeroot.c wrapdef.h wrapstruct.h wraptmpf.h 
+symver.h: symver.awk
+	readelf -Ws $(LIBCPATH) |awk -f $(srcdir)/symver.awk > $@
+
+libfakeroot.lo:libfakeroot.c wrapdef.h wrapstruct.h wraptmpf.h symver.h
 
 fakerootconfig.h: ./config.status
 	CONFIG_FILES= CONFIG_HEADERS= /bin/sh ./config.status
diff --git a/communicate.c b/communicate.c
index 73b3b48..2676b4d 100644
--- a/communicate.c
+++ b/communicate.c
@@ -57,7 +57,6 @@ static pthread_mutex_t comm_sd_mutex = PTHREAD_MUTEX_INITIALIZER;
 #endif /* FAKEROOT_FAKENET */
 
 
-#ifdef FAKEROOT_FAKENET
 static void fail(const char *msg)
 {
   if (errno > 0)
@@ -67,7 +66,6 @@ static void fail(const char *msg)
 
   exit(1);
 }
-#endif /* FAKEROOT_FAKENET */
 
 const char *env_var_set(const char *env){
   const char *s;
@@ -389,8 +387,7 @@ void semaphore_up(){
   while (1) {
     if (semop(sem_id,&op,1)) {
       if (errno != EINTR) {
-	perror("semop(1): encountered an error");
-        exit(1);
+	fail("semop(-1)");
       }
     } else {
       break;
@@ -408,8 +405,7 @@ void semaphore_down(){
   while (1) {
     if (semop(sem_id,&op,1)) {
       if (errno != EINTR) {
-        perror("semop(2): encountered an error");
-        exit(1);
+        fail("semop(1)");
       }
     } else {
       break;
@@ -483,10 +479,17 @@ void send_fakem(const struct fake_msg *buf)
 
   if(init_get_msg()!=-1){
     ((struct fake_msg *)buf)->mtype=1;
-    r=msgsnd(msg_snd, (struct fake_msg *)buf,
-	     sizeof(*buf)-sizeof(buf->mtype), 0);
-    if(r==-1)
-      perror("libfakeroot, when sending message");
+    while (1) {
+      r=msgsnd(msg_snd, (struct fake_msg *)buf,
+	       sizeof(*buf)-sizeof(buf->mtype), 0);
+      if (r==-1) {
+        if (errno != EINTR) {
+	  fail("msgsnd");
+        }
+      } else {
+        break;
+      }
+    }
   }
 }
 
diff --git a/configure.ac b/configure.ac
index a3e9a96..221285e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,14 +1,13 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT([fakeroot],[FAKEROOT_VERSION],[schizo@debian.org],[fakeroot])
-AC_PREREQ(2.61)
-LT_PREREQ(2.1a)
+AC_PREREQ(2.59)
 AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE
 AM_MAINTAINER_MODE
 AC_CONFIG_HEADERS([config.h])
 AC_PROG_MAKE_SET
-LT_INIT
-LT_LANG(C)
+AM_PROG_LIBTOOL
+AC_PROG_CC
 
 AH_BOTTOM([#if ! HAVE_BUILTIN_EXPECT
 #define __builtin_expect(x, expected_value) (x)
@@ -417,6 +416,7 @@ case $target_cpu:$target_os in
 esac
 
 AC_DEFINE_UNQUOTED([LIBCPATH], "$libcpath", [path to libc shared object])
+AC_SUBST([LIBCPATH], [$libcpath])
 AC_SUBST(DLSUFFIX)
 AC_SUBST(LDLIBPATHVAR)
 AC_SUBST(LDPRELOADVAR)
@@ -424,7 +424,7 @@ AC_SUBST(LDPRELOADABS)
 AC_SUBST(LDEXTRAVAR)
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(strdup strstr getresuid setresuid getresgid setresgid setfsuid setfsgid)
+AC_CHECK_FUNCS(strdup strstr getresuid setresuid getresgid setresgid setfsuid setfsgid dlvsym)
 
 AC_CHECK_DECLS([setenv, unsetenv])
 AC_REPLACE_FUNCS([setenv])
diff --git a/faked.c b/faked.c
index aedb884..d8f3d9d 100644
--- a/faked.c
+++ b/faked.c
@@ -94,8 +94,10 @@
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
+#include <setjmp.h>
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
+# include <inttypes.h>
 #endif
 #ifdef HAVE_SYS_SYSMACROS_H
 # include <sys/sysmacros.h>
@@ -114,6 +116,10 @@
 # define SOL_TCP 6 /* this should probably be done with getprotoent */
 #endif
 
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL	"/dev/null"
+#endif
+
 #define fakestat_equal(a, b)  ((a)->dev == (b)->dev && (a)->ino == (b)->ino)
 
 #ifndef FAKEROOT_FAKENET
@@ -151,25 +157,25 @@ unsigned int highest_funcid = sizeof(func_arr)/sizeof(func_arr[0]);
 key_t msg_key=0;
 #else /* FAKEROOT_FAKENET */
 static int comm_sd = -1;
-static volatile int detached = 0;
+static volatile sig_atomic_t detached = 0;
 #endif /* FAKEROOT_FAKENET */
 
 int debug = 0, unknown_is_real = 0;
 char *save_file = NULL;
 
+static sigjmp_buf jmpbuf;
+static sigset_t mask_busy;
 void cleanup(int);
 
-#ifdef FAKEROOT_FAKENET
 static void fail(const char *msg)
 {
   if (errno > 0)
-    fprintf(stderr, "fakeroot daemon: %s (%s)\n", msg, strerror(errno));
+    fprintf(stderr, "fakeroot daemon: %s: %m\n", msg);
   else
     fprintf(stderr, "fakeroot daemon: %s\n", msg);
 
   exit(1);
 }
-#endif
 
 struct data_node_s;
 typedef struct data_node_s {
@@ -495,15 +501,17 @@ int save_database(const uint32_t remote)
 
 #ifdef FAKEROOT_DB_PATH
     if (find_path(i->buf.dev, i->buf.ino, roots, path))
-      fprintf(f,"mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu %s\n",
+      fprintf(f,"mode=%" PRIx64 ",uid=%" PRIu64 ",gid=%" PRIu64 ",nlink=%" PRIu64 ",rdev=%" PRIu64 " %s\n",
               (uint64_t) i->buf.mode,(uint64_t) i->buf.uid,(uint64_t) i->buf.gid,
               (uint64_t) i->buf.nlink,(uint64_t) i->buf.rdev,path);
 #else
-    fprintf(f,"dev=%llx,ino=%llu,mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu\n",
+    fprintf(f,"dev=%" PRIx64 ",ino=%" PRIu64 ",mode=%" PRIo64 ",uid=%" PRIu64 ",gid=%" PRIu64 ",nlink=%" PRIu64 ",rdev=%" PRIu64 "\n",
             (uint64_t) i->buf.dev,(uint64_t) i->buf.ino,(uint64_t) i->buf.mode,
             (uint64_t) i->buf.uid,(uint64_t) i->buf.gid,(uint64_t) i->buf.nlink,
             (uint64_t) i->buf.rdev);
 #endif
+    if (ferror(f))
+      fail(save_file);
   }
 
   return fclose(f);
@@ -525,13 +533,13 @@ int load_database(const uint32_t remote)
 
   while(1){
 #ifdef FAKEROOT_DB_PATH
-    r=scanf("mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu "DB_PATH_SCAN"\n",
+    r=scanf("mode=%" PRIo64 ",uid=%" PRIu64 ",gid=%" PRIu64 ",nlink=%" PRIu64 ",rdev=%" PRIu64 " "DB_PATH_SCAN"\n",
             &stmode, &stuid, &stgid, &stnlink, &strdev, &path);
     if (r != 6)
       break;
 
     if (stat(path, &path_st) < 0) {
-      fprintf(stderr, "%s: %s\n", path, strerror(errno));
+      fprintf(stderr, "%s: %m\n", path);
       if (errno == ENOENT || errno == EACCES)
         continue;
       else
@@ -540,7 +548,7 @@ int load_database(const uint32_t remote)
     stdev = path_st.st_dev;
     stino = path_st.st_ino;
 #else
-    r=scanf("dev=%llx,ino=%llu,mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu\n",
+    r=scanf("dev=%" PRIx64 ",ino=%" PRIu64 ",mode=%" PRIo64 ",uid=%" PRIu64 ",gid=%" PRIu64 ",nlink=%" PRIu64 ",rdev=%" PRIu64 "\n",
             &stdev, &stino, &stmode, &stuid, &stgid, &stnlink, &strdev);
     if (r != 7)
       break;
@@ -567,7 +575,7 @@ int load_database(const uint32_t remote)
 /*                               */
 /*********************************/
 void debug_stat(const struct fakestat *st){
-  fprintf(stderr,"dev:ino=(%llx:%lli), mode=0%lo, own=(%li,%li), nlink=%li, rdev=%lli\n",
+  fprintf(stderr,"dev:ino=(%" PRIx64 ":%" PRIi64 "), mode=0%lo, own=(%li,%li), nlink=%li, rdev=%" PRIi64 "\n",
 	  st->dev,
 	  st->ino,
 	  (long)st->mode,
@@ -751,8 +759,13 @@ void process_msg(struct fake_msg *buf){
 
   func_id_t f;
   f= buf->id;
-  if (f <= highest_funcid)
+  if (f <= highest_funcid) {
+    sigset_t mask_save;
+
+    sigprocmask(SIG_SETMASK, &mask_busy, &mask_save);
     func_arr[f]((struct fake_msg*)buf);
+    sigprocmask(SIG_SETMASK, &mask_save, NULL);
+  }
 }
 
 #ifndef FAKEROOT_FAKENET
@@ -882,7 +895,7 @@ void get_msg(const int listen_sd)
 /*         */
 /***********/
 
-void save(int dummy){
+void save(int dummy UNUSED){
   int savedb_state;
   savedb_state = save_database(0);
   if(!savedb_state) {
@@ -895,21 +908,21 @@ void save(int dummy){
 #ifdef FAKEROOT_FAKENET
 static void detach(int g)
 {
-  int saved_errno = errno;
-
-  if (debug)
-    fprintf(stderr, "fakeroot: detaching, signal=%i\n", g);
-
   detached = 1;
 
-  errno = saved_errno;
+  if (debug) {
+    int saved_errno = errno;
+
+    fprintf(stderr, "fakeroot: detaching, signal=%i\n", g);
+    errno = saved_errno;
+  }
 }
 #endif /* FAKEROOT_FAKENET */
 
 #ifndef FAKEROOT_FAKENET
-# define FAKEROOT_CLEANUPMSG "fakeroot: clearing up message queues and semaphores, signal=%i\n"
+# define FAKEROOT_CLEANUPMSG "fakeroot: clearing up message queues and semaphores, param=%i\n"
 #else /* FAKEROOT_FAKENET */
-# define FAKEROOT_CLEANUPMSG "fakeroot: signal=%i\n"
+# define FAKEROOT_CLEANUPMSG "fakeroot: param=%i\n"
 #endif /* FAKEROOT_FAKENET */
 
 void cleanup(int g)
@@ -918,6 +931,8 @@ void cleanup(int g)
   union semun sem_union;
 #endif /* ! FAKEROOT_FAKENET */
 
+  sigprocmask(SIG_SETMASK, &mask_busy, NULL);
+
   if(debug)
     fprintf(stderr, FAKEROOT_CLEANUPMSG,  g);
 
@@ -928,9 +943,7 @@ void cleanup(int g)
 #endif /* ! FAKEROOT_FAKENET */
 
   save(0);
-
-  if(g!=-1)
-    exit(0);
+  exit(g);
 }
 
 /*************/
@@ -983,6 +996,16 @@ static int get_fakem(struct fake_msg *buf)
 }
 #endif /* FAKEROOT_FAKENET */
 
+static void abort_handler(int dummy UNUSED){
+  const char msg[] = "faked: aborted by unhandled signal\n";
+  write(2, msg, sizeof(msg)-1);
+  _exit(2);
+}
+
+static void cleanup_handler(int dummy UNUSED){
+  siglongjmp(jmpbuf, 1);
+}
+
 int main(int argc, char **argv){
   struct sigaction sa,sa_debug,sa_save;
   int i;
@@ -1052,6 +1075,14 @@ int main(int argc, char **argv){
     }
   }
 
+  sigprocmask(SIG_SETMASK, NULL, &mask_busy);
+  sigaddset(&mask_busy, SIGHUP);
+  sigaddset(&mask_busy, SIGINT);
+  sigaddset(&mask_busy, SIGQUIT);
+  sigaddset(&mask_busy, SIGTERM);
+  sigaddset(&mask_busy, SIGUSR1);
+  sigaddset(&mask_busy, SIGUSR2);
+
   init_hash_table();
 
   if(load)
@@ -1081,8 +1112,7 @@ int main(int argc, char **argv){
   if((msg_get==-1)||(msg_snd==-1)||(sem_id==-1)){
     perror("fakeroot, while creating message channels");
     fprintf(stderr, "This may be due to a lack of SYSV IPC support.\n");
-    cleanup(-1);
-    exit(1);
+    cleanup(1);
   }
 
   if(debug)
@@ -1125,60 +1155,39 @@ int main(int argc, char **argv){
   port = ntohs(addr.sin_port);
 
   sa_detach.sa_handler=detach;
-  sigemptyset(&sa_detach.sa_mask);
+  sa_detach.sa_mask=mask_busy;
   sa_detach.sa_flags=0;
 
 #endif /* FAKEROOT_FAKENET */
 
-  sa.sa_handler=cleanup;
-  sigemptyset(&sa.sa_mask);
-  sa.sa_flags=0;
-  //  sa.sa_restorer=0;
-
   sa_debug.sa_handler=debugdata;
-  sigemptyset(&sa_debug.sa_mask);
+  sa_debug.sa_mask=mask_busy;
   sa_debug.sa_flags=0;
-  //  sa_debug.sa_restorer=0;
   
   sa_save.sa_handler=save;
-  sigemptyset(&sa_save.sa_mask);
+  sa_save.sa_mask=mask_busy;
   sa_save.sa_flags=0;
 
-  for(i=1; i< NSIG; i++){
-    switch (i){
-    case SIGKILL:
-    case SIGTSTP:
-    case SIGCONT:
-      break;
-    case SIGUSR1:
-      /* this is strictly a debugging feature, unless someone can confirm
-         that save will always get a consistent database */
-      sigaction(i,&sa_save,NULL);
-      break;
-    case SIGUSR2:
-      sigaction(i,&sa_debug,NULL);
-      break;
-#ifdef FAKEROOT_FAKENET
-    case SIGHUP:
-      sigaction(i,&sa_detach,NULL);
-      break;
-#endif /* FAKEROOT_FAKENET */
-    default:
-      sigaction(i,&sa,NULL);
-      break;
-    }
-  }
-
   if(!foreground){
-    /* literally copied from the linux klogd code, go to background */
-    if ((pid=fork()) == 0){
-      int fl;
-      int num_fds = getdtablesize();
-      
-      fflush(stdout);
+    /* Copied from the linux klogd code, go to background */
+    int fl;
+
+    if ((fl = open(_PATH_DEVNULL, O_RDWR)) < 0)
+      fail(_PATH_DEVNULL);
+
+    if ((pid = fork()) == -1)
+      fail("fork");
+    else if (pid == 0)
+    {
+      int num_fds;
 
       /* This is the child closing its file descriptors. */
-      for (fl= 0; fl <= num_fds; ++fl)
+      if ((dup2(fl, 0) != 0) ||
+          (dup2(fl, 1) != 1))
+	fail("dup2");
+
+      num_fds = getdtablesize();
+      for (fl= 3; fl <= num_fds; ++fl)
 #ifdef FAKEROOT_FAKENET
 	if (fl != sd)
 #endif /* FAKEROOT_FAKENET */
@@ -1194,13 +1203,55 @@ int main(int argc, char **argv){
     fflush(stdout);
   }
 
+  sa.sa_handler=abort_handler;
+  sigfillset(&sa.sa_mask);
+  sa.sa_flags=0;
+
+  for(i=1; i<NSIG; ++i) {
+    switch (i) {
+      case SIGKILL:
+      case SIGSTOP:
+      case SIGCONT:
+      case SIGTSTP:
+      case SIGHUP:
+      case SIGINT:
+      case SIGQUIT:
+      case SIGTERM:
+      case SIGUSR1:
+      case SIGUSR2:
+        break;
+      default:
+        sigaction(i,&sa,NULL);
+    }
+  }
+
+  if (sigsetjmp(jmpbuf, 1)) {
+    cleanup(0);
+    return 1;
+  }
+
+  sa.sa_handler=cleanup_handler;
+  sigemptyset(&sa.sa_mask);
+  sa.sa_flags=0;
+
+#ifdef FAKEROOT_FAKENET
+  sigaction(SIGHUP,&sa_detach,NULL);
+#else
+  sigaction(SIGHUP,&sa,NULL);
+#endif /* FAKEROOT_FAKENET */
+  sigaction(SIGINT,&sa,NULL);
+  sigaction(SIGQUIT,&sa,NULL);
+  sigaction(SIGTERM,&sa,NULL);
+  sigaction(SIGUSR1,&sa_save,NULL);
+  sigaction(SIGUSR2,&sa_debug,NULL);
+
 #ifndef FAKEROOT_FAKENET
   get_msg();    /* we shouldn't return from this function */
 #else /* FAKEROOT_FAKENET */
   get_msg(sd);  /* we shouldn't return from this function */
 #endif /* FAKEROOT_FAKENET */
 
-  cleanup(-1);  /* if we do return, try to clean up and exit with a nonzero
-		   return status */
+  /* if we do return, try to clean up and exit with a nonzero return status */
+  cleanup(1);
   return 1;
 }
diff --git a/libfakeroot.c b/libfakeroot.c
index 5a4c4be..07ad60c 100644
--- a/libfakeroot.c
+++ b/libfakeroot.c
@@ -105,7 +105,8 @@ extern int unsetenv (const char *name);
  
 struct next_wrap_st{
   void **doit;
-  char *name;
+  const char *name;
+  const char *vers;
 };
 
 void *get_libc(){
@@ -131,6 +132,7 @@ int fakeroot_disabled = 0;
 #include "wrapped.h"
 #include "wraptmpf.h"
 #include "wrapdef.h"
+#include "symver.h"
 #include "wrapstruct.h"
 
 
@@ -153,6 +155,11 @@ void load_library_symbols(void){
   
   if(!done){
     for(i=0; next_wrap[i].doit; i++){
+#if HAVE_DLVSYM
+      if (next_wrap[i].vers)
+	*(next_wrap[i].doit)=dlvsym(get_libc(), next_wrap[i].name, next_wrap[i].vers);
+      if (!next_wrap[i].vers || (msg = dlerror()) != NULL)
+#endif
       *(next_wrap[i].doit)=dlsym(get_libc(), next_wrap[i].name);
       if ( (msg = dlerror()) != NULL){
 	fprintf (stderr, "dlsym(%s): %s\n", next_wrap[i].name, msg);
@@ -716,7 +723,7 @@ int chown(const char *path, uid_t owner, gid_t group){
   INT_SEND_STAT(&st,chown_func, _STAT_VER);
 #endif
   if(!dont_try_chown())
-    r=next_lchown(path,owner,group);
+    r=next_chown(path,owner,group);
   else
     r=0;
   if(r&&(errno==EPERM))
diff --git a/scripts/fakeroot.in b/scripts/fakeroot.in
index dba738b..5c55653 100755
--- a/scripts/fakeroot.in
+++ b/scripts/fakeroot.in
@@ -62,7 +62,7 @@ while test "X$1" != "X--"; do
     -i)
        shift
        if test -f "$1"; then
-         FAKEDOPTS=$FAKEDOPTS" --load"
+         FAKEDOPTS="$FAKEDOPTS --load"
          PIPEIN="<$1"
        else
          echo 1>&2 "fakeroot: database file \`$1' does not exist."
@@ -70,11 +70,11 @@ while test "X$1" != "X--"; do
        ;;
     -s)
        shift
-       FAKEDOPTS=$FAKEDOPTS" --save-file $1"
-       [ -p $1 ] || WAITINTRAP=1
+       FAKEDOPTS="$FAKEDOPTS --save-file $1"
+       [ -p "$1" ] || WAITINTRAP=1
        ;;
     -u|--unknown-is-real)
-       FAKEDOPTS=$FAKEDOPTS" --unknown-is-real"
+       FAKEDOPTS="$FAKEDOPTS --unknown-is-real"
        FAKED_MODE="unknown-is-real"
        ;;
     -b|--fd-base)
@@ -98,7 +98,7 @@ shift #get rid of the '--'
 ABSLIB=""
 if [ -n "$PATHS" ]
 then
-    for dir in `echo $PATHS | sed 's/:/ /g'`
+    for dir in `echo $PATHS | tr : ' '`
     do
 	if test -r "$dir/$LIB"
 	then
@@ -130,19 +130,31 @@ fi
 unset FAKEROOTKEY
 KEY_PID=`eval $FAKED $FAKEDOPTS $PIPEIN`
 FAKEROOTKEY=`echo $KEY_PID|cut -d: -f1`
-PID=`echo $KEY_PID|cut -d: -f2`
+DPID=`echo $KEY_PID|cut -d: -f2`
 
-if [ "$WAITINTRAP" -eq 0 ]; then
-  trap "kill -s @signal@ $PID" EXIT INT
-else
-  trap 'FAKEROOTKEY=$FAKEROOTKEY LD_LIBRARY_PATH="$PATHS"  LD_PRELOAD="$LIB" /bin/ls -l / >/dev/null 2>&1; while kill -s @signal@ $PID 2>/dev/null; do sleep 0.1; done' EXIT INT
-fi
-
-if test -z "$FAKEROOTKEY" || test -z "$PID"; then
+if test -z "$FAKEROOTKEY" || test -z "$DPID"; then
   echo >&2 "fakeroot: error while starting the \`faked' daemon."
   exit 1
 fi
 
+CPID=
+cleanup_handler()
+{
+  trap - EXIT
+  for p in $CPID $DPID; do
+    kill -s @signal@ $p 2>/dev/null
+    if [ "$WAITINTRAP" -ne 0 ]; then
+      while kill -0 $p 2>/dev/null; do
+	sleep 0.01
+      done
+    fi
+  done
+  exit "$@"
+}
+
+trap 'cleanup_handler $?' EXIT
+trap 'cleanup_handler 143' INT QUIT TERM
+
 if test $USEABSLIBPATH -ne 0 ; then
   LIB=$ABSLIB
 fi
@@ -158,11 +170,8 @@ fi
 export FAKEROOT_FD_BASE
 
 if test -z "$*"; then
-  FAKEROOTKEY=$FAKEROOTKEY @LDLIBPATHVAR@="$PATHS" @LDEXTRAVAR@ @LDPRELOADVAR@="$LIB" ${SHELL:-/bin/sh}
-  RESULT=$?
-else
-  FAKEROOTKEY=$FAKEROOTKEY @LDLIBPATHVAR@="$PATHS" @LDEXTRAVAR@ @LDPRELOADVAR@="$LIB" "$@"
-  RESULT=$?
+  set -- ${SHELL:-/bin/sh}
 fi
-
-exit $RESULT
+FAKEROOTKEY=$FAKEROOTKEY @LDLIBPATHVAR@="$PATHS" @LDEXTRAVAR@ @LDPRELOADVAR@="$LIB" "$@" <&0 &
+CPID=$!
+wait $CPID
diff --git a/symver.awk b/symver.awk
new file mode 100644
index 0000000..5c745ce
--- /dev/null
+++ b/symver.awk
@@ -0,0 +1,26 @@
+#!/bin/awk
+BEGIN {
+	print "/* Automatically generated file. Do not edit. See symver.awk. */";
+	print ""
+}
+$4 == "FUNC" && $6 == "DEFAULT" && $8 ~ /@@/ {
+	sym=$8;
+	name=gensub("@@.*", "", 1, sym);
+	vers=gensub("^[^@]*@@", "", 1, sym);
+	printf("#define sym_%s_ver \"%s\"\n", name, vers);
+}
+END {
+	print ""
+	print "#define sym_wrap_fstat_ver sym___fxstat_ver";
+	print "#define sym_wrap_fstat64_ver sym___fxstat64_ver";
+	print "#define sym_wrap_fstatat_ver sym___fxstatat_ver";
+	print "#define sym_wrap_fstatat64_ver sym___fxstatat64_ver";
+	print "#define sym_wrap_lstat64_ver sym___lxstat64_ver";
+	print "#define sym_wrap_lstat_ver sym___lxstat_ver";
+	print "#define sym_wrap_mknod_ver sym___xmknod_ver";
+	print "#define sym_wrap_mknodat_ver sym___xmknodat_ver";
+	print "#define sym_wrap_stat_ver sym___xstat_ver";
+	print "#define sym_wrap_stat64_ver sym___xstat64_ver";
+	print "#define sym_acl_set_fd_ver NULL";
+	print "#define sym_acl_set_file_ver NULL";
+}
diff --git a/test/compare-tar b/test/compare-tar
index d764705..4f2a069 100755
--- a/test/compare-tar
+++ b/test/compare-tar
@@ -2,8 +2,8 @@
 set -e
 echo compare-tar:
 
-gzip -dc $1 | tar -tvf - |awk '{print $1, $2, $3, $NF}' |sort > tmp-1
-gzip -dc $2 | tar -tvf - |awk '{print $1, $2, $3, $NF}' |sort > tmp-2
+gzip -dc $1 | tar -tvf - |awk '{print $1, $2, $3, $NF}' |sed 's/sys\|adm/bin/g' |sort > tmp-1
+gzip -dc $2 | tar -tvf - |awk '{print $1, $2, $3, $NF}' |sed 's/sys\|adm/bin/g' |sort > tmp-2
 
 diff tmp-1 tmp-2 > tmp-diff || true
 
diff --git a/wrapawk b/wrapawk
index a2fd220..6c65b68 100644
--- a/wrapawk
+++ b/wrapawk
@@ -38,7 +38,7 @@ BEGIN{
   argname=$4;
   MACRO=$5;
   if(MACRO){
-    print "  {(void(*))&NEXT_" MACRO "_NOARG, " name "_QUOTE},"  > structfile;
+    print "  {(void(*))&NEXT_" MACRO "_NOARG, " name "_QUOTE, sym_" tolower(name) "_ver},"  > structfile;
     print "extern " ret " (*NEXT_" MACRO "_NOARG)" argtype ";" > headerfile;
     print ret " (*NEXT_" MACRO "_NOARG)" argtype "=TMP_" MACRO ";"> deffile;
     
@@ -48,7 +48,7 @@ BEGIN{
     print "}"                                           > tmpffile;
     print ""                                            > tmpffile;
   } else {
-    print "  {(void(*))&next_" name ", \"" name "\"},"  > structfile;
+    print "  {(void(*))&next_" name ", \"" name "\", sym_" name "_ver},"  > structfile;
     print "extern " ret " (*next_" name ")" argtype ";" > headerfile;
     print ret " (*next_" name ")" argtype "=tmp_" name ";"> deffile;
     
@@ -68,7 +68,7 @@ BEGIN{
 }
 
 END{
-  print "  {NULL, NULL}," > structfile;
+  print "  {NULL, NULL, NULL}," > structfile;
   print "};"              > structfile;
   print "#endif"          > structfile;
   print "#endif"          > tmpffile;
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin