summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-10 20:12:02 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-05-10 21:28:52 (GMT)
commitdb81e378576dcc5510032c72060e48e562f208c9 (patch) (side-by-side diff)
tree914c5f277a5fad050527a5c5da815f521e8023dc
parent84db86f0151385a8f05483bf691fde86b4e4e153 (diff)
downloadwydawca-db81e378576dcc5510032c72060e48e562f208c9.tar.gz
wydawca-db81e378576dcc5510032c72060e48e562f208c9.tar.bz2
Remove save-cwd.
* src/pushd.c: New file. * src/Makefile.am: Add pushd.c * src/wydawca.h (push_dir, pop_dir): New functions. * src/diskio.c: Use push_dir/pop_dir. * src/exec.c: Likewise. * src/gpg.c: Likewise. * gnulib.modules: Remove save-cwd. * tests/pushck.c: New file. * tests/pushdir.at: New file. * tests/testsuite.at: Add pushdir.at * tests/Makefile.am: Likewise. * tests/.gitignore: Add pushck.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--configure.ac2
-rw-r--r--gnulib.modules1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/diskio.c24
-rw-r--r--src/exec.c1
-rw-r--r--src/gpg.c6
-rw-r--r--src/pushd.c162
-rw-r--r--src/wydawca.h4
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.am8
-rw-r--r--tests/pushck.c34
-rw-r--r--tests/pushdir.at39
-rw-r--r--tests/testsuite.at2
13 files changed, 258 insertions, 27 deletions
diff --git a/configure.ac b/configure.ac
index 0005006..7002fb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,7 +53,7 @@ AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_STAT
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([memset strchr strdup strerror strrchr setegid setregid setresgid setresuid seteuid setreuid vsyslog sysconf getdtablesize])
+AC_CHECK_FUNCS([fchdir memset strchr strdup strerror strrchr setegid setregid setresgid setresuid seteuid setreuid vsyslog sysconf getdtablesize])
# **********************
# Mailutils
diff --git a/gnulib.modules b/gnulib.modules
index 3d3f7f9..4eb77a8 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -2,5 +2,4 @@ xalloc
obstack
getline
mkdtemp
-save-cwd
backupfile
diff --git a/src/Makefile.am b/src/Makefile.am
index b79e0ec..8fd7d94 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,6 +32,7 @@ wydawca_SOURCES=\
net.c\
pidfile.c\
process.c\
+ pushd.c\
sql.c\
sql.h\
tcpwrap.c\
diff --git a/src/diskio.c b/src/diskio.c
index ed16e35..9addd9b 100644
--- a/src/diskio.c
+++ b/src/diskio.c
@@ -15,7 +15,6 @@
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
-#include "save-cwd.h"
/* Return true if ARG is NULL or is a sub-directory of DIR */
int
@@ -529,7 +528,6 @@ dir_symlink_file (struct file_triplet *trp,
const char *wanted_src, const char *wanted_dst)
{
int rc = 0;
- struct saved_cwd cwd;
const struct spool *spool = trp->spool;
char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir);
char *src, *dst;
@@ -537,13 +535,6 @@ dir_symlink_file (struct file_triplet *trp,
if (!dst_dir)
return 1;
- if (save_cwd (&cwd))
- {
- logmsg (LOG_ERR, _("cannot save current directory: %s"),
- strerror (errno));
- return 1;
- }
-
src = safe_file_name_alloc (wanted_src);
if (!src || src[0] == '/')
{
@@ -585,7 +576,7 @@ dir_symlink_file (struct file_triplet *trp,
if (rc == 0)
{
- if (chdir (dst_dir))
+ if (push_dir (dst_dir))
logmsg (LOG_ERR, _("cannot change to %s: %s"),
dst_dir, strerror (errno));
else
@@ -625,17 +616,16 @@ dir_symlink_file (struct file_triplet *trp,
_("symlinking %s to %s in directory %s failed: %s"),
src, dst, dst_dir, strerror (errno));
}
+ if (pop_dir ())
+ {
+ logmsg (LOG_EMERG, _("cannot restore current directory: %s"),
+ strerror (errno));
+ exit (EX_SOFTWARE);
+ }
}
}
}
- if (restore_cwd (&cwd))
- {
- logmsg (LOG_EMERG, _("cannot restore current directory: %s"),
- strerror (errno));
- exit (EX_SOFTWARE);
- }
-
free (src);
free (dst);
free (dst_dir);
diff --git a/src/exec.c b/src/exec.c
index 94c7e65..ed7ee1e 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -15,7 +15,6 @@
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
-#include "save-cwd.h"
#include <gpgme.h>
#include <sys/types.h>
#include <sys/wait.h>
diff --git a/src/gpg.c b/src/gpg.c
index 979d0c0..474d94b 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -17,7 +17,6 @@
/* GPG interface functions */
#include "wydawca.h"
-#include "save-cwd.h"
#include <gpgme.h>
#define fail_if_err(expr) \
@@ -91,16 +90,15 @@ static int
rmdir_r (const char *name)
{
int rc;
- struct saved_cwd cwd;
- if (save_cwd (&cwd))
+ if (push_dir (NULL))
{
logmsg (LOG_ERR, _("cannot save current directory: %s"),
strerror (errno));
return 1;
}
rc = recursive_rmdir (name);
- if (restore_cwd (&cwd))
+ if (pop_dir ())
{
logmsg (LOG_ERR, _("cannot restore current directory: %s"),
strerror (errno));
diff --git a/src/pushd.c b/src/pushd.c
new file mode 100644
index 0000000..6de10a6
--- a/dev/null
+++ b/src/pushd.c
@@ -0,0 +1,162 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 2011 Sergey Poznyakoff
+
+ Wydawca is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ Wydawca is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with wydawca. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "wydawca.h"
+
+struct saved_dir
+{
+ struct saved_dir *prev;
+ int fd;
+ char *name;
+};
+
+struct saved_dir *dir_stack;
+
+#ifndef O_SEARCH
+# define O_SEARCH 0
+#endif
+
+char *
+getcwd_alloc (void)
+{
+ size_t size = 0;
+ char *buf = NULL;
+ char *p;
+
+ do
+ {
+ if (!buf)
+ {
+ size = 64;
+ buf = malloc (size);
+ }
+ else
+ {
+ char *np;
+ size_t ns = 2 * size;
+ if (ns < size)
+ {
+ free (buf);
+ errno = ENOMEM;
+ return NULL;
+ }
+ size = ns;
+ np = realloc (buf, size);
+ if (!np)
+ free (buf);
+ buf = np;
+ }
+ if (!buf)
+ return NULL;
+ }
+ while ((p = getcwd (buf, size)) == NULL && errno == ERANGE);
+ if (!p)
+ {
+ int ec = errno;
+ free (buf);
+ buf = NULL;
+ errno = ec;
+ }
+ return buf;
+}
+
+static int
+_save_dir (struct saved_dir *sd)
+{
+ int fd;
+
+#ifdef HAVE_FCHDIR
+ fd = open (".", O_SEARCH);
+#else
+ fd = -1;
+#endif
+ if (fd == -1)
+ {
+ sd->name = getcwd_alloc ();
+ if (!sd->name)
+ return errno;
+ }
+ else
+ sd->name = NULL;
+ sd->fd = fd;
+ return 0;
+}
+
+static void
+_drop_dir (struct saved_dir *sd)
+{
+ if (sd->fd != -1)
+ close (sd->fd);
+ free (sd->name);
+ free (sd);
+}
+
+static int
+_push_dir (struct saved_dir *sd, const char *dirname)
+{
+ int rc = _save_dir (sd);
+ if (rc)
+ return rc;
+ if (dirname && chdir (dirname))
+ {
+ rc = errno;
+ _drop_dir (sd);
+ return rc;
+ }
+ return 0;
+}
+
+int
+push_dir (const char *dirname)
+{
+ int rc;
+ struct saved_dir *sd = malloc (sizeof (*sd));
+
+ if (!sd)
+ return errno;
+ rc = _push_dir (sd, dirname);
+ if (rc)
+ {
+ errno = rc;
+ return -1;
+ }
+ sd->prev = dir_stack;
+ dir_stack = sd;
+ return 0;
+}
+
+int
+pop_dir ()
+{
+ struct saved_dir *sd = dir_stack;
+ int rc;
+
+ if (!sd)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ dir_stack = sd->prev;
+ if (sd->fd != -1)
+ rc = fchdir (sd->fd);
+ else
+ rc = chdir (sd->name);
+ if (rc)
+ rc = errno;
+ _drop_dir (sd);
+ errno = rc;
+ return rc;
+}
diff --git a/src/wydawca.h b/src/wydawca.h
index 7b9875f..8d5dd34 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -554,3 +554,7 @@ int tcpwrap_access(int fd);
/* userprivs.c */
int wydawca_userprivs (uid_t uid, gid_t gid, gid_t *grplist, size_t ngrp);
+
+int push_dir (const char *dirname);
+int pop_dir (void);
+char *getcwd_alloc (void);
diff --git a/tests/.gitignore b/tests/.gitignore
index 15381c3..7c8bd6b 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -8,3 +8,4 @@ source
dest
wstest
wsbatch
+pushck
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3da497b..b174fcd 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,9 +43,10 @@ TESTSUITE_AT = \
check-fail.at\
check-notify.at\
check-ok.at\
- testsuite.at\
notify-upl.at\
mailstats.at\
+ pushdir.at\
+ testsuite.at\
upload.at\
upload-dry.at\
version.at\
@@ -72,8 +73,9 @@ check-local: atconfig atlocal $(TESTSUITE)
#installcheck-local:
# $(SHELL) $(TESTSUITE) AUTOTEST_PATH=$(exec_prefix)/bin
-check_PROGRAMS = wstest wsbatch
-INCLUDES = -I$(top_srcdir)/grecs/src -I$(top_srcdir)/gnu -I../gnu
+check_PROGRAMS = wstest wsbatch pushck
+INCLUDES = -I$(top_srcdir)/grecs/src -I$(top_srcdir)/gnu -I../gnu -I$(top_srcdir)/src
LDADD=../grecs/src/libgrecs.a ../gnu/libgnu.a
+pushck_LDADD=../src/pushd.o
diff --git a/tests/pushck.c b/tests/pushck.c
new file mode 100644
index 0000000..f94cbf7
--- a/dev/null
+++ b/tests/pushck.c
@@ -0,0 +1,34 @@
+#include <config.h>
+#include <wydawca.h>
+
+static void
+printcwd (int c)
+{
+ char *dir = getcwd_alloc ();
+ printf ("%c%s\n", c, dir);
+ free (dir);
+}
+
+int
+main (int argc, char **argv)
+{
+ while (--argc)
+ {
+ char *dir = *++argv;
+ if (push_dir (dir))
+ {
+ perror (dir);
+ abort ();
+ }
+ printcwd ('+');
+ }
+
+ do
+ {
+ printcwd ('-');
+ }
+ while (pop_dir() == 0);
+ exit(0);
+}
+
+ /*===============*/
diff --git a/tests/pushdir.at b/tests/pushdir.at
new file mode 100644
index 0000000..3887ffb
--- a/dev/null
+++ b/tests/pushdir.at
@@ -0,0 +1,39 @@
+# Check directory stack functions -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# Wydawca is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# Wydawca is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Wydawca. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Directory push/pop])
+AT_KEYWORDS([dir pushdir])
+
+AT_CHECK([
+install-sh -d a/b/c/d/e >/dev/null || exit 1
+cwd=`pwd`
+pushck a b c d e | sed 's|'"$cwd"'||'
+],
+[0],
+[+/a
++/a/b
++/a/b/c
++/a/b/c/d
++/a/b/c/d/e
+-/a/b/c/d/e
+-/a/b/c/d
+-/a/b/c
+-/a/b
+-/a
+-
+])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 1adc6db..240ab5d 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -23,6 +23,8 @@ AT_INIT
AT_TESTED([wydawca])
m4_include([version.at])
m4_include([wordsplit.at])
+m4_include([pushdir.at])
+
m4_include([upload-dry.at])
m4_include([upload.at])
m4_include([notify-upl.at])

Return to:

Send suggestions and report system problems to the System administrator.