-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgetcwd_code.c
More file actions
141 lines (126 loc) · 3.43 KB
/
getcwd_code.c
File metadata and controls
141 lines (126 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <pwd.h>
char *my_getcwd(char *buffer, size_t size)
{
ino_t current_inode;
dev_t current_device;
struct stat statbuf;
// Get inode and device number of current directory
if (stat(".", &statbuf) != 0)
{
perror("Failed to get current directory stats");
return NULL;
}
current_inode = statbuf.st_ino;
current_device = statbuf.st_dev;
// Initialize the buffer
if (buffer == NULL)
{
buffer = malloc(size);
if (buffer == NULL)
{
perror("Malloc failed");
return NULL;
}
}
buffer[0] = '\0';
// Start with the current directory and move upwards
// Note: This is a highly simplified version and does not cover all cases
while (1)
{
struct dirent *entry;
DIR *dir = opendir("..");
if (dir == NULL)
{
perror("Failed to open parent directory");
return NULL;
}
// Try to find current directory entry in parent directory
int found = 0;
while ((entry = readdir(dir)) != NULL)
{
if (stat(entry->d_name, &statbuf) != 0)
{
continue;
}
if (statbuf.st_ino == current_inode && statbuf.st_dev == current_device)
{
found = 1;
break;
}
}
if (!found)
{
perror("Current directory not found in parent");
closedir(dir);
return NULL;
}
// Prepend the found directory name to buffer
size_t len = strlen(entry->d_name);
if (len + 2 > size)
{ // including '/' and null terminator
perror("Buffer size too small");
closedir(dir);
return NULL;
}
memmove(buffer + len + 1, buffer, strlen(buffer) + 1);
memcpy(buffer, entry->d_name, len);
buffer[len] = '/';
buffer[len + 1] = '\0';
// Move to the parent directory
if (chdir("..") != 0)
{
perror("Failed to change to parent directory");
closedir(dir);
return NULL;
}
// Update current inode and device to parent's
if (stat(".", &statbuf) != 0)
{
perror("Failed to get parent directory stats");
closedir(dir);
return NULL;
}
current_inode = statbuf.st_ino;
current_device = statbuf.st_dev;
// Check if root directory is reached
if (current_inode == statbuf.st_ino && current_device == statbuf.st_dev)
{
break;
}
closedir(dir);
}
// Final path adjustment
if (buffer[0] == '\0')
{
strcpy(buffer, "/");
}
else
{
size_t len = strlen(buffer);
if (buffer[len - 1] == '/')
{
buffer[len - 1] = '\0'; // Remove trailing slash
}
}
return buffer;
}
int main()
{
char *cwd = my_getcwd(NULL, 1024);
if (cwd)
{
printf("Current directory: %s\n", cwd);
free(cwd);
}
return 0;
}