Fix wrong argument of write. Fix return type of getdents. Fix procfs_getdents. Finish implementing the base version of the ps command.
This commit is contained in:
+29
-11
@@ -7,21 +7,19 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <strerror.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FORMAT_S "%5s %5s %6s %s\n"
|
||||
#define FORMAT "%5d %5d %6c %s\n"
|
||||
|
||||
static inline void __iterate_proc_dirs(int fd)
|
||||
static inline void __iterate_proc_dirs(int proc_fd)
|
||||
{
|
||||
char absolute_path[PATH_MAX] = "/proc/";
|
||||
// Holds the file descriptor of the stat file.
|
||||
int stat_fd;
|
||||
// Buffer used to read the stat file.
|
||||
char stat_buffer[BUFSIZ] = { 0 };
|
||||
// Holds the number of bytes read from stat file.
|
||||
ssize_t ret;
|
||||
// Variables used to read the stat file.
|
||||
// (1) pid %d
|
||||
// (2) comm %s
|
||||
@@ -33,7 +31,20 @@ static inline void __iterate_proc_dirs(int fd)
|
||||
pid_t ppid;
|
||||
// The directory entry.
|
||||
dirent_t dent;
|
||||
while (getdents(fd, &dent, sizeof(dirent_t)) == sizeof(dirent_t)) {
|
||||
// Holds the number of bytes read.
|
||||
ssize_t read_bytes;
|
||||
do {
|
||||
// Read an entry.
|
||||
read_bytes = getdents(proc_fd, &dent, sizeof(dirent_t));
|
||||
// We reached the end of the folder.
|
||||
if (read_bytes == 0) {
|
||||
break;
|
||||
}
|
||||
// We encountered an error.
|
||||
if (read_bytes == -1) {
|
||||
perror("Failed to read entry in `/proc` folder");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Skip non-directories.
|
||||
if (dent.d_type != DT_DIR)
|
||||
continue;
|
||||
@@ -42,14 +53,20 @@ static inline void __iterate_proc_dirs(int fd)
|
||||
strcat(absolute_path, "/stat");
|
||||
// Open the `/proc/<pid>/stat` file.
|
||||
if ((stat_fd = open(absolute_path, O_RDONLY, 0)) == -1) {
|
||||
printf("Failed to open `%s`\n", absolute_path);
|
||||
printf("Failed to open `%s`: ", absolute_path);
|
||||
perror(NULL);
|
||||
putchar('\n');
|
||||
continue;
|
||||
}
|
||||
// Reset the stat buffer.
|
||||
memset(stat_buffer, 0, BUFSIZ);
|
||||
// Read the content of the stat file.
|
||||
if ((ret = read(stat_fd, stat_buffer, BUFSIZ)) <= 0) {
|
||||
printf("Cannot read `%s`\n", absolute_path);
|
||||
read_bytes = read(stat_fd, stat_buffer, BUFSIZ);
|
||||
// Check if the read failed.
|
||||
if (read_bytes <= 0) {
|
||||
printf("Cannot read `%s`", absolute_path);
|
||||
perror(NULL);
|
||||
putchar('\n');
|
||||
close(stat_fd);
|
||||
continue;
|
||||
}
|
||||
@@ -61,14 +78,15 @@ static inline void __iterate_proc_dirs(int fd)
|
||||
printf(FORMAT, pid, ppid, state, comm);
|
||||
// Closing stat FD.
|
||||
close(stat_fd);
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd = open("/proc", O_RDONLY | O_DIRECTORY, 0);
|
||||
if (fd == -1) {
|
||||
printf("ps: cannot access '/proc': %s\n\n", strerror(errno));
|
||||
perror("ps: cannot access '/proc' folder");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
printf(FORMAT_S, "PID", "PPID", "STATUS", "CMD");
|
||||
__iterate_proc_dirs(fd);
|
||||
@@ -124,5 +142,5 @@ int main(int argc, char **argv)
|
||||
}
|
||||
close(fd_self);
|
||||
#endif
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user