Add support for reading symlinks

This commit is contained in:
Enrico Fraccaroli (Galfurian)
2023-11-21 14:20:41 -05:00
parent 1197797ee1
commit f066dd2ad9
22 changed files with 173 additions and 54 deletions
+2
View File
@@ -133,6 +133,8 @@ add_library(
${PROJECT_SOURCE_DIR}/src/unistd/kill.c
${PROJECT_SOURCE_DIR}/src/unistd/signal.c
${PROJECT_SOURCE_DIR}/src/unistd/interval.c
${PROJECT_SOURCE_DIR}/src/unistd/symlink.c
${PROJECT_SOURCE_DIR}/src/unistd/readlink.c
${PROJECT_SOURCE_DIR}/src/libc_start.c
${PROJECT_SOURCE_DIR}/src/crt0.S
)
+3
View File
@@ -53,5 +53,8 @@
/// Maximum number of characters in a path name.
#define PATH_MAX 4096
/// Maximum length of arguments provided to exec function.
#define ARG_MAX 256
/// Maximum pid number.
#define PID_MAX_LIMIT 32768
+7
View File
@@ -60,6 +60,13 @@ int unlink(const char *path);
/// @return 0 on success, a negative number if fails and errno is set.
int symlink(const char *linkname, const char *path);
/// @brief Read the symbolic link, if present.
/// @param file the file for which we want to read the symbolic link information.
/// @param buffer the buffer where we will store the symbolic link path.
/// @param bufsize the size of the buffer.
/// @return The number of read characters on success, -1 otherwise and errno is set to indicate the error.
int readlink(const char *path, char *buffer, size_t bufsize);
/// @brief Wrapper for exit system call.
/// @param status The exit status.
extern void exit(int status);
+17 -18
View File
@@ -18,30 +18,31 @@ static int __fd = -1;
/// @brief It parses the line (as string) and saves its content inside the
/// group_t structure.
/// @param grp the struct where we store the information.
/// @param buf the buffer from which we extract the information.
/// @param buf the line from which we extract the information.
static inline void __parse_line(group_t *grp, char *buf)
{
assert(grp && "Received null grp!");
char *token;
// Parse the group name.
if ((token = strtok(buf, ":")) != NULL) {
token = strtok(buf, ":");
if (token != NULL) {
grp->gr_name = token;
}
// Parse the group passwd.
if ((token = strtok(NULL, ":")) != NULL) {
token = strtok(NULL, ":");
if (token != NULL) {
grp->gr_passwd = token;
}
// Parse the group id.
if ((token = strtok(NULL, ":")) != NULL) {
token = strtok(NULL, ":");
if (token != NULL) {
grp->gr_gid = atoi(token);
}
size_t found_users = 0;
while ((token = strtok(NULL, ",\n\0")) != NULL && found_users < MAX_MEMBERS_PER_GROUP) {
grp->gr_mem[found_users] = token;
found_users += 1;
}
// Null terminate array
grp->gr_mem[found_users] = "\0";
}
@@ -52,8 +53,8 @@ static inline void __parse_line(group_t *grp, char *buf)
/// @param buflen the length of the buffer.
/// @param name the name we are looking for.
/// @param gid the group id we must match.
/// @return a pointer to the filled input buffer on success, NULL on failure.
static inline char *__search_entry(int fd, char *buf, int buflen, const char *name, gid_t gid)
/// @return 1 on success, 0 on failure.
static inline int __search_entry(int fd, char *buf, size_t buflen, const char *name, gid_t gid)
{
int ret;
char c;
@@ -65,7 +66,7 @@ static inline char *__search_entry(int fd, char *buf, int buflen, const char *na
}
if (pos >= buflen) {
errno = ERANGE;
return NULL;
return 0;
}
// If we have found a newline or the EOF, parse the entry.
if ((c == '\n') || (ret == EOF)) {
@@ -74,7 +75,7 @@ static inline char *__search_entry(int fd, char *buf, int buflen, const char *na
// Check the entry.
if (name) {
if (strncmp(buf, name, strlen(name)) == 0) {
return buf;
return 1;
}
} else {
int gid_start = -1, col_count = 0;
@@ -91,7 +92,7 @@ static inline char *__search_entry(int fd, char *buf, int buflen, const char *na
int found_gid = atoi(&buf[gid_start]);
// Check the gid.
if (found_gid == gid) {
return buf;
return 1;
}
}
}
@@ -106,7 +107,7 @@ static inline char *__search_entry(int fd, char *buf, int buflen, const char *na
}
}
errno = ENOENT;
return NULL;
return 0;
}
group_t *getgrgid(gid_t gid)
@@ -148,12 +149,11 @@ int getgrgid_r(gid_t gid, group_t *group, char *buf, size_t buflen, group_t **re
return 0;
}
char *entry = __search_entry(fd, buf, buflen, NULL, gid);
if (entry != NULL) {
if (__search_entry(fd, buf, buflen, NULL, gid)) {
// Close the file.
close(fd);
// Parse the line.
__parse_line(group, entry);
__parse_line(group, buf);
// Return success.
return 1;
}
@@ -173,12 +173,11 @@ int getgrnam_r(const char *name, group_t *group, char *buf, size_t buflen, group
return 0;
}
char *entry = __search_entry(fd, buf, buflen, name, 0);
if (entry != NULL) {
if (__search_entry(fd, buf, buflen, name, 0)) {
// Close the file.
close(fd);
// Parse the line.
__parse_line(group, entry);
__parse_line(group, buf);
// Return success.
return 1;
}
+10
View File
@@ -0,0 +1,10 @@
/// @file readlink.c
/// @brief
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "sys/errno.h"
#include "system/syscall_types.h"
_syscall3(int, readlink, const char *, path, char *, buffer, size_t, bufsize)
+1 -1
View File
@@ -1,4 +1,4 @@
/// @file unlink.c
/// @file symlink.c
/// @brief
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
/// See LICENSE.md for details.