summaryrefslogtreecommitdiffabout
path: root/src
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 /src
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 (limited to 'src') (more/less context) (ignore whitespace changes)
-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
6 files changed, 176 insertions, 22 deletions
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);

Return to:

Send suggestions and report system problems to the System administrator.