1/* BEGIN LICENSE BLOCK 2 * Version: CMPL 1.1 3 * 4 * The contents of this file are subject to the Cisco-style Mozilla Public 5 * License Version 1.1 (the "License"); you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License 7 * at www.eclipse-clp.org/license. 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and limitations 12 * under the License. 13 * 14 * The Original Code is The ECLiPSe Constraint Logic Programming System. 15 * The Initial Developer of the Original Code is Cisco Systems, Inc. 16 * Portions created by the Initial Developer are 17 * Copyright (C) 1988-2006 Cisco Systems, Inc. All Rights Reserved. 18 * 19 * Contributor(s): 20 * 21 * END LICENSE BLOCK */ 22 23/* 24 * VERSION $Id: getwd.c,v 1.1 2008/06/30 17:43:55 jschimpf Exp $ 25*/ 26 27/*--------------------------------------------------------------------- 28 * 29 * author: M.Dorochevsky 30 * modified by: 31 *--------------------------------------------------------------------- 32 */ 33 34#ifdef SYSDIR 35 36/* #include <sys/types.h> */ /* all included in bip_misc.c */ 37/* #include <sys/param.h> */ 38/* #include <sys/stat.h> */ 39#include <sys/dir.h> 40 41#define FILESYSTEM_READ_ERROR \ 42"getwd(): Filesystem error: read()\nCurrent working directory maybe changed.\n" 43 44 45 46/* char * strcpy(); */ 47 48 49 50/* 51 * Copies the pathname of the current working directory into the 52 * buffer path and returns a pointer to this pathname. 53 * Path is a buffer of MAX_PATH_LEN characters. 54 * 55 * If an error occurs, getwd() returns zero ((char *) 0) and leaves 56 * an error message in path 57 */ 58 59char * getwd(char *path) 60{ 61 struct stat dotstat, dotdotstat; 62 struct direct dir; 63 int fd; 64 char * ptail; 65 unsigned len, pathlen; 66 char statbuf[MAX_PATH_LEN]; 67 68 ptail = &(path[MAX_PATH_LEN-1]); 69 *ptail = '\0'; 70 pathlen = 0; 71 statbuf[0] = '.'; 72 statbuf[1] = '.'; 73 statbuf[2] = '/'; 74 75 for(;;) { 76 if(stat(".", &dotstat) < 0) { 77 (void) strcpy(path,"getwd(): stat()\n"); 78 goto err; 79 } 80 if ((fd = open("..",0)) < 0) { 81 (void) strcpy(path,"getwd(): open()\n"); 82 goto err; 83 } 84 if(fstat(fd, &dotdotstat) < 0) { 85 (void) strcpy(path,"getwd(): fstat()\n"); 86 goto err_close; 87 } 88 89 if ((dotstat.st_dev == dotdotstat.st_dev) && 90 (dotstat.st_ino == dotdotstat.st_ino)) { 91 92 /* 93 * root reached 94 */ 95 (void) close(fd); 96 break; 97 } 98 else { 99 100 /* 101 * root not reached 102 */ 103 if (pathlen + DIRSIZ + 1 >= MAX_PATH_LEN) { 104 (void) strcpy(path,"getwd(): Pathname too long.\n"); 105 goto err_close; /* path name too long */ 106 } 107 108 do { 109 if (read(fd,(char *) &dir,sizeof(dir)) != sizeof(dir)) { 110 (void) strcpy(path, FILESYSTEM_READ_ERROR); 111 goto err_close; 112 } 113 (void) strcpy(statbuf + 3, dir.d_name); 114 (void) stat(statbuf, &dotdotstat); 115 } while ((dotdotstat.st_ino != dotstat.st_ino) || 116 (dotdotstat.st_dev != dotstat.st_dev)); 117 (void) close(fd); 118 if(chdir("..") < 0) { 119 (void) strcpy(path,"getwd(): fopen()\n"); 120 goto err_close; 121 } 122 123 /* copy name to path */ 124 { 125 register char * pname; 126 127 pname = dir.d_name; 128 len = 0; 129 while ((len < DIRSIZ) && (*pname++ != '\0')) 130 len++; 131 132 pathlen += len + 1; 133 for (pname = &(dir.d_name[len]); len; len--) 134 *--ptail = *--pname; 135 *--ptail = '/'; 136 } 137 } 138 } 139 140 if (pathlen == 0) { 141 path[0] = '/'; 142 path[1] = '\0'; 143 } 144 else { 145 register char * pto = path; 146 register char * pfrom = ptail; 147 148 for (len = 0; len <= pathlen; len++) 149 *pto++ = *pfrom++; 150 151 /* go back to initial working directory */ 152 (void) chdir(ptail+1); 153 } 154 155 return(path); 156 157err_close: 158 (void) close(fd); 159err: 160 /* go back to initial working directory */ 161 if (*ptail) 162 (void) chdir(ptail+1); 163 return((char *) 0); 164} 165 166#endif 167 168