Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!cornell!uw-beaver!ssc-vax!uvicctr!tholm From: tholm@uvicctr.UUCP (Terrence W. Holm) Newsgroups: comp.os.minix Subject: getcwd(3) Message-ID: <482@uvicctr.UUCP> Date: 26 Aug 88 00:15:16 GMT Reply-To: tholm@uvicctr.UUCP (Terrence W. Holm) Organization: University of Victoria, Victoria B.C. Canada Lines: 244 EFTH MINIX report #38 - August 1988 - getcwd(3) There follows an implementation of getcwd(3), derived from Adri Koppes' pwd(1). Also included is a pwd(1) which uses getcwd(3). This should be used, as the MINIX V1.1-V1.3 pwd(1) does not handle 14 character file names. [Yes, V1.3 had a patch, but it was wrong.] ---------------------------------------------------------- echo x - getcwd.3 gres '^X' '' > getcwd.3 << '/' XSUBROUTINES X getcwd(3) - current working directory X XINVOCATION X char *getcwd( buffer, size ) X char *buffer; X int size; X XEXPLANATION X The name of the current working directory is placed into X the . is the size of the buffer, it should X be at least 128 (PATH_MAX+1). X XRESULTS X NULL : Error. X o/w : Pointer to name at . / echo x - pwd.1 gres '^X' '' > pwd.1 << '/' XCOMMANDS X pwd(1) - print working directory X XINVOCATION X pwd X XEXPLANATION X The path name, from the root, of the current directory X is written to standard output. / echo x - getcwd.c gres '^X' '' > getcwd.c << '/' X/* getcwd(3) X * X * Author: Terrence W. Holm Aug. 1988 X * X * Directly derived from Adri Koppes' pwd(1). X */ X X#include X#include X#include X#include X X#define NULL (char *) 0 X#define O_RDONLY 0 X#define DIRECT_SIZE (sizeof (struct direct)) X#define PATH_MAX 127 X Xextern char *rindex(); X Xextern int errno; X X Xchar *getcwd( buffer, size ) X char *buffer; X int size; X X { X static char path[ PATH_MAX + 1 ]; X struct stat current; X X if ( buffer == NULL || size == 0 ) X { X errno = EINVAL; X return( NULL ); X } X X path[0] = '\0'; X X /* Get the inode for the current directory */ X X if ( stat( ".", ¤t ) == -1 ) X return( NULL ); X X if ( (current.st_mode & S_IFMT) != S_IFDIR ) X return( NULL ); X X X /* Run backwards up the directory tree, grabbing */ X /* directory names on the way. */ X X while (1) X { X struct stat parent; X struct direct d; X int same_device = 0; X int found = 0; X int fd; X X /* Get the inode for the parent directory */ X X if ( chdir( ".." ) == -1 ) X return( NULL ); X X if ( stat( ".", &parent ) == -1 ) X return( NULL ); X X if ( (parent.st_mode & S_IFMT) != S_IFDIR ) X return( NULL ); X X if ( current.st_dev == parent.st_dev ) X same_device = 1; X X X /* At the root, "." is the same as ".." */ X X if ( same_device && current.st_ino == parent.st_ino ) X break; X X X /* Search the parent directory for the current entry */ X X if ( (fd = open( ".", O_RDONLY )) == -1 ) X return( NULL ); X X while ( ! found && read(fd, &d, DIRECT_SIZE) == DIRECT_SIZE ) X { X if ( same_device ) X { X if ( current.st_ino == d.d_ino ) X found = 1; X } X else X { X static char temp_name[ DIRSIZ + 1 ]; X static struct stat dir_entry; X X temp_name[0] = '\0'; X strncat( temp_name, d.d_name, DIRSIZ ); X X if ( stat( temp_name, &dir_entry ) == -1 ) X { X close( fd ); X return( NULL ); X } X X if ( current.st_dev == dir_entry.st_dev && X current.st_ino == dir_entry.st_ino ) X found = 1; X } X } X X close( fd ); X X if ( ! found ) X return( NULL ); X X if ( strlen(path) + DIRSIZ + 1 > PATH_MAX ) X { X errno = ERANGE; X return( NULL ); X } X X strcat( path, "/" ); X strncat( path, d.d_name, DIRSIZ ); X X current.st_dev = parent.st_dev; X current.st_ino = parent.st_ino; X } X X X /* Copy the reversed path name into */ X X if ( strlen(path) + 1 > size ) X { X errno = ERANGE; X return( NULL ); X } X X if ( strlen(path) == 0 ) X { X strcpy( buffer, "/" ); X return( buffer ); X } X X *buffer = '\0'; X X { X char *r; X X while ( (r = rindex( path, '/' )) != NULL ) X { X strcat( buffer, r ); X *r = '\0'; X } X } X X return( buffer ); X } / echo x - pwd.c gres '^X' '' > pwd.c << '/' X/* pwd(1) X * X * Author: Terrence W. Holm Aug. 1988 X */ X X#define NULL (char *) 0 X#define PATH_MAX 127 X Xextern char *getcwd(); X X Xmain() X { X char buffer[ PATH_MAX + 1 ]; X char *path; X X path = getcwd( buffer, PATH_MAX + 1 ); X X if ( path == NULL ) X { X perror( ".." ); X exit( 1 ); X } X X write( 1, path, strlen(path) ); X write( 1, "\n", 1 ); X X exit( 0 ); X } / ---------------------------------------------------------- Edwin L. Froese uw-beaver!ubc-cs!mprg!handel!froese Terrence W. Holm uw-beaver!uvicctr!tholm