LCOV - code coverage report
Current view: top level - lib - save-cwd.c (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 13 16 81.2 %
Date: 2018-01-30 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* save-cwd.c -- Save and restore current working directory.
       2             : 
       3             :    Copyright (C) 1995, 1997, 1998, 2003, 2004, 2005, 2006 Free
       4             :    Software Foundation, Inc.
       5             : 
       6             :    This program is free software: you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      18             : 
      19             : /* Written by Jim Meyering.  */
      20             : 
      21             : #include <config.h>
      22             : 
      23             : #include "save-cwd.h"
      24             : 
      25             : #include <errno.h>
      26             : #include <stdbool.h>
      27             : #include <stdio.h>
      28             : #include <stdlib.h>
      29             : #include <unistd.h>
      30             : 
      31             : #include "chdir-long.h"
      32             : #include "fcntl--.h"
      33             : #include "xgetcwd.h"
      34             : 
      35             : /* On systems without the fchdir function (WOE), pretend that open
      36             :    always returns -1 so that save_cwd resorts to using xgetcwd.
      37             :    Since chdir_long requires fchdir, use chdir instead.  */
      38             : #if !HAVE_FCHDIR
      39             : # undef open
      40             : # define open(File, Flags) (-1)
      41             : # undef fchdir
      42             : # define fchdir(Fd) (abort (), -1)
      43             : # undef chdir_long
      44             : # define chdir_long(Dir) chdir (Dir)
      45             : #endif
      46             : 
      47             : /* Record the location of the current working directory in CWD so that
      48             :    the program may change to other directories and later use restore_cwd
      49             :    to return to the recorded location.  This function may allocate
      50             :    space using malloc (via xgetcwd) or leave a file descriptor open;
      51             :    use free_cwd to perform the necessary free or close.  Upon failure,
      52             :    no memory is allocated, any locally opened file descriptors are
      53             :    closed;  return non-zero -- in that case, free_cwd need not be
      54             :    called, but doing so is ok.  Otherwise, return zero.
      55             : 
      56             :    The `raison d'etre' for this interface is that the working directory
      57             :    is sometimes inaccessible, and getcwd is not robust or as efficient.
      58             :    So, we prefer to use the open/fchdir approach, but fall back on
      59             :    getcwd if necessary.
      60             : 
      61             :    Some systems lack fchdir altogether: e.g., OS/2, pre-2001 Cygwin,
      62             :    SCO Xenix.  Also, SunOS 4 and Irix 5.3 provide the function, yet it
      63             :    doesn't work for partitions on which auditing is enabled.  If
      64             :    you're still using an obsolete system with these problems, please
      65             :    send email to the maintainer of this code.  */
      66             : 
      67             : int
      68      133378 : save_cwd (struct saved_cwd *cwd)
      69             : {
      70      133378 :   cwd->name = NULL;
      71             : 
      72      133378 :   cwd->desc = open (".", O_RDONLY);
      73      133378 :   if (cwd->desc < 0)
      74             :     {
      75           0 :       cwd->name = xgetcwd ();
      76           0 :       return cwd->name ? 0 : -1;
      77             :     }
      78             : 
      79      133378 :   return 0;
      80             : }
      81             : 
      82             : /* Change to recorded location, CWD, in directory hierarchy.
      83             :    Upon failure, return -1 (errno is set by chdir or fchdir).
      84             :    Upon success, return zero.  */
      85             : 
      86             : int
      87      133378 : restore_cwd (const struct saved_cwd *cwd)
      88             : {
      89      133378 :   if (0 <= cwd->desc)
      90      133378 :     return fchdir (cwd->desc);
      91             :   else
      92           0 :     return chdir_long (cwd->name);
      93             : }
      94             : 
      95             : void
      96      133378 : free_cwd (struct saved_cwd *cwd)
      97             : {
      98      133378 :   if (cwd->desc >= 0)
      99      133378 :     close (cwd->desc);
     100      133378 :   free (cwd->name);
     101      133378 : }

Generated by: LCOV version 1.10