1 /* @(#)savewd.c 1.3 18/05/30 Copyright 2004-2018 J. Schilling */ 2 /* 3 * Save and restore working directory. 4 * 5 * The code has been adopted from libfind. 6 * 7 * Copyright (c) 2004-2018 J. Schilling 8 */ 9 /* 10 * The contents of this file are subject to the terms of the 11 * Common Development and Distribution License, Version 1.0 only 12 * (the "License"). You may not use this file except in compliance 13 * with the License. 14 * 15 * See the file CDDL.Schily.txt in this distribution for details. 16 * A copy of the CDDL is also available via the Internet at 17 * http://www.opensource.org/licenses/cddl1.txt 18 * 19 * When distributing Covered Code, include this CDDL HEADER in each 20 * file and include the License file CDDL.Schily.txt from this distribution. 21 */ 22 23 #include <schily/unistd.h> 24 #include <schily/types.h> 25 #include <schily/fcntl.h> 26 #include <schily/maxpath.h> 27 #include <schily/string.h> 28 #include <schily/errno.h> 29 #include <schily/standard.h> 30 #include <schily/schily.h> 31 #include "at-defs.h" 32 33 EXPORT int savewd __PR((struct save_wd *sp)); 34 EXPORT void closewd __PR((struct save_wd *sp)); 35 EXPORT int restorewd __PR((struct save_wd *sp)); 36 37 38 EXPORT int savewd(sp)39savewd(sp) 40 struct save_wd *sp; 41 { 42 sp->fd = -1; 43 sp->name = NULL; 44 #ifdef HAVE_FCHDIR 45 /* 46 * Note that we do not need O_RDONLY as we do not like to 47 * run readdir() on that directory but just fchdir(). 48 */ 49 if ((sp->fd = open(".", O_SEARCH|O_DIRECTORY|O_NDELAY)) >= 0) { 50 #ifdef F_SETFD 51 (void) fcntl(sp->fd, F_SETFD, FD_CLOEXEC); 52 #endif 53 return (0); 54 } 55 #endif 56 { 57 char buf[max(8192, PATH_MAX+1)]; 58 59 if (getcwd(buf, sizeof (buf)) == NULL) { 60 return (-1); 61 } 62 sp->name = strdup(buf); 63 if (sp->name == NULL) 64 return (-1); 65 } 66 return (0); 67 } 68 69 EXPORT void closewd(sp)70closewd(sp) 71 struct save_wd *sp; 72 { 73 if (sp->fd >= 0) 74 close(sp->fd); 75 if (sp->name != NULL) 76 free(sp->name); 77 sp->fd = -1; 78 sp->name = NULL; 79 } 80 81 EXPORT int restorewd(sp)82restorewd(sp) 83 struct save_wd *sp; 84 { 85 #ifdef HAVE_FCHDIR 86 if (sp->fd >= 0) 87 return (fchdir(sp->fd)); 88 #endif 89 if (sp->name != NULL) 90 return (lxchdir(sp->name)); 91 92 seterrno(EINVAL); 93 return (-1); 94 } 95