]> Savannah Git Hosting - gnulib.git/commitdiff
stdopen: copy from last use in coreutils
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 5 Jan 2019 19:02:51 +0000 (11:02 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 6 Jan 2019 02:04:24 +0000 (18:04 -0800)
* lib/stdopen.c, lib/stdopen.h, m4/stdopen.m4:
New files, taken from their last commit in coreutils
2007-07-23T12:35:58Z!jim@meyering.net
71aa3ea88084d17bcb4fc1031ad7b66f8647115e.

ChangeLog
lib/stdopen.c [new file with mode: 0644]
lib/stdopen.h [new file with mode: 0644]
m4/stdopen.m4 [new file with mode: 0644]

index d05cd8453d677497102ab1b7410fab2e58dcb831..72d75ef26e6957c2e09923b91b19959e2726cb3c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2019-01-05  Paul Eggert  <eggert@cs.ucla.edu>
+
+       stdopen: copy from last use in coreutils
+       * lib/stdopen.c, lib/stdopen.h, m4/stdopen.m4:
+       New files, taken from their last commit in coreutils
+       2007-07-23T12:35:58Z!jim@meyering.net
+       71aa3ea88084d17bcb4fc1031ad7b66f8647115e.
+
 2019-01-05  Bruno Haible  <bruno@clisp.org>
 
        argp: Don't pass an invalid argument to dgettext().
diff --git a/lib/stdopen.c b/lib/stdopen.c
new file mode 100644 (file)
index 0000000..e9b5544
--- /dev/null
@@ -0,0 +1,74 @@
+/* stdopen.c - ensure that the three standard file descriptors are in use
+
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert and Jim Meyering.  */
+
+#include <config.h>
+
+#include "stdopen.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* Try to ensure that all of the standard file numbers (0, 1, 2)
+   are in use.  Without this, each application would have to guard
+   every call to open, dup, fopen, etc. with tests to ensure they
+   don't use one of the special file numbers when opening a file.
+   Return false if at least one of the file descriptors is initially
+   closed and an attempt to reopen it fails.  Otherwise, return true.  */
+bool
+stdopen (void)
+{
+  int fd;
+  bool ok = true;
+
+  for (fd = 0; fd <= 2; fd++)
+    {
+      if (fcntl (fd, F_GETFD) < 0)
+       {
+         if (errno != EBADF)
+           ok = false;
+         else
+           {
+             static const int contrary_mode[]
+               = { O_WRONLY, O_RDONLY, O_RDONLY };
+             int mode = contrary_mode[fd];
+             int new_fd;
+             /* Open /dev/null with the contrary mode so that the typical
+                read (stdin) or write (stdout, stderr) operation will fail.
+                With descriptor 0, we can do even better on systems that
+                have /dev/full, by opening that write-only instead of
+                /dev/null.  The only drawback is that a write-provoked
+                failure comes with a misleading errno value, ENOSPC.  */
+             if (mode == O_RDONLY
+                 || (new_fd = open ("/dev/full", mode) != fd))
+               new_fd = open ("/dev/null", mode);
+             if (new_fd != fd)
+               {
+                 if (0 <= new_fd)
+                   close (new_fd);
+                 ok = false;
+               }
+           }
+       }
+    }
+
+  return ok;
+}
diff --git a/lib/stdopen.h b/lib/stdopen.h
new file mode 100644 (file)
index 0000000..d54e5f1
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef STDOPEN_H
+# define STDOPEN_H 1
+
+# include <stdbool.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+bool stdopen (void);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
diff --git a/m4/stdopen.m4 b/m4/stdopen.m4
new file mode 100644 (file)
index 0000000..b18c22d
--- /dev/null
@@ -0,0 +1,13 @@
+#serial 1
+dnl Copyright (C) 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_STDOPEN],
+[
+  AC_LIBSOURCES([stdopen.c, stdopen.h])
+  AC_LIBOBJ([stdopen])
+
+  dnl Prerequisites.
+])