Add support for reading symlinks
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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.
|
||||
|
||||
Reference in New Issue
Block a user