aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-12-31 21:47:26 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-12-31 21:47:26 +0000
commit5af96b9e2a15827bc49e24af497571b45959ca6a (patch)
tree5d08aefa82f86fa33a42546b91321460a74ff8a3 /paludis/repositories/e/ebuild/utils/locked_pipe_command.cc
parent6d95e48cbd418ee7a49bceeae864c41eba31eeb3 (diff)
downloadpaludis-5af96b9e2a15827bc49e24af497571b45959ca6a.tar.gz
paludis-5af96b9e2a15827bc49e24af497571b45959ca6a.tar.xz
Switch to using pipes to implement has_version etc.
Diffstat (limited to 'paludis/repositories/e/ebuild/utils/locked_pipe_command.cc')
-rw-r--r--paludis/repositories/e/ebuild/utils/locked_pipe_command.cc107
1 files changed, 107 insertions, 0 deletions
diff --git a/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc b/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc
new file mode 100644
index 000000000..eca37809d
--- /dev/null
+++ b/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc
@@ -0,0 +1,107 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <cstdlib>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <iostream>
+
+int
+main(int argc, char *argv[])
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << " write_fd read_fd" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ int write_fd(std::atoi(argv[1])), read_fd(std::atoi(argv[2]));
+ if (0 != ::lockf(write_fd, F_LOCK, 0))
+ {
+ std::cerr << "Error: " << argv[0] << ": lockf failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /* copy stdin to the pipe read buffer */
+ char buf[1024];
+ int c, w;
+ while (((c = read(0, buf, 1024))) > 0)
+ {
+ char * buf_p(buf);
+ while (((w = write(write_fd, buf_p, c))) > 0)
+ {
+ buf_p += w;
+ c -= w;
+ if (c == 0)
+ break;
+ }
+ if (w == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": write failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (c == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": read failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /* append null to the pipe read buffer */
+ buf[0] = '\0';
+ while (((w = write(write_fd, buf, 1))) == 0)
+ sleep(0);
+ if (w == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": write failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /* copy write buffer to stdout until we get a null, and discard that null */
+ while (((c = read(read_fd, buf, 1))) > 0)
+ {
+ if (buf[0] == '\0')
+ break;
+
+ while (((w = write(1, buf, c))) == 0)
+ sleep(0);
+ if (w == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": write failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (c == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": read failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (0 != ::lockf(write_fd, F_ULOCK, 0))
+ {
+ std::cerr << "Error: " << argv[0] << ": lockf unlock failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+