Merge branch 'release/v0.4.0'

This commit is contained in:
Enrico Fraccaroli
2021-10-14 18:01:02 +02:00
437 changed files with 42261 additions and 20773 deletions
+12 -11
View File
@@ -11,23 +11,24 @@
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: true
#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
AlignOperands: true
AlignTrailingComments: false
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: true
AllowShortBlocksOnASingleLine: Always
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BinPackParameters: false
BraceWrapping:
AfterClass: false
AfterControlStatement: false
@@ -52,7 +53,7 @@ BreakConstructorInitializersBeforeComma: false
#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
#CompactNamespaces: false # Unknown to clang-format-4.0
ConstructorInitializerAllOnOneLineOrOnePerLine: false
@@ -463,7 +464,7 @@ SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
Standard: Auto
TabWidth: 4
UseTab: Always
UseTab: Never
...
+3
View File
@@ -99,3 +99,6 @@ src/initscp/initfscp
# OS generated files
.DS_Store
# OS filesystem files.
files/bin/**
+136 -89
View File
@@ -1,111 +1,158 @@
# ------------------------------------------------------------------------------
# =============================================================================
# Set the minimum required version of cmake.
cmake_minimum_required(VERSION 2.8)
# Initialize the project.
project(MentOs)
cmake_minimum_required(VERSION 2.8.4)
message(STATUS "Crosscompiling: ${CMAKE_CROSSCOMPILING}")
# ------------------------------------------------------------------------------
# Add operating system specific option.
message(STATUS "System name: ${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "Kernel version: ${CMAKE_SYSTEM_VERSION}")
if ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE)
# Apple MacOSx
elseif ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32)
# Windows
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
else()
# Generic Unix System
find_program(LSB_RELEASE_EXEC lsb_release)
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release
OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "LSB version: ${LSB_RELEASE_VERSION_SHORT}")
if (${LSB_RELEASE_VERSION_SHORT} MATCHES "^18")
# Ubuntu 18
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
elseif (${LSB_RELEASE_VERSION_SHORT} MATCHES "^19")
# Ubuntu 19
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
elseif (${LSB_RELEASE_VERSION_SHORT} MATCHES "^20")
# Ubuntu 20
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
else()
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
endif()
# =============================================================================
# Set the default build type to Debug.
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE
"Debug"
CACHE STRING "Choose the type of build." FORCE)
endif()
# ------------------------------------------------------------------------------
# Add the debugging option.
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
"Chose the type of debugging: DEBUG_STDIO DEBUG_LOG")
set_property(
CACHE DEBUGGING_TYPE PROPERTY STRINGS
DEBUG_STDIO
DEBUG_LOG)
if ("${DEBUGGING_TYPE}" STREQUAL "DEBUG_STDIO" OR
"${DEBUGGING_TYPE}" STREQUAL "DEBUG_LOG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${DEBUGGING_TYPE}")
message(STATUS "Setting debugging type to ${DEBUGGING_TYPE}.")
else ()
message(FATAL_ERROR "Debugging type ${DEBUGGING_TYPE} is not valid.")
endif ()
# =============================================================================
# Add operating system specific option.
message(STATUS "Crosscompiling : ${CMAKE_CROSSCOMPILING}")
message(STATUS "System name : ${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "Kernel version : ${CMAKE_SYSTEM_VERSION}")
if((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE)
# Set the Apple MacOSx compilers.
if(CMAKE_VERSION VERSION_LESS "3.6.0")
include(CMakeForceCompiler)
cmake_force_c_compiler(i386-elf-gcc Clang)
cmake_force_cxx_compiler(i386-elf-g++ Clang)
else()
set(CMAKE_C_COMPILER i386-elf-gcc)
set(CMAKE_CXX_COMPILER i386-elf-g++)
set(CMAKE_AR i386-elf-ar)
endif()
# Speicfy the linker.
set(CMAKE_LINKER i386-elf-ld)
# Specify the linker flags.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib")
# ------------------------------------------------------------------------------
elseif((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32)
# Windows set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
else()
# Generic Unix System
find_program(LSB_RELEASE_EXEC lsb_release)
execute_process(
COMMAND "${LSB_RELEASE_EXEC}" --short --release
OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "LSB version : ${LSB_RELEASE_VERSION_SHORT}")
if(${LSB_RELEASE_VERSION_SHORT} MATCHES "^18")
# Ubuntu 18 set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
elseif(${LSB_RELEASE_VERSION_SHORT} MATCHES "^19")
# Ubuntu 19
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
elseif(${LSB_RELEASE_VERSION_SHORT} MATCHES "^20")
# Ubuntu 20
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
else()
# set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
endif()
endif()
# =============================================================================
# Add the debugging option.
set(DEBUGGING_TYPE
"DEBUG_STDIO"
CACHE STRING "Chose the type of debugging: DEBUG_STDIO DEBUG_LOG")
set_property(CACHE DEBUGGING_TYPE PROPERTY STRINGS DEBUG_STDIO DEBUG_LOG)
if("${DEBUGGING_TYPE}" STREQUAL "DEBUG_STDIO" OR "${DEBUGGING_TYPE}" STREQUAL "DEBUG_LOG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${DEBUGGING_TYPE}")
message(STATUS "Setting debugging type to ${DEBUGGING_TYPE}.")
else()
message(FATAL_ERROR "Debugging type ${DEBUGGING_TYPE} is not valid.")
endif()
# =============================================================================
# Add the sub-directories.
add_subdirectory(programs)
add_subdirectory(programs/tests)
add_subdirectory(mentos)
add_subdirectory(initscp)
add_subdirectory(libc)
add_subdirectory(doc)
# ------------------------------------------------------------------------------
# Generate the initrd filesystem.
# =============================================================================
# Target to generate the initrd filesystem.
add_custom_target(
initfs
COMMAND echo "---------------------------------------------"
COMMAND echo "Initializing 'initfs'..."
COMMAND echo "---------------------------------------------"
COMMAND ./initscp/initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev
COMMAND echo "---------------------------------------------"
COMMAND echo "Done!"
COMMAND echo "---------------------------------------------"
DEPENDS initfscp
)
initrd
COMMAND echo "---------------------------------------------"
COMMAND echo "Initializing 'initrd'..."
COMMAND echo "---------------------------------------------"
COMMAND initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initrd -m /dev
COMMAND echo "---------------------------------------------"
COMMAND echo "Done!"
COMMAND echo "---------------------------------------------"
DEPENDS initfscp
DEPENDS all_programs all_tests)
# ------------------------------------------------------------------------------
# =============================================================================
# Update GDB symbol file.
add_custom_target(
gdb_file
COMMAND echo "symbol-file ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin" >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND echo "exec-file ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin" >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel.bin > ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/tests/test_* >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/prog_* >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND echo "break boot.c: boot_main" >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND echo "break kernel.c: kmain" >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND echo "target remote localhost:1234" >> ${CMAKE_BINARY_DIR}/.gdbinit
DEPENDS ${PROJECT_NAME}_bootloader
DEPENDS all_programs all_tests
DEPENDS libc)
# =============================================================================
# Update GDB symbol file.
add_custom_target(
gdb_file_clion_embedded
COMMAND echo "symbol-file ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin" >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND echo "exec-file ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin" >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel.bin > ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin >> ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/prog_* >> ${CMAKE_BINARY_DIR}/.gdbinit
DEPENDS ${PROJECT_NAME}_bootloader
DEPENDS all_programs all_tests
DEPENDS libc)
# =============================================================================
# Set memory size.
SET(MEMORY_SIZE 1096M)
set(MEMORY_SIZE 1096M)
# ------------------------------------------------------------------------------
# =============================================================================
# Builds the code and runs qemu with the built Os.
SET(EMULATOR qemu-system-i386)
if (${DEBUGGING_TYPE} STREQUAL DEBUG_LOG)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial file:serial.log)
elseif (${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial stdio)
endif ()
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
SET(EMULATOR_FS -initrd initfs)
set(EMULATOR qemu-system-i386)
if(${DEBUGGING_TYPE} STREQUAL DEBUG_LOG)
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial file:serial.log)
elseif(${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial stdio)
endif(${DEBUGGING_TYPE} STREQUAL DEBUG_LOG)
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
set(EMULATOR_KERNEL -kernel mentos/kernel-bootloader.bin)
set(EMULATOR_FS -initrd initrd)
add_custom_target(
qemu
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} ${EMULATOR_KERNEL} ${EMULATOR_FS}
DEPENDS MentOs
DEPENDS initfs
)
qemu
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} ${EMULATOR_KERNEL} ${EMULATOR_FS}
DEPENDS kernel-bootloader.bin initrd all_programs all_tests libc)
# ------------------------------------------------------------------------------
# =============================================================================
# Builds the code and runs qemu with the built Os.
SET(EMULATOR_FLAGS_GDB ${EMULATOR_FLAGS} -s -S)
SET(GDB_PROG cgdb)
SET(GDB_ARGS -x ${CMAKE_SOURCE_DIR}/.gdb.debug)
set(EMULATOR_FLAGS_GDB ${EMULATOR_FLAGS} -s -S)
add_custom_target(
qemu-gdb
COMMAND xterm -geometry 160x30-0-0 -e ${EMULATOR} ${EMULATOR_FLAGS_GDB} ${EMULATOR_KERNEL} ${EMULATOR_FS} &
COMMAND xterm -geometry 160x30-0+0 -e ${GDB_PROG} ${GDB_ARGS} &
DEPENDS MentOs
DEPENDS initfs
)
qemu-gdb
COMMAND ${EMULATOR} ${EMULATOR_FLAGS_GDB} ${EMULATOR_KERNEL} ${EMULATOR_FS} &
DEPENDS gdb_file kernel-bootloader.bin initrd)
add_custom_target(all-execs-clion-embedded DEPENDS gdb_file_clion_embedded kernel-bootloader.bin initrd)
+1 -4
View File
@@ -1,7 +1,4 @@
Code Styles for this project
============================
# Coding Style
If you'd like to contribute you are welcome, thus refer to the following coding
styles please:
+95 -134
View File
@@ -1,95 +1,93 @@
MentOS
======
# MentOS
[![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com)
[![forthebadge](https://forthebadge.com/images/badges/made-with-c.svg)](https://forthebadge.com)
[![forthebadge](https://forthebadge.com/images/badges/for-you.svg)](https://forthebadge.com)
What is MentOS
-----------------
## 1. What is MentOS
MentOS (Mentoring Operating system) is an open source educational operating
system.
The goal of MentOS is to provide a project environment that is realistic
enough to show how a real Operating System work, yet simple enough that
students can understand and modify it in significant ways.
MentOS (Mentoring Operating System) is an open source educational operating
system. The goal of MentOS is to provide a project environment that is realistic
enough to show how a real Operating System work, yet simple enough that students
can understand and modify it in significant ways.
There are so many operating systems, why did we write MentOS?
It is true, there are a lot of education operating system, BUT
how many of them follow the guideline de fined by Linux?
There are so many operating systems, why did we write MentOS? It is true, there
are a lot of education operating system, BUT how many of them follow the
guideline de fined by Linux?
MentOS aims to have the same Linux's data structures and algorithms. It has a
well-documented source code, and you can compile it on your laptop in a few
seconds!
MentOS aims to have the same Linux's data structures and algorithms. It
has a well-documented source code, and you can compile it on your laptop
in a few seconds!
If you are a beginner in Operating-System developing, perhaps MentOS is the
right operating system to start with.
Parts of MentOS are inherited or inspired by a similar educational operating
system called [DreamOs](https://github.com/dreamos82/DreamOs) written by Ivan
Gualandri.
Developers
----------------
Main Developers:
## 2. Prerequisites
* [Enrico Fraccaroli](https://github.com/Galfurian)
* [Alessandro Danese](https://github.com/alessandroDanese88)
* [Luigi Capogrosso](https://github.com/luigicapogrosso)
* [Mirco De Marchi](https://github.com/mircodemarchi)
MentOS is compatible with the main **unix-based** operating systems. It has been
tested with *Ubuntu*, *WSL1*, *WSL2*, and *MacOS*.
Prerequisites
-----------------
### 2.1. Generic Prerequisites
MentOS is compatible with the main Unix distribution operating systems. It has been tested with *Ubuntu* and *MacOS*, but specifically tested on *Ubuntu 18.04*.
#### 3.1.1. Compile
For compiling the main system:
For compiling the system:
* nasm
* gcc
* g++
* make
* cmake
* git
- nasm
- gcc
- make
- cmake
- git
- ccmake (suggested)
To run and try:
Under **MacOS**, for compiling, you have additional dependencies:
* qemu-system-i386
- i386-elf-binutils
- i386-elf-gcc
For debugging:
#### 3.1.2. Execute
* ccmake
* cgdb
* xterm
To execute the operating system, you need to install:
For MacOS, you have additional dependencies:
- qemu-system-i386 (or qemu-system-x86)
* i386-elf-binutils (from [i386-elf-toolchain](https://github.com/nativeos/homebrew-i386-elf-toolchain))
* i386-elf-gcc (from [i386-elf-toolchain](https://github.com/nativeos/homebrew-i386-elf-toolchain))
#### 3.1.3. Debug
Prerequisites installation commands
-----------------
For debugging we suggest using:
For Ubuntu:
- cgdb
- xterm
```
### 2.2. installation Prerequisites
Under **Ubuntu**, you can type the following commands:
```bash
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y build-essential git cmake qemu-system-i386
sudo apt-get install -y cgdb xterm #<- for debug only
sudo apt-get install -y cgdb xterm
```
For MacOS:
Under **MacOS** you also need to install the i386-elf cross-compiler. The
simplest installation method is through Homebrew package manager.
Install [Homebrew](https://brew.sh/index_it) if you don't already have it, and
then type the following commands:
You need to install additionally the i386-elf cross-compiler. The simplest installation method is through Homebrew package manager. Install [Homebrew](https://brew.sh/index_it) if you don't already have and exec the following commands:
```
```bash
brew update && brew upgrade
brew tap nativeos/i386-elf-toolchain
brew install i386-elf-binutils i386-elf-gcc git cmake qemu nasm
brew install cgdb xterm #<- for debug only
```
Compiling MentOS
-----------------
Compile and boot MentOS with qemu in Unix systems:
## 3. Compiling MentOS
```
Compile and boot MentOS with qemu:
```bash
cd <clone_directory>
mkdir build
cd build
@@ -98,26 +96,20 @@ make
make qemu
```
If you want to access to the shell, use one of the usernames listed in files/passwd.
To login, use one of the usernames listed in `files/etc/passwd`.
**For MacOS**, the steps are the same but instead of `cmake ..`, you have to put an additional argument in order to use the i386-elf cross-compiler:
```
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..
```
Change the scheduling algorithm
-----------------
## 4. Change the scheduling algorithm
MentOS provides three different scheduling algorithms:
* Round-Robin
* Priority
* Completely Fair Scheduling
- Round-Robin
- Priority
- Completely Fair Scheduling
If you want to change the scheduling algorithm:
```
```bash
cd build
# Round Robin scheduling algorithm
@@ -133,7 +125,7 @@ make qemu
Otherwise you can use `ccmake`:
```
```bash
cd build
cmake ..
ccmake ..
@@ -151,72 +143,20 @@ SCHEDULER_TYPE SCHEDULER_RR
```
Select SCHEDULER_TYPE, and type Enter to scroll the three available algorithms
(SCHEDULER_RR, SCHEDULER_PRIORITY, SCHEDULER_CFS).
Afterwards,
```
type c
type g
(SCHEDULER_RR, SCHEDULER_PRIORITY, SCHEDULER_CFS). Afterwards,
```bash
<press c>
<press g>
make
make qemu
```
Enable to Buddy System
-----------------
## 5. Use Debugger
MentOS provides a Buddy System to manage the allocation and deallocation of
page frames in the physical memory.
If you want to enable the MentOS's Buddy System:
```
cd build
cmake -DENABLE_BUDDY_SYSTEM=ON ..
make
make qemu
```
Otherwise you can use `ccmake`:
```
cd build
cmake ..
ccmake ..
```
Now you should see something like this:
```
BUILD_DOCUMENTATION ON
CMAKE_BUILD_TYPE
CMAKE_INSTALL_PREFIX /usr/local
DEBUGGING_TYPE DEBUG_STDIO
ENABLE_BUDDY_SYSTEM OFF
SCHEDULER_TYPE SCHEDULER_RR
```
Select ENABLE_BUDDY_SYSTEM, and type Enter.
You should see something like this:
```
BUILD_DOCUMENTATION ON
CMAKE_BUILD_TYPE
CMAKE_INSTALL_PREFIX /usr/local
DEBUGGING_TYPE DEBUG_STDIO
ENABLE_BUDDY_SYSTEM ON
SCHEDULER_TYPE SCHEDULER_RR
```
Afterwards,
```
type c
type g
make
make qemu
```
Use Debugger
-----------------
If you want to use GDB to debug MentOS:
```
```bash
cd build
cmake ..
make
@@ -224,8 +164,29 @@ make qemu-gdb
```
If you did everything correctly, you should have 3 windows with:
```
1) - Kernel Booting on qemu
2) - Shell with video printing of statistics previously discussed
3) - Debugger cgdb with code screening
```
1. Kernel Booting on qemu
2. Shell with video printing of statistics previously discussed
3. Debugger cgdb with code screening
## Developers
Main Developers:
* [Enrico Fraccaroli](https://github.com/Galfurian)
- Mr. Wolf
* [Alessandro Danese](https://github.com/alessandroDanese88), [Luigi Capogrosso](https://github.com/luigicapogrosso), [Mirco De Marchi](https://github.com/mircodemarchi)
- Protection ring
- libc
* Andrea Cracco
- Buddy System, Heap, Paging, Slab, Caching, Zone
- Process Image, ELF
- VFS: procfs
- Bootloader
* Linda Sacchetto, Marco Berti
- Real time scheduler
* Daniele Nicoletti, Filippo Ziche
- Real time scheduler (Asynchronous EDF)
- Soft IRQs
- Timer
- Signals
+1
View File
@@ -0,0 +1 @@
# TODOs
-38
View File
@@ -1,38 +0,0 @@
# This is the CMakeCache file.
# For build in directory: /home/enrico/Repositories/University/DreamOs/doc
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
########################
# INTERNAL cache entries
########################
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/enrico/Repositories/University/DreamOs/doc
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=5
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.5
-1
View File
@@ -1 +0,0 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
+37
View File
@@ -0,0 +1,37 @@
# Find Doxygen
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc_doxygen)
set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/html/index.html)
# Replace variables inside @@ with the current values.
set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxygen)
set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxygen)
configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
# Copy the files needd by the documentation.
set(DOXYFILE_CSS ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.css)
set(DOXYFILE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/header.html)
set(DOXYFILE_FOOTER ${CMAKE_CURRENT_SOURCE_DIR}/footer.html)
# Doxygen won't create this for us.
file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
add_custom_command(
OUTPUT ${DOXYGEN_INDEX_FILE}
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
COMMENT "Generating docs"
)
add_custom_target(
Doxygen
DEPENDS
${DOXYGEN_INDEX_FILE}
${DOXYFILE_IN}
${DOXYFILE_CSS}
${DOXYFILE_HEADER}
${DOXYFILE_FOOTER}
)
endif (DOXYGEN_FOUND)
+197 -94
View File
@@ -1,4 +1,4 @@
# Doxyfile 1.8.11
# Doxyfile 1.8.17
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -17,11 +17,11 @@
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
# for the list of possible encodings.
# This tag specifies the encoding used for all characters in the configuration
# file that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
DOXYFILE_ENCODING = UTF-8
@@ -32,19 +32,19 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "MentOS"
PROJECT_NAME = MentOS
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER = 0.3.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF =
PROJECT_BRIEF = "The Mentoring Operating System"
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
@@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY =
OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIR@"
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@@ -152,7 +160,7 @@ FULL_PATH_NAMES = YES
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
@@ -179,6 +187,16 @@ SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
# such as
# /***************
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
# Javadoc-style will behave just like regular comments and it will not be
# interpreted by doxygen.
# The default value is: NO.
JAVADOC_BANNER = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
@@ -226,7 +244,12 @@ TAB_SIZE = 4
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
ALIASES =
@@ -242,7 +265,7 @@ TCL_SUBST =
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
@@ -264,17 +287,26 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
# sources only. Doxygen will then generate output that is more tailored for that
# language. For instance, namespaces will be presented as modules, types will be
# separated into more groups, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_SLICE = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
# .inc files as Fortran files (default is PHP), and .f files as C (default is
# Fortran), use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
@@ -285,7 +317,7 @@ EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@@ -293,6 +325,15 @@ EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 5.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 5
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
@@ -318,7 +359,7 @@ BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.
@@ -424,6 +465,12 @@ EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
# methods of a class will be included in the documentation.
# The default value is: NO.
EXTRACT_PRIV_VIRTUAL = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
# The default value is: NO.
@@ -478,8 +525,8 @@ HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# declarations. If set to NO, these declarations will be included in the
# documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
@@ -502,7 +549,7 @@ INTERNAL_DOCS = NO
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
# (including Cygwin) ands Mac users are advised to set this option to NO.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
@@ -689,7 +736,7 @@ LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
@@ -734,10 +781,11 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation.
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
WARN_NO_PARAMDOC = YES
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
@@ -759,7 +807,7 @@ WARN_FORMAT = "$file:$line: $text"
# messages should be written. If left blank the output is written to standard
# error (stderr).
WARN_LOGFILE = mentos.log
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
@@ -771,12 +819,19 @@ WARN_LOGFILE = mentos.log
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = . ../README.md ../src/mentos
INPUT = @CMAKE_SOURCE_DIR@/README.md \
@CMAKE_SOURCE_DIR@/CODING_STYLE.md \
@CMAKE_SOURCE_DIR@/LICENSE.md \
@CMAKE_SOURCE_DIR@/TODO.md \
@CMAKE_SOURCE_DIR@/doc/signal.md \
@CMAKE_SOURCE_DIR@/doc/syscall.md \
@CMAKE_SOURCE_DIR@/mentos \
@CMAKE_SOURCE_DIR@/libc
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
# possible encodings.
# The default value is: UTF-8.
@@ -793,10 +848,12 @@ INPUT_ENCODING = UTF-8
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS =
FILE_PATTERNS = *.c *.h
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@@ -864,7 +921,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/resources"
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -920,7 +977,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = ../README.md
USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
@@ -933,7 +990,7 @@ USE_MDFILE_AS_MAINPAGE = ../README.md
# also VERBATIM_HEADERS is set to NO.
# The default value is: NO.
SOURCE_BROWSER = NO
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
# classes and enums directly into the documentation.
@@ -949,7 +1006,7 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
# entity all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
@@ -981,12 +1038,12 @@ SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
# (see http://www.gnu.org/software/global/global.html). You will need version
# (see https://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
@@ -1014,7 +1071,7 @@ VERBATIM_HEADERS = YES
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse-libclang=ON option for CMake.
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
@@ -1027,6 +1084,16 @@ CLANG_ASSISTED_PARSING = NO
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the compilation database (see:
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
# were built. This is equivalent to specifying the "-p" option to a clang tool,
# such as clang-check. These options will then be passed to the parser.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@@ -1095,7 +1162,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
HTML_HEADER = "@CMAKE_CURRENT_SOURCE_DIR@/header.html"
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1105,7 +1172,7 @@ HTML_HEADER =
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
HTML_FOOTER = "@CMAKE_CURRENT_SOURCE_DIR@/footer.html"
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1117,7 +1184,7 @@ HTML_FOOTER =
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET =
HTML_STYLESHEET = "@CMAKE_CURRENT_SOURCE_DIR@/doxygen.css"
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
@@ -1145,7 +1212,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
@@ -1181,6 +1248,17 @@ HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have JavaScript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_MENUS = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
@@ -1204,13 +1282,13 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1249,7 +1327,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
@@ -1325,7 +1403,7 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1333,7 +1411,7 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1342,7 +1420,7 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1350,7 +1428,7 @@ QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1358,7 +1436,7 @@ QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
@@ -1451,7 +1529,7 @@ EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
@@ -1462,8 +1540,14 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
FORMULA_MACROFILE =
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering
# https://www.mathjax.org) which uses client side JavaScript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@@ -1490,8 +1574,8 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from http://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
@@ -1533,7 +1617,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
# implemented using a web server instead of a web client using JavaScript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@@ -1552,7 +1636,7 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: http://xapian.org/).
# Xapian (see: https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@@ -1565,7 +1649,7 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: http://xapian.org/). See the section "External Indexing and
# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
@@ -1617,21 +1701,35 @@ LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when enabling USE_PDFLATEX this option is only used for generating
# bitmaps for formulas in the HTML output, but not in the Makefile that is
# written to the output directory.
# The default file is: latex.
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
# chosen this is overwritten by pdflatex. For specific output languages the
# default can have been set differently, this depends on the implementation of
# the output language.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# Note: This tag is used in the Makefile / make.bat.
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
# generate index for LaTeX. In case there is no backslash (\) as first character
# it will be automatically added in the LaTeX code.
# Note: This tag is used in the generated output file (.tex).
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
# The default value is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_MAKEINDEX_CMD = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
@@ -1752,7 +1850,7 @@ LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1766,6 +1864,14 @@ LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
# LATEX_OUTPUT directory will be used.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -1805,9 +1911,9 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
# file, i.e. a series of assignments. You only have to provide replacements,
# missing definitions are set to their default value.
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# configuration file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
@@ -1816,8 +1922,8 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# similar to doxygen's configuration file. A template extensions file can be
# generated using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
@@ -1903,6 +2009,13 @@ XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
# namespace members in file scope as well, matching the HTML output.
# The default value is: NO.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
@@ -1935,9 +2048,9 @@ DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
# AutoGen Definitions (see http://autogen.sf.net) file that captures the
# structure of the code including all documentation. Note that this feature is
# still experimental and incomplete at the moment.
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
# the structure of the code including all documentation. Note that this feature
# is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_AUTOGEN_DEF = NO
@@ -1997,7 +2110,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO
MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -2005,7 +2118,7 @@ MACRO_EXPANSION = NO
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO
EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
@@ -2037,7 +2150,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
PREDEFINED = __attribute__(x)=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2104,12 +2217,6 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
@@ -2123,15 +2230,6 @@ PERL_PATH = /usr/bin/perl
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
@@ -2162,7 +2260,7 @@ HAVE_DOT = YES
# Minimum value: 0, maximum value: 32, default value: 0.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_NUM_THREADS = 0
DOT_NUM_THREADS = 2
# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
@@ -2361,6 +2459,11 @@ DIAFILE_DIRS =
PLANTUML_JAR_PATH =
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
# configuration file for plantuml.
PLANTUML_CFG_FILE =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.
-17
View File
@@ -1,17 +0,0 @@
* * *
### Come usare lo script per generare un'entry di GRUB #
* * *
#### 1. Inserire la partizione dei sorgenti
Questo significa dire al programma in quale partizione si trova la vostra directory dei sorgenti.
Ad esempio se siete su **/dev/hda2**, dovrete inserire **hda2**
#### 2. Inserire il mountpoint
Tale partizione ha un mountpoint (se non lo conoscete, date da shell il comando mount senza argomenti oppure date uno sguardo in **/etc/fstab**). Ad esempio potrà essere **/** o anche **/home/vostroutente** se tenete la home directory in una partizione separata.
#### 3. Attenzione al path
Il path dell'immagine di MentOS sarà calcolato automaticamente, ma per fare questo lo script dev'essere nella stessa directory dell'immagine.
Dopodiché vi basta confermare ed avere la vostra entry nel file **menu.lst**
**ATTENZIONE: Usatelo solo se sapete cosa state facendo. Lo script e' stato testato e funziona, ma non rispondiamo di eventuali blocchi del vostro computer.**
+1604
View File
File diff suppressed because it is too large Load Diff
+2061
View File
File diff suppressed because it is too large Load Diff
+38
View File
@@ -0,0 +1,38 @@
<!-- HTML footer for doxygen 1.8.16-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
</a> $doxygenversion
</li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<div class="footer">
<hr class="footer"/>
<ul class="footer-info">
<li class="footer-info-lastmode">
This page was last modified on $datetime.
</li>
<li class="footer-info-copyright">
MentOs © 20142021 the MentOs team, and numerous contributors.<br>
It is available for use and modification under the&#160;
<a href="$relpath^md_LICENSE.html">MIT License</a>.<br>
</li>
</ul>
<hr class="footer"/>
<address class="footer">
$generatedby&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
</a> $doxygenversion
</address>
</div>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>
+63
View File
@@ -0,0 +1,63 @@
<!-- HTML header for doxygen 1.8.17-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css"/>
$extrastylesheet
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo"
src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span
id="projectnumber">$projectnumber</span>
<!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF-->
<div id="projectbrief">$projectbrief</div>
<!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

+49
View File
@@ -0,0 +1,49 @@
# Signal
## Legenda
The **first column** of the table represent the implementation status,
specifically:
1. Implemented
2. Tested
If the column is empty it means that it's not implemented yet.
## Implementation Status
```
S | Number | Signal | Standard | Action | Comment
---+--------+-----------+----------+--------+------------------------------
| 1 | SIGHUP | P1990 | Term | Hangup detected on controlling terminal or death of controlling process
| 2 | SIGINT | P1990 | Term | Interrupt from keyboard
| 3 | SIGQUIT | P1990 | Core | Quit from keyboard
| 4 | SIGILL | P1990 | Core | Illegal Instruction
| 5 | SIGTRAP | P2001 | Core | Trace/breakpoint trap
2 | 6 | SIGABRT | P1990 | Core | Abort signal from abort(3)
| 7 | SIGEMT | - | Term | Emulator trap
2 | 8 | SIGFPE | P1990 | Core | Floating-point exception
2 | 9 | SIGKILL | P1990 | Term | Kill signal
| 10 | SIGBUS | P2001 | Core | Bus error (bad memory access)
| 11 | SIGSEGV | P1990 | Core | Invalid memory reference
| 12 | SIGSYS | P2001 | Core | Bad system call (SVr4); see also seccomp(2)
| 13 | SIGPIPE | P1990 | Term | Broken pipe: write to pipe with no readers; see pipe(7)
2 | 14 | SIGALRM | P1990 | Term | Timer signal from alarm(2)
2 | 15 | SIGTERM | P1990 | Term | Termination signal
2 | 16 | SIGUSR1 | P1990 | Term | User-defined signal 1
2 | 17 | SIGUSR2 | P1990 | Term | User-defined signal 2
1 | 18 | SIGCHLD | P1990 | Ign | Child stopped or terminated
| 19 | SIGPWR | - | Term | Power failure (System V)
| 20 | SIGWINCH | - | Ign | Window resize signal (4.3BSD, Sun)
| 21 | SIGURG | P2001 | Ign | Urgent condition on socket (4.2BSD)
| 22 | SIGPOLL | P2001 | Term | Pollable event (Sys V); synonym for SIGIO
2 | 23 | SIGSTOP | P1990 | Stop | Stop process
| 24 | SIGTSTP | P1990 | Stop | Stop typed at terminal
2 | 25 | SIGCONT | P1990 | Cont | Continue if stopped
| 26 | SIGTTIN | P1990 | Stop | Terminal input for background process
| 27 | SIGTTOU | P1990 | Stop | Terminal output for background process
| 28 | SIGVTALRM | P2001 | Term | Virtual alarm clock (4.2BSD)
2 | 29 | SIGPROF | P2001 | Term | Profiling timer expired
| 30 | SIGXCPU | P2001 | Core | CPU time limit exceeded (4.2BSD); see setrlimit(2)
| 31 | SIGXFSZ | P2001 | Core | File size limit exceeded (4.2BSD); see setrlimit(2)
```
+207
View File
@@ -0,0 +1,207 @@
# System Call
## Legenda
The **first column** of the table represent the implementation status,
specifically:
1. Implemented
2. Tested
If the column is empty it means that it's not implemented yet.
## Implementation Status
```
S | EAX | Name | Source | EBX | ECX | EDX | ESX | EDI |
---+-----+----------------------------+-----------------------------+--------------------------+------------------------------+-------------------------+-----------------+------------------|
2 | 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
2 | 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
2 | 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - |
2 | 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - |
2 | 5 | sys_open | fs/open.c | const char * | int | int | - | - |
2 | 6 | sys_close | fs/open.c | int | - | - | - | - |
2 | 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
| 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
| 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
2 | 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
2 | 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
2 | 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
2 | 13 | sys_time | kernel/time.c | int * | - | - | - | - |
| 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
| 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
| 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
2 | 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
2 | 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
2 | 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
| 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
| 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
| 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
| 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
| 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
| 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
| 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
2 | 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
| 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
| 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
| 33 | sys_access | fs/open.c | const char * | int | - | - | - |
1 | 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
| 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
1 | 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
| 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
2 | 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
2 | 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
| 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
| 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
| 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
2 | 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
| 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
| 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
1 | 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
| 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
| 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
| 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
| 52 | sys_umount | fs/super.c | char * | int | - | - | - |
1 | 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - |
| 55 | sys_fcntl | fs/fcntl.c | unsigned int | unsigned int | unsigned long | - | - |
| 57 | sys_setpgid | kernel/sys.c | pid_t | pid_t | - | - | - |
| 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
| 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
| 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
| 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
| 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
2 | 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
| 65 | sys_getpgrp | kernel/sys.c | - | - | - | - | - |
| 66 | sys_setsid | kernel/sys.c | - | - | - | - | - |
1 | 67 | sys_sigaction | arch/i386/kernel/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - |
| 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
| 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
| 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
| 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
| 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
| 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
| 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
| 75 | sys_setrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
| 76 | sys_getrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
| 77 | sys_getrusage | kernel/sys.c | int | struct rusage * | - | - | - |
| 78 | sys_gettimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
| 79 | sys_settimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
| 80 | sys_getgroups | kernel/sys.c | int | gid_t * | - | - | - |
| 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
| 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
| 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
| 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
| 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
1 | 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
1 | 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
| 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
| 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
| 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
| 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
| 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
| 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
| 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
| 99 | sys_statfs | fs/open.c | const char * | struct statfs * | - | - | - |
| 100 | sys_fstatfs | fs/open.c | unsigned int | struct statfs * | - | - | - |
| 101 | sys_ioperm | arch/i386/kernel/ioport.c | unsigned long | unsigned long | int | - | - |
| 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
| 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
| 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
| 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
| 106 | sys_newstat | fs/stat.c | char * | struct stat * | - | - | - |
| 107 | sys_newlstat | fs/stat.c | char * | struct stat * | - | - | - |
| 108 | sys_newfstat | fs/stat.c | unsigned int | struct stat * | - | - | - |
1 | 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
| 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
| 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
| 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
| 113 | sys_vm86old | arch/i386/kernel/vm86.c | unsigned long | struct vm86plus_struct * | - | - | - |
| 114 | sys_wait4 | kernel/exit.c | pid_t | unsigned long * | int options | struct rusage * | - |
| 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
| 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
* | 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
| 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
| 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
| 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
| 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
| 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
| 125 | sys_mprotect | mm/mprotect.c | unsigned long | size_t | unsigned long | - | - |
1 | 126 | sys_sigprocmask | kernel/signal.c | int | old_sigset_t * | old_sigset_t * | - | - |
| 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
| 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
| 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
| 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
| 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
| 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
1 | 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
| 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
| 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
| 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
| 138 | sys_setfsuid | kernel/sys.c | uid_t | - | - | - | - |
| 139 | sys_setfsgid | kernel/sys.c | gid_t | - | - | - | - |
| 140 | sys_llseek | fs/read_write.c | unsigned int | unsigned long | unsigned long | loff_t * | unsigned int |
2 | 141 | sys_getdents | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 142 | sys_select | fs/select.c | int | fd_set * | fd_set * | fd_set * | struct timeval * |
| 143 | sys_flock | fs/locks.c | unsigned int | unsigned int | - | - | - |
| 144 | sys_msync | mm/filemap.c | unsigned long | size_t | int | - | - |
| 145 | sys_readv | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
| 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
| 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
| 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
| 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
1 | 154 | sys_sched_setparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
1 | 155 | sys_sched_getparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
| 156 | sys_sched_setscheduler | kernel/sched.c | pid_t | int | struct sched_param * | - | - |
| 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
| 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
| 159 | sys_sched_get_priority_max | kernel/sched.c | int | - | - | - | - |
| 160 | sys_sched_get_priority_min | kernel/sched.c | int | - | - | - | - |
| 161 | sys_sched_rr_get_interval | kernel/sched.c | pid_t | struct timespec * | - | - | - |
| 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
| 163 | sys_mremap | mm/mremap.c | unsigned long | unsigned long | unsigned long | unsigned long | - |
| 164 | sys_setresuid | kernel/sys.c | uid_t | uid_t | uid_t | - | - |
| 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
| 166 | sys_vm86 | arch/i386/kernel/vm86.c | struct vm86_struct * | - | - | - | - |
| 167 | sys_query_module | kernel/module.c | const char * | int | char * | size_t | size_t * |
| 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
| 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
| 170 | sys_setresgid | kernel/sys.c | gid_t | gid_t | gid_t | - | - |
| 171 | sys_getresgid | kernel/sys.c | gid_t * | gid_t * | gid_t * | - | - |
| 172 | sys_prctl | kernel/sys.c | int | unsigned long | unsigned long | unsigned long | unsigned long |
| 173 | sys_rt_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 174 | sys_rt_sigaction | kernel/signal.c | int | const struct sigaction * | struct sigaction * | size_t | - |
| 175 | sys_rt_sigprocmask | kernel/signal.c | int | sigset_t * | sigset_t * | size_t | - |
| 176 | sys_rt_sigpending | kernel/signal.c | sigset_t * | size_t | - | - | - |
| 177 | sys_rt_sigtimedwait | kernel/signal.c | const sigset_t * | siginfo_t * | const struct timespec * | size_t | - |
| 178 | sys_rt_sigqueueinfo | kernel/signal.c | int | int | siginfo_t * | - | - |
| 179 | sys_rt_sigsuspend | arch/i386/kernel/signal.c | sigset_t * | size_t | - | - | - |
| 180 | sys_pread | fs/read_write.c | unsigned int | char * | size_t | loff_t | - |
| 181 | sys_pwrite | fs/read_write.c | unsigned int | const char * | size_t | loff_t | - |
| 182 | sys_chown | fs/open.c | const char * | uid_t | gid_t | - | - |
1 | 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
| 184 | sys_capget | kernel/capability.c | cap_user_header_t | cap_user_data_t | - | - | - |
| 185 | sys_capset | kernel/capability.c | cap_user_header_t | const cap_user_data_t | - | - | - |
| 186 | sys_sigaltstack | arch/i386/kernel/signal.c | const stack_t * | stack_t * | - | - | - |
| 187 | sys_sendfile | mm/filemap.c | int | int | off_t * | size_t | - |
| | | | | | | | |
2 | 188 | sys_waitperiod | kernel/sched.c | | | | | |
| 189 | sys_msgctl | | int | | | | |
| 190 | sys_msgget | | | | | | |
| 191 | sys_msgrcv | | | | | | |
| 192 | sys_msgsnd | | | | | | |
| 193 | sys_semctl | | | | | | |
| 194 | sys_semget | | | | | | |
| 195 | sys_semop | | | | | | |
| 196 | sys_shmat | | | | | | |
| 197 | sys_shmctl | | | | | | |
| 198 | sys_shmdt | | | | | | |
| 199 | sys_shmget | | | | | | |
```
-181
View File
@@ -1,181 +0,0 @@
| EAX | Name | Source | EBX | ECX | EDX | ESX | EDI |
|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------|
| 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
| 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - |
| 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - |
| 5 | sys_open | fs/open.c | const char * | int | int | - | - |
| 6 | sys_close | fs/open.c | unsigned int | - | - | - | - |
| 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
| 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
| 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
| 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
| 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
| 13 | sys_time | kernel/time.c | int * | - | - | - | - |
| 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
| 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
| 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
| 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
| 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
| 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
| 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
| 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
| 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
| 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
| 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
| 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
| 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
| 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
| 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
| 33 | sys_access | fs/open.c | const char * | int | - | - | - |
| 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
| 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
| 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
| 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
| 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
| 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
| 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
| 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
| 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
| 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
| 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
| 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
| 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
| 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
| 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
| 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
| 52 | sys_umount | fs/super.c | char * | int | - | - | - |
| 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - |
| 55 | sys_fcntl | fs/fcntl.c | unsigned int | unsigned int | unsigned long | - | - |
| 57 | sys_setpgid | kernel/sys.c | pid_t | pid_t | - | - | - |
| 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
| 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
| 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
| 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
| 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
| 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
| 65 | sys_getpgrp | kernel/sys.c | - | - | - | - | - |
| 66 | sys_setsid | kernel/sys.c | - | - | - | - | - |
| 67 | sys_sigaction | arch/i386/kernel/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - |
| 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
| 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
| 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
| 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
| 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
| 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
| 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
| 75 | sys_setrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
| 76 | sys_getrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
| 77 | sys_getrusage | kernel/sys.c | int | struct rusage * | - | - | - |
| 78 | sys_gettimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
| 79 | sys_settimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
| 80 | sys_getgroups | kernel/sys.c | int | gid_t * | - | - | - |
| 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
| 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
| 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
| 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
| 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
| 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
| 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
| 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
| 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
| 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
| 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
| 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
| 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
| 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
| 99 | sys_statfs | fs/open.c | const char * | struct statfs * | - | - | - |
| 100 | sys_fstatfs | fs/open.c | unsigned int | struct statfs * | - | - | - |
| 101 | sys_ioperm | arch/i386/kernel/ioport.c | unsigned long | unsigned long | int | - | - |
| 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
| 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
| 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
| 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
| 106 | sys_newstat | fs/stat.c | char * | struct stat * | - | - | - |
| 107 | sys_newlstat | fs/stat.c | char * | struct stat * | - | - | - |
| 108 | sys_newfstat | fs/stat.c | unsigned int | struct stat * | - | - | - |
| 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
| 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
| 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
| 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
| 113 | sys_vm86old | arch/i386/kernel/vm86.c | unsigned long | struct vm86plus_struct * | - | - | - |
| 114 | sys_wait4 | kernel/exit.c | pid_t | unsigned long * | int options | struct rusage * | - |
| 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
| 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
| 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
| 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
| 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
| 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
| 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
| 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
| 125 | sys_mprotect | mm/mprotect.c | unsigned long | size_t | unsigned long | - | - |
| 126 | sys_sigprocmask | kernel/signal.c | int | old_sigset_t * | old_sigset_t * | - | - |
| 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
| 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
| 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
| 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
| 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
| 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
| 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
| 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
| 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
| 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
| 138 | sys_setfsuid | kernel/sys.c | uid_t | - | - | - | - |
| 139 | sys_setfsgid | kernel/sys.c | gid_t | - | - | - | - |
| 140 | sys_llseek | fs/read_write.c | unsigned int | unsigned long | unsigned long | loff_t * | unsigned int |
| 141 | sys_getdents | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 142 | sys_select | fs/select.c | int | fd_set * | fd_set * | fd_set * | struct timeval * |
| 143 | sys_flock | fs/locks.c | unsigned int | unsigned int | - | - | - |
| 144 | sys_msync | mm/filemap.c | unsigned long | size_t | int | - | - |
| 145 | sys_readv | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
| 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
| 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
| 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
| 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
| 154 | sys_sched_setparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
| 155 | sys_sched_getparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
| 156 | sys_sched_setscheduler | kernel/sched.c | pid_t | int | struct sched_param * | - | - |
| 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
| 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
| 159 | sys_sched_get_priority_max | kernel/sched.c | int | - | - | - | - |
| 160 | sys_sched_get_priority_min | kernel/sched.c | int | - | - | - | - |
| 161 | sys_sched_rr_get_interval | kernel/sched.c | pid_t | struct timespec * | - | - | - |
| 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
| 163 | sys_mremap | mm/mremap.c | unsigned long | unsigned long | unsigned long | unsigned long | - |
| 164 | sys_setresuid | kernel/sys.c | uid_t | uid_t | uid_t | - | - |
| 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
| 166 | sys_vm86 | arch/i386/kernel/vm86.c | struct vm86_struct * | - | - | - | - |
| 167 | sys_query_module | kernel/module.c | const char * | int | char * | size_t | size_t * |
| 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
| 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
| 170 | sys_setresgid | kernel/sys.c | gid_t | gid_t | gid_t | - | - |
| 171 | sys_getresgid | kernel/sys.c | gid_t * | gid_t * | gid_t * | - | - |
| 172 | sys_prctl | kernel/sys.c | int | unsigned long | unsigned long | unsigned long | unsigned long |
| 173 | sys_rt_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 174 | sys_rt_sigaction | kernel/signal.c | int | const struct sigaction * | struct sigaction * | size_t | - |
| 175 | sys_rt_sigprocmask | kernel/signal.c | int | sigset_t * | sigset_t * | size_t | - |
| 176 | sys_rt_sigpending | kernel/signal.c | sigset_t * | size_t | - | - | - |
| 177 | sys_rt_sigtimedwait | kernel/signal.c | const sigset_t * | siginfo_t * | const struct timespec * | size_t | - |
| 178 | sys_rt_sigqueueinfo | kernel/signal.c | int | int | siginfo_t * | - | - |
| 179 | sys_rt_sigsuspend | arch/i386/kernel/signal.c | sigset_t * | size_t | - | - | - |
| 180 | sys_pread | fs/read_write.c | unsigned int | char * | size_t | loff_t | - |
| 181 | sys_pwrite | fs/read_write.c | unsigned int | const char * | size_t | loff_t | - |
| 182 | sys_chown | fs/open.c | const char * | uid_t | gid_t | - | - |
| 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
| 184 | sys_capget | kernel/capability.c | cap_user_header_t | cap_user_data_t | - | - | - |
| 185 | sys_capset | kernel/capability.c | cap_user_header_t | const cap_user_data_t | - | - | - |
| 186 | sys_sigaltstack | arch/i386/kernel/signal.c | const stack_t * | stack_t * | - | - | - |
| 187 | sys_sendfile | mm/filemap.c | int | int | off_t * | size_t | - |
| 190 | sys_vfork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| | | | | | | | |
+2
View File
@@ -0,0 +1,2 @@
root:x:0:user,root,marco
user:x:1000:banana,marco
+1
View File
@@ -0,0 +1 @@
avalon
+2
View File
@@ -0,0 +1,2 @@
root:root:0:0:Root User:/:/bin/shell
user:user:1000:1000:Normal User:/home/user:/bin/shell
-3
View File
@@ -1,3 +0,0 @@
root:password
user:computer
asd:asd
-28
View File
@@ -1,28 +0,0 @@
#include <stdio.h>
#include <fcntl.h>
void main(int argc, char ** argv)
{
if (argc == 2)
{
// Try to open the file.
int fd = open(argv[1], O_RDONLY, 42);
if (fd > -1)
{
char c;
// Put on the standard output the characters.
while (read(fd, &c, 1)) putchar(c);
putchar('\n');
putchar('\n');
close(fd);
}
else
{
printf("%s: cannot find the file.\n\n", argv[1]);
}
}
else
{
printf("Usage: more file\n\n");
}
}
+2
View File
@@ -1 +1,3 @@
come va ?
AAA
+1 -5
View File
@@ -1,6 +1,6 @@
# ------------------------------------------------------------------------------
# Initialize the project.
project(initfscp C ASM)
project(initfscp C)
# ------------------------------------------------------------------------------
# Set the project name.
@@ -19,10 +19,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
# ------------------------------------------------------------------------------
# Add the includes.
include_directories(inc)
# ------------------------------------------------------------------------------
# Add the source files.
set(SOURCE_FILES src/initfscp.c)
-42
View File
@@ -1,42 +0,0 @@
/// @file initfscp.h
/// @brief
#pragma once
#define MAX_FILENAME_LENGTH 64
#define MAX_FILES 32
#define INITFSCP_VER "0.3.0"
#define FS_FILE 0x01 ///< Identifies a file.
#define FS_DIRECTORY 0x02 ///< Identifies a directory.
#define FS_CHARDEVICE 0x04 ///< Identifies a character devies.
#define FS_BLOCKDEVICE 0x08 ///< Identifies a block devies.
#define FS_PIPE 0x10 ///< Identifies a pipe.
#define FS_SYMLINK 0x20 ///< Identifies a symbolic link.
#define FS_MOUNTPOINT 0x40 ///< Identifies a mount-point.
#define RESET "\033[00m"
#define BLACK "\033[30m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN "\033[36m"
#define WHITE "\033[37m"
/// @brief Information concerning a file.
typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF.
int magic;
/// The name of the file.
char fileName[MAX_FILENAME_LENGTH];
/// The type of the file.
short int file_type;
/// The uid of the owner.
int uid;
/// Offset of the starting address.
unsigned int offset;
/// Dimension of the file.
unsigned int length;
} initrd_file_t;
+352 -272
View File
@@ -4,321 +4,401 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <initfscp.h>
#include <stdbool.h>
#include <stdint.h>
#include <libgen.h>
#include <dirent.h>
#include <assert.h>
#include <time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
static FILE *target_fs = NULL;
static initrd_file_t headers[MAX_FILES];
static char mount_points[MAX_FILES][MAX_FILENAME_LENGTH];
static int mountpoint_idx = 0;
static int header_idx = 0;
static int header_offset = 0;
#define INITFSCP_VER "0.3.0"
#define INITRD_NAME_MAX 255
#define INITRD_MAX_FILES 128
#define INITRD_MAX_FS_SIZE 1048576
#define RESET "\033[00m"
#define BLACK "\033[30m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN "\033[36m"
#define WHITE "\033[37m"
static const char dt_char_array[] = {
'?', // DT_UNKNOWN = 0,
'p', //DT_FIFO = 1,
'c', //DT_CHR = 2,
'*',
'd', //DT_DIR = 4,
'*',
'b', //DT_BLK = 6,
'*',
'-', //DT_REG = 8,
'*',
'l', //DT_LNK = 10,
'*',
's', //DT_SOCK = 12,
'*',
'?', //DT_WHT = 14
};
/// @brief Information concerning a file.
typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF.
int magic;
/// The inode of the file.
unsigned int inode;
/// The name of the file.
char name[INITRD_NAME_MAX];
/// The type of the file.
short int file_type;
/// The permissions mask.
unsigned int mask;
/// The id of the owner.
unsigned int uid;
/// The id of the group.
unsigned int gid;
/// Time of last access.
unsigned int atime;
/// Time of last data modification.
unsigned int mtime;
/// Time of last status change.
unsigned int ctime;
/// Offset of the starting address.
unsigned int offset;
/// Dimension of the file.
unsigned int length;
} __attribute__((aligned(16))) initrd_file_t;
/// @brief The details regarding the filesystem.
/// @brief Contains the number of files inside the initrd filesystem.
typedef struct initrd_t {
/// Number of files.
unsigned int nfiles;
/// List of headers.
initrd_file_t headers[INITRD_MAX_FILES];
} __attribute__((aligned(16))) initrd_t;
// Prepare a variable to keep track of the offsets inside the FS. By
// default skip the initial space for the FS details structure.
static int fs_offset = sizeof(initrd_t);
static inline void usage(char *prgname)
{
printf("Usage:\n");
printf(" %s --help For this screen\n", prgname);
printf(" %s --source [-s] The source directory.\n", prgname);
printf(" %s --target [-t] The target file for the initfs.\n", prgname);
printf("Usage:\n");
printf(" %s --help For this screen\n", prgname);
printf(" %s --source [-s] The source directory.\n", prgname);
printf(" %s --target [-t] The target file for the initrd.\n", prgname);
}
static inline void version(char *prgname)
{
printf("%s version: %s\n", prgname, INITFSCP_VER);
printf("%s version: %s\n", prgname, INITFSCP_VER);
}
static inline bool is_option_mount_point(char *arg)
static inline int is_option_mount_point(char *arg)
{
if (arg == NULL)
return false;
return ((strcmp(arg, "-m") == 0) || (strcmp(arg, "--mountpoint") == 0));
return ((strcmp(arg, "-m") == 0) || (strcmp(arg, "--mountpoint") == 0));
}
static inline bool is_option_source(char *arg)
static inline int is_option_source(char *arg)
{
if (arg == NULL)
return false;
return ((strcmp(arg, "-s") == 0) || (strcmp(arg, "--source") == 0));
return ((strcmp(arg, "-s") == 0) || (strcmp(arg, "--source") == 0));
}
static inline bool is_option_target(char *arg)
static inline int is_option_target(char *arg)
{
if (arg == NULL)
return false;
return ((strcmp(arg, "-t") == 0) || (strcmp(arg, "--target") == 0));
return ((strcmp(arg, "-t") == 0) || (strcmp(arg, "--target") == 0));
}
static inline bool is_mount_point(char *name)
static int open_target_fs(int argc, char *argv[])
{
if (name == NULL)
return false;
// Check if the name matches with a mount-point.
for (int i = 0; i < mountpoint_idx; ++i) {
if (strcmp(name, mount_points[i]) == 0) {
return true;
}
}
return false;
printf("%-64s", "Opening target filesystem...");
int fd = -1;
for (int i = 1; i < argc; ++i) {
if (is_option_target(argv[i]) && ((i + 1) < argc)) {
fd = open(argv[i + 1], O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
break;
}
}
if (fd == -1)
printf("[" RED "FAILED" RESET "]\n\n");
else
printf("[" GREEN "DONE" RESET "]\n\n");
return fd;
}
static FILE *openfile(const char *dirname, struct dirent *dir, const char *mode)
static void init_headers(initrd_t *initrd)
{
char pathname[1024];
FILE *fp;
sprintf(pathname, "%s/%s", dirname, dir->d_name);
fp = fopen(pathname, mode);
return fp;
printf("%-64s", "Initializing headers structures...");
for (size_t i = 0; i < INITRD_MAX_FILES; i++) {
initrd->headers[i].magic = 0xBF;
initrd->headers[i].inode = i;
initrd->headers[i].file_type = 0;
initrd->headers[i].mask = 0;
initrd->headers[i].uid = 0;
initrd->headers[i].gid = 0;
initrd->headers[i].atime = time(NULL);
initrd->headers[i].mtime = time(NULL);
initrd->headers[i].ctime = time(NULL);
initrd->headers[i].offset = 0;
initrd->headers[i].length = 0;
memset(initrd->headers[i].name, 0, INITRD_NAME_MAX);
}
printf("[" GREEN "DONE" RESET "]\n\n");
}
static bool open_target_fs(int argc, char *argv[])
static int create_file_headers(initrd_t *initrd, char *mountpoint, char *directory)
{
printf("%-64s", "Opening target filesystem...");
for (int i = 1; i < argc; ++i) {
if (is_option_target(argv[i]) && ((i + 1) < argc)) {
target_fs = fopen(argv[i + 1], "w");
printf("[" GREEN "DONE" RESET "]\n\n");
return true;
}
}
printf("[" RED "FAILED" RESET "]\n\n");
return false;
assert(mountpoint && "Received null mountpoint.");
assert(directory && "Received null directory.");
// ------------------------------------------------------------------------
char directory_path_abs[PATH_MAX], entry_path_abs[PATH_MAX], fs_abs_path[PATH_MAX];
memset(directory_path_abs, 0, PATH_MAX);
memset(entry_path_abs, 0, PATH_MAX);
memset(fs_abs_path, 0, PATH_MAX);
strcpy(directory_path_abs, mountpoint);
strcat(directory_path_abs, directory);
int dir_fd = open(directory_path_abs, O_RDONLY);
if (dir_fd == -1) {
printf("[" RED "FAILED" RESET "]\n");
printf("Could not open source directory %s.\n", directory_path_abs);
return 0;
}
// ------------------------------------------------------------------------
char buffer[BUFSIZ], *ebuf;
off_t basep;
int nbytes;
while ((nbytes = getdirentries(dir_fd, buffer, BUFSIZ, &basep)) > 0) {
ebuf = buffer + nbytes;
char *cp = buffer;
while (cp < ebuf) {
struct dirent *entry = (struct dirent *)cp;
if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
cp += entry->d_reclen;
continue;
}
// Create the host machine absolute path.
strcpy(entry_path_abs, directory_path_abs);
strcat(entry_path_abs, "/");
strcat(entry_path_abs, entry->d_name);
// Create the filesystem absolute path.
strcpy(fs_abs_path, directory);
strcat(fs_abs_path, "/");
strcat(fs_abs_path, entry->d_name);
// Print the entry.
printf("[%3d] ENTRY: %-52s", initrd->nfiles, fs_abs_path);
// Stat the file.
struct stat _stat;
if (stat(entry_path_abs, &_stat) == -1) {
printf("[" RED "FAILED" RESET "]\n");
printf("Error while executing stat on file : %s\n", entry_path_abs);
return 0;
}
printf("[%c%c%c%c%c%c%c%c%c%c]",
dt_char_array[entry->d_type],
(_stat.st_mode & S_IRUSR) != 0 ? 'r' : '-',
(_stat.st_mode & S_IWUSR) != 0 ? 'w' : '-',
(_stat.st_mode & S_IXUSR) != 0 ? 'x' : '-',
(_stat.st_mode & S_IRGRP) != 0 ? 'r' : '-',
(_stat.st_mode & S_IWGRP) != 0 ? 'w' : '-',
(_stat.st_mode & S_IXGRP) != 0 ? 'x' : '-',
(_stat.st_mode & S_IROTH) != 0 ? 'r' : '-',
(_stat.st_mode & S_IWOTH) != 0 ? 'w' : '-',
(_stat.st_mode & S_IXOTH) != 0 ? 'x' : '-');
if (entry->d_type != DT_DIR) {
// ----------------------------------------------------------------
// Copy the name and the main info.
strcpy(initrd->headers[initrd->nfiles].name, fs_abs_path);
initrd->headers[initrd->nfiles].file_type = DT_REG;
initrd->headers[initrd->nfiles].length = _stat.st_size;
initrd->headers[initrd->nfiles].offset = fs_offset;
initrd->headers[initrd->nfiles].mask = _stat.st_mode;
initrd->headers[initrd->nfiles].uid = _stat.st_uid;
initrd->headers[initrd->nfiles].gid = _stat.st_gid;
initrd->headers[initrd->nfiles].atime = _stat.st_atim.tv_sec;
initrd->headers[initrd->nfiles].mtime = _stat.st_mtim.tv_sec;
initrd->headers[initrd->nfiles].ctime = _stat.st_ctim.tv_sec;
// ----------------------------------------------------------------
printf("[OFFSET:%6d]", initrd->headers[initrd->nfiles].offset);
printf("[SIZE:%6d]", initrd->headers[initrd->nfiles].length);
printf("[" GREEN "DONE" RESET "]\n");
fs_offset += initrd->headers[initrd->nfiles].length;
++initrd->nfiles;
} else {
// ----------------------------------------------------------------
strcpy(initrd->headers[initrd->nfiles].name, fs_abs_path);
initrd->headers[initrd->nfiles].file_type = DT_DIR;
initrd->headers[initrd->nfiles].length = _stat.st_size;
initrd->headers[initrd->nfiles].offset = fs_offset;
initrd->headers[initrd->nfiles].mask = _stat.st_mode;
initrd->headers[initrd->nfiles].uid = _stat.st_uid;
initrd->headers[initrd->nfiles].gid = _stat.st_gid;
initrd->headers[initrd->nfiles].atime = _stat.st_atim.tv_sec;
initrd->headers[initrd->nfiles].mtime = _stat.st_mtim.tv_sec;
initrd->headers[initrd->nfiles].ctime = _stat.st_ctim.tv_sec;
// ----------------------------------------------------------------
printf("[OFFSET:%6d]", initrd->headers[initrd->nfiles].offset);
printf("[SIZE:%6d]", initrd->headers[initrd->nfiles].length);
printf("[" GREEN "DONE" RESET "]\n");
// ----------------------------------------------------------------
++initrd->nfiles;
// ----------------------------------------------------------------
if (!create_file_headers(initrd, mountpoint, fs_abs_path)) {
break;
}
}
cp += entry->d_reclen;
}
}
close(dir_fd);
return 1;
}
static bool init_headers()
static int write_file_system(initrd_t *initrd, int target_fd, char *mountpoint)
{
printf("%-64s", "Initializing headers structures...");
for (size_t i = 0; i < MAX_FILES; i++) {
headers[i].magic = 0xBF;
memset(headers[i].fileName, 0, MAX_FILENAME_LENGTH);
headers[i].file_type = 0;
headers[i].uid = 0;
headers[i].offset = 0;
headers[i].length = 0;
}
printf("[" GREEN "DONE" RESET "]\n\n");
return true;
}
printf("Copying data to filesystem...\n");
for (int i = 0; i < INITRD_MAX_FILES; i++) {
// --------------------------------------------------------------------
char absolute_path[256];
memset(absolute_path, 0, 256);
strcpy(absolute_path, mountpoint);
strcat(absolute_path, initrd->headers[i].name);
static bool init_mount_points(int argc, char *argv[])
{
printf("Initializing mount points...\n");
for (int i = 1; i < argc; ++i) {
if (is_option_mount_point(argv[i]) && ((i + 1) < argc)) {
strcpy(mount_points[mountpoint_idx], argv[i + 1]);
printf("[%3d] MPNT: %-52s", mountpoint_idx,
mount_points[mountpoint_idx]);
printf("[" CYAN "DONE" RESET "]\n");
++mountpoint_idx;
}
}
printf("[" GREEN "DONE" RESET "]\n\n");
return true;
}
// --------------------------------------------------------------------
if (initrd->headers[i].file_type == DT_REG) {
FILE *fd2 = fopen(absolute_path, "r+");
if (fd2 == NULL) {
continue;
}
printf("[%3d] FILE: %-92s", i, absolute_path);
char *buffer = (char *)malloc(initrd->headers[i].length);
fread(buffer, 1, initrd->headers[i].length, fd2);
// Write the content.
write(target_fd, buffer, initrd->headers[i].length);
static bool create_file_headers(char *mountpoint, char *directory)
{
assert(mountpoint && "Received null mountpoint.");
assert(directory && "Received null directory.");
// ------------------------------------------------------------------------
char absolute_path[256];
memset(absolute_path, 0, 256);
strcpy(absolute_path, mountpoint);
strcat(absolute_path, directory);
// ------------------------------------------------------------------------
DIR *source_dir = opendir(absolute_path);
if (source_dir == NULL) {
printf("[" RED "FAILED" RESET "]\n");
printf("Could not open source directory %s.\n", absolute_path);
return false;
}
struct dirent *entry;
while ((entry = readdir(source_dir)) != NULL) {
if ((strcmp(entry->d_name, ".") == 0) ||
(strcmp(entry->d_name, "..") == 0)) {
continue;
}
if (entry->d_type != DT_DIR) {
char relative_filename[256];
strcpy(relative_filename, directory);
strcat(relative_filename, "/");
strcat(relative_filename, entry->d_name);
// ----------------------------------------------------------------
FILE *fd = openfile(absolute_path, entry, "r+");
printf("[%3d] FILE: %-52s", header_idx, relative_filename);
if (fd == NULL) {
printf("[" RED "FAILED" RESET "]\n");
printf("Error while opening file : %s\n", relative_filename);
}
fseek(fd, 0, SEEK_END);
long length = ftell(fd);
fclose(fd);
// ----------------------------------------------------------------
strcpy(headers[header_idx].fileName, relative_filename);
headers[header_idx].file_type = FS_FILE;
headers[header_idx].length = length;
headers[header_idx].offset = header_offset;
// ----------------------------------------------------------------
printf("[" BLUE "OPEN" RESET "]");
printf("[OFFSET:%6d]", headers[header_idx].offset);
printf("[SIZE:%6d]", headers[header_idx].length);
printf("[" GREEN "DONE" RESET "]\n");
header_offset += headers[header_idx].length;
++header_idx;
} else {
// ----------------------------------------------------------------
char sub_directory[256];
memset(sub_directory, 0, 256);
strcpy(sub_directory, directory);
strcat(sub_directory, "/");
strcat(sub_directory, entry->d_name);
// ----------------------------------------------------------------
strcpy(headers[header_idx].fileName, sub_directory);
headers[header_idx].file_type = FS_DIRECTORY;
headers[header_idx].length = 0;
headers[header_idx].offset = 0 /*++header_offset*/;
// ----------------------------------------------------------------
// Check if the directory is a mountpoint.
if (is_mount_point(headers[header_idx].fileName)) {
headers[header_idx].file_type = FS_MOUNTPOINT;
}
// ----------------------------------------------------------------
printf("[%3d] %3s : %-52s", header_idx,
(headers[header_idx].file_type == FS_DIRECTORY) ? "DIR" :
"MPT",
sub_directory);
printf("[" BLUE "OPEN" RESET "]");
printf("[OFFSET:%6d]", headers[header_idx].offset);
printf("[SIZE:%6d]", headers[header_idx].length);
printf("[" GREEN "DONE" RESET "]\n");
// ----------------------------------------------------------------
++header_idx;
// ----------------------------------------------------------------
create_file_headers(mountpoint, sub_directory);
}
}
closedir(source_dir);
return true;
}
static bool write_file_system(char *mountpoint)
{
printf("Copying data to filesystem...\n");
for (int i = 0; i < MAX_FILES; i++) {
// --------------------------------------------------------------------
char absolute_path[256];
memset(absolute_path, 0, 256);
strcpy(absolute_path, mountpoint);
strcat(absolute_path, headers[i].fileName);
// --------------------------------------------------------------------
if (headers[i].file_type == FS_FILE) {
FILE *fd2 = fopen(absolute_path, "r+");
if (fd2 == NULL) {
continue;
}
printf("[%3d] FILE: %-92s", i, absolute_path);
char *buffer = (char *)malloc(headers[i].length);
fread(buffer, 1, headers[i].length, fd2);
fwrite(buffer, 1, headers[i].length, target_fs);
printf("[" GREEN "DONE" RESET "]\n");
fclose(fd2);
free(buffer);
}
}
printf("[" GREEN "DONE" RESET "]\n\n");
return true;
printf("[" GREEN "DONE" RESET "]\n");
fclose(fd2);
free(buffer);
}
}
printf("[" GREEN "DONE" RESET "]\n\n");
return 1;
}
int main(int argc, char *argv[])
{
printf("Welcome to MentOS initfs file copier tool\n\n");
if (argc <= 1) {
if (argv[0][0] == '.') {
version(argv[0] + 2);
}
usage(argv[0]);
return EXIT_FAILURE;
}
if (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-v")) {
version(argv[0] + 2);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
usage(argv[0]);
return EXIT_SUCCESS;
}
printf("Welcome to MentOS initrd file copier tool\n\n");
if (argc <= 1) {
if (argv[0][0] == '.') {
version(argv[0] + 2);
}
usage(argv[0]);
return EXIT_FAILURE;
}
if (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-v")) {
version(argv[0] + 2);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
usage(argv[0]);
return EXIT_SUCCESS;
}
// ------------------------------------------------------------------------
// Open the fs.
if (!open_target_fs(argc, argv)) {
printf("Could not open target FileSystem.\n");
return EXIT_FAILURE;
}
// Create the filesystem details structure.
initrd_t initrd;
// Target fs file descriptor.
int target_fd;
// ------------------------------------------------------------------------
// Initialize the headers.
if (!init_headers()) {
printf("Could not initialize headers.\n");
fclose(target_fs);
return EXIT_FAILURE;
}
// ------------------------------------------------------------------------
// Open the fs.
if ((target_fd = open_target_fs(argc, argv)) == -1) {
printf("Could not open target FileSystem.\n");
return EXIT_FAILURE;
}
// ------------------------------------------------------------------------
// Initialize the mountpoints.
if (!init_mount_points(argc, argv)) {
printf("Could not initialize mount points.\n");
fclose(target_fs);
return EXIT_FAILURE;
}
// ------------------------------------------------------------------------
// Initialize the headers.
init_headers(&initrd);
// ------------------------------------------------------------------------
// Create file headers.
header_offset = sizeof(struct initrd_file_t) * MAX_FILES + sizeof(int);
printf("Creating headers...\n");
for (uint32_t i = 1; i < argc; ++i) {
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
if (!create_file_headers(argv[i + 1], "")) {
printf("Could not create file headers.\n");
fclose(target_fs);
return EXIT_FAILURE;
}
}
}
printf("[" GREEN "DONE" RESET "]\n\n");
// ------------------------------------------------------------------------
// Create file headers.
printf("Creating headers...\n");
for (unsigned int i = 1; i < argc; ++i) {
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
// ----------------------------------------------------------------
strcpy(initrd.headers[initrd.nfiles].name, "/");
initrd.headers[initrd.nfiles].file_type = DT_DIR;
initrd.headers[initrd.nfiles].length = 0;
initrd.headers[initrd.nfiles].offset = fs_offset;
initrd.headers[initrd.nfiles].mask = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
initrd.headers[initrd.nfiles].uid = 0;
initrd.headers[initrd.nfiles].gid = 0;
initrd.headers[initrd.nfiles].atime = time(NULL);
initrd.headers[initrd.nfiles].mtime = time(NULL);
initrd.headers[initrd.nfiles].ctime = time(NULL);
// ------------------------------------------------------------------------
// Copying information about headers on filesystem.
printf("%-64s", "Copying information about headers to filesystem...");
fwrite(&header_idx, sizeof(int), 1, target_fs);
fwrite(headers, sizeof(struct initrd_file_t), 32, target_fs);
printf("[" GREEN "DONE" RESET "]\n\n");
printf("[%3d] DIR : %-52s", initrd.nfiles, initrd.headers[initrd.nfiles].name);
printf("[" BLUE "OPEN" RESET "]");
printf("[OFFSET:%6d]", initrd.headers[initrd.nfiles].offset);
printf("[SIZE:%6d]", initrd.headers[initrd.nfiles].length);
printf("[" GREEN "DONE" RESET "]\n");
++initrd.nfiles;
// ------------------------------------------------------------------------
// Write headers on filesystem.
for (uint32_t i = 1; i < argc; ++i) {
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
if (!write_file_system(argv[i + 1])) {
printf("Could not write on filesystem.\n");
fclose(target_fs);
return EXIT_FAILURE;
}
}
}
fclose(target_fs);
return 0;
// ----------------------------------------------------------------
if (!create_file_headers(&initrd, argv[i + 1], "")) {
printf("Could not create file headers.\n");
close(target_fd);
return EXIT_FAILURE;
}
}
}
printf("[" GREEN "DONE" RESET "]\n\n");
// ------------------------------------------------------------------------
// Copying information about headers on filesystem.
printf("%-64s", "Copying the filesystem's details structure...");
write(target_fd, &initrd, sizeof(initrd_t));
printf("[" GREEN "DONE" RESET "]\n\n");
// ------------------------------------------------------------------------
// Write headers on filesystem.
for (unsigned int i = 1; i < argc; ++i) {
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
if (!write_file_system(&initrd, target_fd, argv[i + 1])) {
printf("Could not write on filesystem.\n");
close(target_fd);
return EXIT_FAILURE;
}
}
}
// ------------------------------------------------------------------------
lseek(target_fd, 0L, SEEK_SET);
size_t fs_size = lseek(target_fd, 0L, SEEK_END);
printf("FS size : %ld\n", fs_size);
if (fs_size < INITRD_MAX_FS_SIZE - 1) {
printf("Extend FS size to : %d\n", INITRD_MAX_FS_SIZE - 1);
lseek(target_fd, INITRD_MAX_FS_SIZE - 1, SEEK_SET);
write(target_fd, 0, 1);
}
close(target_fd);
return 0;
}
+140
View File
@@ -0,0 +1,140 @@
# =============================================================================
# Author: Enrico Fraccaroli
# =============================================================================
# Set the minimum required version of cmake.
cmake_minimum_required(VERSION 2.8)
# Initialize the project.
project(libc C ASM)
# =============================================================================
# Set the default build type to Debug.
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE
"Debug"
CACHE STRING "Choose the type of build." FORCE)
endif()
# =============================================================================
# Enable the assembly language.
enable_language(ASM)
# Find the NASM compiler.
find_program(ASM_COMPILER
NAMES nasm
HINTS /usr/bin/ ${CMAKE_SOURCE_DIR}/third_party/nasm/bin
)
# Check that we have found the compiler.
if(NOT ASM_COMPILER)
message(FATAL_ERROR "ASM compiler not found!")
endif(NOT ASM_COMPILER)
# Set the asm compiler.
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
# Set the assembly compiler flags.
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O3")
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
# =============================================================================
# Warning flags.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
# Set the C compiler options.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
# =============================================================================
# Add the library.
add_library(
${PROJECT_NAME}
${PROJECT_SOURCE_DIR}/src/stdio.c
${PROJECT_SOURCE_DIR}/src/ctype.c
${PROJECT_SOURCE_DIR}/src/string.c
${PROJECT_SOURCE_DIR}/src/stdlib.c
${PROJECT_SOURCE_DIR}/src/math.c
${PROJECT_SOURCE_DIR}/src/fcvt.c
${PROJECT_SOURCE_DIR}/src/time.c
${PROJECT_SOURCE_DIR}/src/strerror.c
${PROJECT_SOURCE_DIR}/src/termios.c
${PROJECT_SOURCE_DIR}/src/libgen.c
${PROJECT_SOURCE_DIR}/src/vsprintf.c
${PROJECT_SOURCE_DIR}/src/vscanf.c
${PROJECT_SOURCE_DIR}/src/pwd.c
${PROJECT_SOURCE_DIR}/src/grp.c
${PROJECT_SOURCE_DIR}/src/sched.c
${PROJECT_SOURCE_DIR}/src/setenv.c
${PROJECT_SOURCE_DIR}/src/assert.c
${PROJECT_SOURCE_DIR}/src/abort.c
${PROJECT_SOURCE_DIR}/src/io/mm_io.c
${PROJECT_SOURCE_DIR}/src/io/port_io.c
${PROJECT_SOURCE_DIR}/src/ipc/ipc.c
${PROJECT_SOURCE_DIR}/src/sys/unistd.c
${PROJECT_SOURCE_DIR}/src/sys/errno.c
${PROJECT_SOURCE_DIR}/src/sys/utsname.c
${PROJECT_SOURCE_DIR}/src/sys/ioctl.c
${PROJECT_SOURCE_DIR}/src/unistd/getppid.c
${PROJECT_SOURCE_DIR}/src/unistd/getpid.c
${PROJECT_SOURCE_DIR}/src/unistd/exit.c
${PROJECT_SOURCE_DIR}/src/unistd/setsid.c
${PROJECT_SOURCE_DIR}/src/unistd/getsid.c
${PROJECT_SOURCE_DIR}/src/unistd/setgid.c
${PROJECT_SOURCE_DIR}/src/unistd/getgid.c
${PROJECT_SOURCE_DIR}/src/unistd/fork.c
${PROJECT_SOURCE_DIR}/src/unistd/read.c
${PROJECT_SOURCE_DIR}/src/unistd/write.c
${PROJECT_SOURCE_DIR}/src/unistd/exec.c
${PROJECT_SOURCE_DIR}/src/unistd/nice.c
${PROJECT_SOURCE_DIR}/src/unistd/open.c
${PROJECT_SOURCE_DIR}/src/unistd/reboot.c
${PROJECT_SOURCE_DIR}/src/unistd/waitpid.c
${PROJECT_SOURCE_DIR}/src/unistd/chdir.c
${PROJECT_SOURCE_DIR}/src/unistd/getcwd.c
${PROJECT_SOURCE_DIR}/src/unistd/close.c
${PROJECT_SOURCE_DIR}/src/unistd/stat.c
${PROJECT_SOURCE_DIR}/src/unistd/rmdir.c
${PROJECT_SOURCE_DIR}/src/unistd/mkdir.c
${PROJECT_SOURCE_DIR}/src/unistd/unlink.c
${PROJECT_SOURCE_DIR}/src/unistd/getdents.c
${PROJECT_SOURCE_DIR}/src/unistd/lseek.c
${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/libc_start.c
${PROJECT_SOURCE_DIR}/src/debug.c
${PROJECT_SOURCE_DIR}/src/crt0.S
)
# Add the includes.
target_include_directories(${PROJECT_NAME} PUBLIC inc)
# Remove the 'lib' prefix.
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
+20
View File
@@ -0,0 +1,20 @@
/// MentOS, The Mentoring Operating system project
/// @file assert.h
/// @brief Defines the function and pre-processor macro for assertions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Function used to log the information of a failed assertion.
/// @param assertion The failed assertion.
/// @param file The file where the assertion is located.
/// @param function The function where the assertion is.
/// @param line The line inside the file.
void __assert_fail(const char *assertion, const char *file, const char *function, unsigned int line);
/// @brief Extract the filename from the full path provided by __FILE__.
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
/// @brief Assert function.
#define assert(expression) ((expression) ? (void)0 : __assert_fail(#expression, __FILENAME__, __func__, __LINE__))
+9
View File
@@ -0,0 +1,9 @@
/// @file ioctls.h
/// @brief Input/Output ConTroL (IOCTL) numbers.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#define TCGETS 0x5401U ///< Get the current serial port settings.
#define TCSETS 0x5402U ///< Set the current serial port settings.
+36
View File
@@ -0,0 +1,36 @@
/// MentOS, The Mentoring Operating system project
/// @file stat.h
/// @brief Defines the structure used by the functiosn fstat(), lstat(), and stat().
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#if !defined(__SYS_STAT_H) && !defined(__KERNEL__)
#error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
#endif
#include "stddef.h"
#include "time.h"
/// @brief Data structure which contains information about a file.
typedef struct stat_t {
/// ID of device containing file.
dev_t st_dev;
/// File serial number.
ino_t st_ino;
/// Mode of file.
mode_t st_mode;
/// File user id.
uid_t st_uid;
/// File group id.
gid_t st_gid;
/// File Size.
off_t st_size;
/// Time of last access.
time_t st_atime;
/// Time of last data modification.
time_t st_mtime;
/// Time of last status change.
time_t st_ctime;
} stat_t;
+45
View File
@@ -0,0 +1,45 @@
/// MentOS, The Mentoring Operating system project
/// @file termios-struct.h
/// @brief Definition of the `termios` structure.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Type for control characters.
typedef unsigned char cc_t;
/// Type for speed.
typedef unsigned int speed_t;
/// Type for flags.
typedef unsigned int tcflag_t;
/// The number of control characters.
#define NCCS 32
/// @brief Stores information about a terminal IOs.
typedef struct termios {
tcflag_t c_iflag; ///< input mode flags
tcflag_t c_oflag; ///< output mode flags
tcflag_t c_cflag; ///< control mode flags
tcflag_t c_lflag; ///< local mode flags
cc_t c_line; ///< line discipline
cc_t c_cc[NCCS]; ///< control characters
speed_t c_ispeed; ///< input speed
speed_t c_ospeed; ///< output speed
} termios;
/// @brief These flags generally control higher-level aspects of input processing than the input
/// modes flags described in Input Modes, such as echoing, signals, and the choice of canonical
/// or noncanonical input.
enum {
ISIG = 000001U, ///< Controls whether the INTR, QUIT, and SUSP characters are recognized.
ICANON = 000002U, ///< Enables canonical input processing mode.
ECHO = 000010U, ///< Echo input characters.
ECHOE = 000020U, ///< If ICANON is set, the ERASE character erases the preceding character.
ECHOK = 000040U, ///< If ICANON is set, the KILL character erases the current line.
ECHONL = 000100U, ///< If ICANON is set, echo the NL character even if ECHO is not set.
NOFLSH = 000200U, ///< Do not clear in/out queues when receiving INTR, QUIT, and SUSP.
TOSTOP = 000400U, ///< Allows SIGTTOU signals generated by background processes.
ECHOCTL = 001000U, ///< If this and ECHO are set, control characters with ^ are echoed.
ECHOKE = 004000U, ///< If ICANON is set, KILL is echoed by erasing each character on the line.
IEXTEN = 100000U, ///< Enables implementation-defined input processing.
};
+19 -1
View File
@@ -1,34 +1,52 @@
/// MentOS, The Mentoring Operating system project
/// @file ctype.h
/// @brief Functions related to character handling.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Check if the given value is a digit.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int isdigit(int c);
/// @brief Check if the given value is a letter.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int isalpha(int c);
/// @brief Check if the given value is either a letter or a digit.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int isalnum(int c);
/// @brief Check if the given value is an hexadecimal digit.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int isxdigit(int c);
/// @brief Check if the given value is a lower case letter.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int islower(int c);
/// @brief Check if the given value is an upper case letter.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int isupper(int c);
/// @brief Transforms the given value into a lower case letter.
/// @param c The input letter.
/// @return The input letter turned into a lower case letter.
int tolower(int c);
/// @brief Transforms the given value into an upper case letter.
/// @param c The input letter.
/// @return The input letter turned into an upper case letter.
int toupper(int c);
/// @brief Check if the given value is a whitespace.
/// @param c The input character.
/// @return 1 on success, 0 otherwise.
int isspace(int c);
+44
View File
@@ -0,0 +1,44 @@
/// MentOS, The Mentoring Operating system project
/// @file debug.h
/// @brief Debugging primitives.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#ifndef __DEBUG_HEADER__
/// Header for identifying outputs coming from a mechanism.
#define __DEBUG_HEADER__
#endif
/// @brief Extract the filename from the full path provided by __FILE__.
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
/// @brief Prints the given character to debug output.
/// @param c The character to print.
void dbg_putchar(char c);
/// @brief Prints the given string to debug output.
/// @param s The string to print.
void dbg_puts(const char *s);
/// @brief Prints the given string to the debug output.
/// @param file The name of the file.
/// @param fun The name of the function.
/// @param line The line inside the file.
/// @param format The format to used, see printf.
/// @param ... The list of arguments.
void dbg_printf(const char *file, const char *fun, int line, const char *format, ...);
/// @brief Transforms the given amount of bytes to a readable string.
/// @param bytes The bytes to turn to string.
/// @return String representing the bytes in human readable form.
const char *to_human_size(unsigned long bytes);
/// @brief Transforms the given value to a binary string.
/// @param value The decimal value.
/// @return String representing the binary value.
const char *dec_to_binary(unsigned long value);
/// Prints a debugging message.
#define pr_debug(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__ __VA_ARGS__)
+46
View File
@@ -0,0 +1,46 @@
/// MentOS, The Mentoring Operating system project
/// @file fcntl.h
/// @brief Headers of functions fcntl() and open().
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#define O_RDONLY 00000000U ///< Open for reading only.
#define O_WRONLY 00000001U ///< Open for writing only.
#define O_RDWR 00000002U ///< Open for reading and writing.
#define O_CREAT 00000100U ///< Create if nonexistant.
#define O_EXCL 00000200U ///< Error if already exists.
#define O_TRUNC 00001000U ///< Truncate to zero length.
#define O_APPEND 00002000U ///< Set append mode.
#define O_NONBLOCK 00004000U ///< No delay.
#define O_DIRECTORY 00200000U ///< If file exists has no effect. Otherwise, the file is created.
/// @defgroup ModeBitsAccessPermission Mode Bits for Access Permission
/// @brief The file modes.
/// @{
#define S_IRWXU 0000700U ///< RWX mask for user.
#define S_IRUSR 0000400U ///< R for user.
#define S_IWUSR 0000200U ///< W for user.
#define S_IXUSR 0000100U ///< X for user.
#define S_IRWXG 0000070U ///< RWX mask for group.
#define S_IRGRP 0000040U ///< R for group.
#define S_IWGRP 0000020U ///< W for group.
#define S_IXGRP 0000010U ///< X for group.
#define S_IRWXO 0000007U ///< RWX mask for group.
#define S_IROTH 0000004U ///< R for group.
#define S_IWOTH 0000002U ///< W for group.
#define S_IXOTH 0000001U ///< X for group.
#define S_ISDIR(m) (((m)&0170000) == 0040000) ///< directory.
#define S_ISCHR(m) (((m)&0170000) == 0020000) ///< char special
#define S_ISBLK(m) (((m)&0170000) == 0060000) ///< block special
#define S_ISREG(m) (((m)&0170000) == 0100000) ///< regular file
#define S_ISFIFO(m) (((m)&0170000) == 0010000) ///< fifo
#define S_ISLNK(m) (((m)&0170000) == 0120000) ///< symbolic link
#define S_ISSOCK(m) (((m)&0170000) == 0140000) ///< socket
/// @}
+37
View File
@@ -0,0 +1,37 @@
/// MentOS, The Mentoring Operating system project
/// @file fcvt.h
/// @brief Declare the functions required to turn double values into a string.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Thif function transforms `value` into a string of digits inside `buf`,
/// representing the whole part followed by the decimal part.
/// @details
/// For instance, 512.765 will result in:
/// decpt = 3
/// sign = 0
/// buf = "512765"
/// @param arg The argument to turn into string.
/// @param chars The total number of digits.
/// @param decpt The position of the decimal point.
/// @param sign The sign of the number.
/// @param buf Buffer where the digits should be placed.
/// @param buf_size Dimension of the buffer.
void ecvtbuf(double arg, int chars, int *decpt, int *sign, char *buf, unsigned buf_size);
/// @brief Thif function transforms `value` into a string of digits inside `buf`,
/// representing the whole part followed by the decimal part.
/// @details
/// For instance, 512.765 will result in:
/// decpt = 3
/// sign = 0
/// buf = "512765"
/// @param arg The argument to turn into string.
/// @param decimals The total number of digits to write after the decimal point.
/// @param decpt The position of the decimal point.
/// @param sign The sign of the number.
/// @param buf Buffer where the digits should be placed.
/// @param buf_size Dimension of the buffer.
void fcvtbuf(double arg, int decimals, int *decpt, int *sign, char *buf, unsigned buf_size);
+76
View File
@@ -0,0 +1,76 @@
/// MentOS, The Mentoring Operating system project
/// @file grp.h
/// @brief Defines the structures and functions for managing groups.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// Maximum number of users per group
#define MAX_MEMBERS_PER_GROUP 64
///@brief Contains user group informations
typedef struct group{
char* gr_name; // the name of the group
gid_t gr_gid; // numerical group ID
char* gr_passwd; // password
//pointer to a null-terminated array of character pointers to member names
char* gr_mem[MAX_MEMBERS_PER_GROUP + 1];
} group;
///@brief Provides access to the group database entry for `uid`.
///@param gid The gid to search inside the database.
///@return A pointer to the structure containing the database entry.
struct group* getgrgid(gid_t gid);
///@brief Provides access to the group database entry for `name`.
///@param name The name to search inside the database.
///@return A pointer to the structure containing the database entry.
struct group* getgrnam(const char* name);
///@brief Provides the same information as getgrgid but it stores the
/// results inside group, and the string information are store store
/// inside `buf`.
///@param gid The uid to search inside the database.
///@param group The structure containing pointers to the entry fields.
///@param buf The buffer where the strings should be stored.
///@param buflen The lenght of the buffer.
///@param result A pointer to the result or NULL is stored here.
///@return If the entry was found returns zero and set *result to group,
/// if the entry was not found returns zero and set *result to NULL,
/// on failure returns a number and sets and set *result to NULL.
int getgrgid_r(gid_t gid, struct group* group, char* buf, size_t buflen, struct group ** result);
///@brief Provides the same information as getgrnam but it stores the
/// results inside group, and the string information are store store
/// inside `buf`.
///@param name The name to search inside the database.
///@param group The structure containing pointers to the entry fields.
///@param buf The buffer where the strings should be stored.
///@param buflen The lenght of the buffer.
///@param result A pointer to the result or NULL is stored here.
///@return If the entry was found returns zero and set *result to group,
/// if the entry was not found returns zero and set *result to NULL,
/// on failure returns a number and sets and set *result to NULL.
int getgrnam_r(const char* name, struct group* group, char* buf, size_t buflen, struct group** result);
///@brief Returns a pointer to a structure containing the broken-out
/// fields of an entry in the group database.
/// When first called returns a pointer to a group structure
/// containing the first entry in the group database.
/// Thereafter, it returns a pointer to a group structure
/// containing the next group structure in the group database,
/// so successive calls may be used to search the entire database.
struct group* getgrent(void);
///@brief Rewinds the group database to allow repeated searches.
void endgrent(void);
///@brief May be called to close the group database when processing is complete.
void setgrent(void);
+27
View File
@@ -0,0 +1,27 @@
/// MentOS, The Mentoring Operating system project
/// @file mm_io.h
/// @brief Memory Mapped IO functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief Reads a 8-bit value from the given address.
uint8_t in_memb(uint32_t addr);
/// @brief Reads a 16-bit value from the given address.
uint16_t in_mems(uint32_t addr);
/// @brief Reads a 32-bit value from the given address.
uint32_t in_meml(uint32_t addr);
/// @brief Writes a 8-bit value at the given address.
void out_memb(uint32_t addr, uint8_t value);
/// @brief Writes a 16-bit value at the given address.
void out_mems(uint32_t addr, uint16_t value);
/// @brief Writes a 32-bit value at the given address.
void out_meml(uint32_t addr, uint32_t value);
+43
View File
@@ -0,0 +1,43 @@
/// MentOS, The Mentoring Operating system project
/// @file port_io.h
/// @brief Byte I/O on ports prototypes.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief Used for reading from the I/O ports.
/// @param port The input port.
/// @return The read value.
uint8_t inportb(uint16_t port);
/// @brief Used for reading 2 bytes from the I/O ports.
/// @param port The input port.
/// @return The read value.
uint16_t inports(uint16_t port);
void inportsm(uint16_t port, uint8_t *data, unsigned long size);
/// @brief Used for reading 4 bytes from the I/O ports.
/// @param port The input port.
/// @return The read value.
uint32_t inportl(uint16_t port);
/// @brief Use this to write to I/O ports to send bytes to devices.
/// @param port The output port.
/// @param data The data to write.
void outportb(uint16_t port, uint8_t data);
/// @brief Use this to write to I/O ports to send 2 bytes to devices.
/// @param port The output port.
/// @param data The data to write.
void outports(uint16_t port, uint16_t data);
void outportsm(uint16_t port, uint8_t *data, uint16_t size);
/// @brief Use this to write to I/O ports to send 4 bytes to devices.
/// @param port The output port.
/// @param data The data to write.
void outportl(uint16_t port, uint32_t data);
+25
View File
@@ -0,0 +1,25 @@
/// MentOS, The Mentoring Operating system project
/// @file ipc.h
/// @brief Inter-Process Communication (IPC) structures.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Permission details of an IPC object.
struct ipc_perm {
/// Key supplied to msgget(2).
key_t __key;
/// Effective UID of owner.
uid_t uid;
/// Effective GID of owner.
gid_t gid;
/// Effective UID of creator.
uid_t cuid;
/// Effective GID of creator.
gid_t cgid;
/// Permissions.
unsigned short mode;
/// Sequence number.
unsigned short __seq;
};
+70
View File
@@ -0,0 +1,70 @@
/// MentOS, The Mentoring Operating system project
/// @file msg.h
/// @brief Definition of structure for managing message queues.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "sys/types.h"
#include "stddef.h"
#include "time.h"
#include "ipc.h"
/// Type for storing the number of messages in a message queue.
typedef unsigned int msgqnum_t;
/// Type for storing the number of bytes in a message queue.
typedef unsigned int msglen_t;
/// @brief Buffer to use with the message queue IPC.
struct msgbuf {
/// Type of the message.
long mtype;
/// Text of the message.
char mtext[1];
};
/// @brief Message queue data structure.
struct msqid_ds {
/// Ownership and permissions.
struct ipc_perm msg_perm;
/// Time of last msgsnd(2).
time_t msg_stime;
/// Time of last msgrcv(2).
time_t msg_rtime;
/// Time of creation or last modification by msgctl().
time_t msg_ctime;
/// Number of bytes in queue.
unsigned long msg_cbytes;
/// Number of messages in queue.
msgqnum_t msg_qnum;
/// Maximum number of bytes in queue.
msglen_t msg_qbytes;
/// PID of last msgsnd(2).
pid_t msg_lspid;
/// PID of last msgrcv(2).
pid_t msg_lrpid;
};
#ifdef __KERNEL__
long sys_msgget(key_t key, int msgflg);
long sys_msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
long sys_msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);
long sys_msgctl(int msqid, int cmd, struct msqid_ds *buf);
#else
long msgget(key_t key, int msgflg);
long msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
long msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);
long msgctl(int msqid, int cmd, struct msqid_ds *buf);
#endif
+40
View File
@@ -0,0 +1,40 @@
/// MentOS, The Mentoring Operating system project
/// @file sem.h
/// @brief Definition of structure for managing semaphores.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "sys/types.h"
#include "stddef.h"
#include "time.h"
#include "ipc.h"
/// @brief Buffer to use with the semaphore IPC.
struct sembuf {
/// Semaphore index in array.
unsigned short sem_num;
/// Semaphore operation.
short sem_op;
/// Operation flags.
short sem_flg;
};
#ifdef __KERNEL__
long sys_semget(key_t key, int nsems, int semflg);
long sys_semop(int semid, struct sembuf *sops, unsigned nsops);
long sys_semctl(int semid, int semnum, int cmd, unsigned long arg);
#else
long semget(key_t key, int nsems, int semflg);
long semop(int semid, struct sembuf *sops, unsigned nsops);
long semctl(int semid, int semnum, int cmd, unsigned long arg);
#endif
+72 -47
View File
@@ -1,14 +1,48 @@
/// MentOS, The Mentoring Operating system project
/// @file shm.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// @brief Definition of structure for managing shared memories.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "sys/types.h"
#include "stddef.h"
#include "time.h"
#include "ipc.h"
/// Data type for storing the number of attaches.
typedef unsigned long shmatt_t;
/// @brief Shared memory data structure.
struct shmid_ds {
/// Operation permission struct.
struct ipc_perm shm_perm;
/// Size of segment in bytes.
size_t shm_segsz;
/// Time of last shmat().
time_t shm_atime;
/// Time of last shmdt().
time_t shm_dtime;
/// Time of last change by shmctl().
time_t shm_ctime;
/// Pid of creator.
pid_t shm_cpid;
/// Pid of last shmop.
pid_t shm_lpid;
/// Number of current attaches.
shmatt_t shm_nattch;
/// Pointer to the next shared memory data structure.
struct shmid_ds *next;
/// Where shm created is memorized, should be a file.
void *shm_location;
};
#if 0
#include "ipc.h"
#include "debug.h"
#include "clock.h"
#include "time.h"
#include "kheap.h"
#include "stddef.h"
#include "paging.h"
@@ -17,10 +51,10 @@
//======== Permission flag for shmget ==========================================
// or S_IRUGO from <linux/stat.h>.
#define SHM_R 0400
#define SHM_R 0400
// or S_IWUGO from <linux/stat.h>.
#define SHM_W 0200
#define SHM_W 0200
//==============================================================================
//======== Flags for shmat =====================================================
@@ -28,76 +62,43 @@
#define SHM_RDONLY 010000
// Round attach address to SHMLBA.
#define SHM_RND 020000
#define SHM_RND 020000
// Take-over region on attach.
#define SHM_REMAP 040000
#define SHM_REMAP 040000
// Execution access.
#define SHM_EXEC 0100000
#define SHM_EXEC 0100000
//==============================================================================
//======== Commands for shmctl =================================================
// Lock segment (root only).
#define SHM_LOCK 11
#define SHM_LOCK 11
// Unlock segment (root only).
#define SHM_UNLOCK 12
//==============================================================================
// Ipcs ctl commands.
#define SHM_STAT 13
#define SHM_STAT 13
#define SHM_INFO 14
#define SHM_STAT_ANY 15
#define SHM_STAT_ANY 15
//======== shm_mode upper byte flags ===========================================
// segment will be destroyed on last detach.
#define SHM_DEST 01000
#define SHM_DEST 01000
// Segment will not be swapped.
#define SHM_LOCKED 02000
#define SHM_LOCKED 02000
// Segment is mapped via hugetlb.
#define SHM_HUGETLB 04000
#define SHM_HUGETLB 04000
// Don't check for reservations.
#define SHM_NORESERVE 010000
typedef unsigned long shmatt_t;
struct shmid_ds {
// Operation permission struct.
struct ipc_perm shm_perm;
// Size of segment in bytes.
size_t shm_segsz;
// Time of last shmat().
time_t shm_atime;
// Time of last shmdt().
time_t shm_dtime;
// Time of last change by shmctl().
time_t shm_ctime;
// Pid of creator.
pid_t shm_cpid;
// Pid of last shmop.
pid_t shm_lpid;
// Number of current attaches.
shmatt_t shm_nattch;
struct shmid_ds *next;
// Where shm created is memorized, should be a file.
void *shm_location;
};
/// @@brief Syscall Service Routine: Shared memory control operation.
int syscall_shmctl(int *args);
@@ -130,3 +131,27 @@ struct shmid_ds *find_shm_fromkey(key_t key);
/// @@brief shmid_ds on list.
struct shmid_ds *find_shm_fromvaddr(void *shmvaddr);
#endif
#ifdef __KERNEL__
long sys_shmat(int shmid, char *shmaddr, int shmflg);
long sys_shmget(key_t key, size_t size, int flag);
long sys_shmdt(char *shmaddr);
long sys_shmctl(int shmid, int cmd, struct shmid_ds *buf);
#else
long shmat(int shmid, char *shmaddr, int shmflg);
long shmget(key_t key, size_t size, int flag);
long shmdt(char *shmaddr);
long shmctl(int shmid, int cmd, struct shmid_ds *buf);
#endif
+41
View File
@@ -0,0 +1,41 @@
/// MentOS, The Mentoring Operating system project
/// @file libgen.h
/// @brief String routines.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "stddef.h"
// TODO: doxygen comment.
/// @brief
/// @param out
/// @param cur
/// @param sep
/// @param max
/// @result
int parse_path(char *out, char **cur, char sep, size_t max);
// TODO: doxygen comment.
/// @brief
/// @param path
/// @result
char *dirname(const char *path);
// TODO: doxygen comment.
/// @brief
/// @param path
/// @result
char *basename(const char *path);
/// @brief Return the canonicalized absolute pathname.
/// @param path The path we are canonicalizing.
/// @param resolved The canonicalized path.
/// @return
/// If there is no error, realpath() returns a pointer to the resolved.
/// Otherwise, it returns NULL, the contents of the array resolved
/// are undefined, and errno is set to indicate the error.
/// @details
/// If resolved is NULL, then realpath() uses malloc
/// to allocate a buffer of up to PATH_MAX bytes to hold the
/// resolved pathname, and returns a pointer to this buffer.
char *realpath(const char *path, char *resolved);
+58
View File
@@ -0,0 +1,58 @@
/// MentOS, The Mentoring Operating system project
/// @file limits.h
/// @brief OS numeric limits.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Number of bits in a `char'.
#define CHAR_BIT 8
/// Minimum value a `signed char' can hold.
#define SCHAR_MIN -128
/// Maximum value a `signed char' can hold.
#define SCHAR_MAX +127
/// Minimum value a `signed char' can hold.
#define CHAR_MIN SCHAR_MIN
/// Maximum value a `signed char' can hold.
#define CHAR_MAX SCHAR_MAX
/// Maximum value a `char' can hold.
#define UCHAR_MAX 255
/// Minimum value a `signed short int' can hold.
#define SHRT_MIN (-32768)
/// Maximum value a `signed short int' can hold.
#define SHRT_MAX (+32767)
/// Maximum value a `unsigned short int' can hold.
#define USHRT_MAX 65535
/// Minimum value a `signed int' can hold.
#define INT_MIN (-2147483648)
/// Maximum values a `signed int' can hold.
#define INT_MAX (+2147483647)
/// Maximum value an `unsigned int' can hold.
#define UINT_MAX (+2147483647)
/// Maximum value a `signed long int' can hold.
#define LONG_MIN (-2147483648L)
/// Minimum value a `signed long int' can hold.
#define LONG_MAX (+2147483647L)
/// Maximum number of characters in a file name.
#define NAME_MAX 255
/// Maximum number of characters in a path name.
#define PATH_MAX 4096
/// Maximum pid number.
#define PID_MAX_LIMIT 32768
+158
View File
@@ -0,0 +1,158 @@
/// MentOS, The Mentoring Operating system project
/// @file math.h
/// @brief Mathematical constants and functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief The absolute value.
#define abs(a) (((a) < 0) ? -(a) : (a))
/// @brief The max of the two values.
#define max(a, b) (((a) > (b)) ? (a) : (b))
/// @brief The min of the two values.
#define min(a, b) (((a) < (b)) ? (a) : (b))
/// @brief The sign the the passed value.
#define sign(x) ((x < 0) ? -1 : ((x > 0) ? 1 : 0))
/// @brief e
#define M_E 2.7182818284590452354
/// @brief log_2 e
#define M_LOG2E 1.4426950408889634074
/// @brief log_10 e
#define M_LOG10E 0.43429448190325182765
/// @brief log_e 2
#define M_LN2 0.69314718055994530942
/// @brief log_e 10
#define M_LN10 2.30258509299404568402
/// @brief pi
#define M_PI 3.14159265358979323846
/// @brief pi / 2
#define M_PI_2 1.57079632679489661923
/// @brief pi / 4
#define M_PI_4 0.78539816339744830962
/// @brief 1 / pi
#define M_1_PI 0.31830988618379067154
/// @brief 2 / pi
#define M_2_PI 0.63661977236758134308
/// @brief 2 / sqrt(pi)
#define M_2_SQRTPI 1.12837916709551257390
/// @brief sqrt(2)
#define M_SQRT2 1.41421356237309504880
/// @brief 1 / sqrt(2)
#define M_SQRT1_2 0.70710678118654752440
/// @brief Returns the integral value that is nearest to x, with
/// halfway cases rounded away from zero.
/// @param x Value to round.
/// @result The value of x rounded to the nearest integral
/// (as a floating-point value).
double round(double x);
/// @brief Rounds x upward, returning the smallest integral value
/// that is not less than x.
/// @param x Value to round up.
/// @return The smallest integral value that is not less than x
/// (as a floating-point value).
double ceil(double x);
/// @brief Rounds x downward, returning the largest integral value
/// that is not greater than x.
/// @param x Value to round down.
/// @return The value of x rounded downward (as a floating-point value).
double floor(double x);
/// @brief Returns base raised to the power exponent:
/// @param base Base value.
/// @param exponent Exponent value.
/// @result The result of raising base to the power exponent.
/// @details
/// If the base is finite negative and the exponent is finite but not an
/// integer value, it causes a domain error.
/// If both base and exponent are zero, it may also cause a domain error
/// on certain implementations.
/// If base is zero and exponent is negative, it may cause a domain error
/// or a pole error (or none, depending on the library implementation).
/// The function may also cause a range error if the result is too great
/// or too small to be represented by a value of the return type.
double pow(double base, double exponent);
/// @brief Returns the base-e exponential function of x, which is e raised
/// to the power x: e^x.
/// @param x Value of the exponent.
/// @return Exponential value of x.
/// @details
/// If the magnitude of the result is too large to be represented by a value
/// of the return type, the function returns HUGE_VAL (or HUGE_VALF or
/// HUGE_VALL) with the proper sign, and an overflow range error occurs and
/// the global variable errno is set to ERANGE.
double exp(double x);
/// @brief Returns the absolute value of x: |x|.
/// @param x Value whose absolute value is returned.
/// @result The absolute value of x.
double fabs(double x);
/// @brief Returns the absolute value of x: |x|.
/// @param x Value whose absolute value is returned.
/// @result The absolute value of x.
float fabsf(float x);
/// @brief Returns the square root of x.
/// @param x Value whose square root is computed.
/// @return Square root of x. If x is negative, the global variable errno
/// is set to EDOM.
double sqrt(double x);
/// @brief Returns the square root of x.
/// @param x Value whose square root is computed.
/// @return Square root of x. If x is negative, the global variable errno
/// is set to EDOM.
float sqrtf(float x);
/// @brief Checks if the input value is Infinite (INF).
/// @param x The value to check.
/// @return 1 if INF, 0 otherwise.
int isinf(double x);
/// @brief Checks if the input value is Not A Number (NAN).
/// @param x The value to check.
/// @return 1 if NAN, 0 otherwise.
int isnan(double x);
/// @brief Logarithm function in base 10.
/// @param x Topic of the logarithm function.
/// @return Return the result.
double log10(double x);
/// @brief Natural logarithm function.
/// @param x Topic of the logarithm function.
/// @return Return the result.
double ln(double x);
/// @brief Logarithm function in base x.
/// @param x Base of the logarithm.
/// @param y Topic of the logarithm function.
/// @return Return the result.
double logx(double x, double y);
/// @brief Breaks x into an integral and a fractional part, both parts have the same sign as x.
/// @param x The value we want to break.
/// @param intpart Where we store the integer part.
/// @return the fractional part.
double modf(double x, double *intpart);
+56
View File
@@ -0,0 +1,56 @@
/// MentOS, The Mentoring Operating system project
/// @file pwd.h
/// @brief Contains the structure and functions for managing passwords.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Stores user account information.
typedef struct passwd_t {
char *pw_name; ///< User's login name.
char *pw_passwd; ///< Encrypted password (not currently).
uid_t pw_uid; ///< User ID.
gid_t pw_gid; ///< Group ID.
char *pw_gecos; ///< User's full name.
char *pw_dir; ///< User's login directory.
char *pw_shell; ///< User's login shell.
} passwd_t;
/// @brief Provides access to the password database entry for `name`.
/// @param name The name to search inside the database.
/// @return A pointer to the structure containing the database entry.
passwd_t *getpwnam(const char *name);
/// @brief Provides access to the password database entry for `uid`.
/// @param uid The uid to search inside the database.
/// @return A pointer to the structure containing the database entry.
passwd_t *getpwuid(uid_t uid);
/// @brief Provides the same information as getpwnam but it stores the
/// results inside pwd, and the string information are store store
/// inside `buf`.
/// @param name The name to search inside the database.
/// @param pwd The structure containing pointers to the entry fields.
/// @param buf The buffer where the strings should be stored.
/// @param buflen The lenght of the buffer.
/// @param result A pointer to the result or NULL is stored here.
/// @return If the entry was found returns zero and set *result to pwd,
/// if the entry was not found returns zero and set *result to NULL,
/// on failure returns a number and sets and set *result to NULL.
int getpwnam_r(const char *name, passwd_t *pwd, char *buf, size_t buflen, passwd_t **result);
/// @brief Provides the same information as getpwuid but it stores the
/// results inside pwd, and the string information are store store
/// inside `buf`.
/// @param uid The uid to search inside the database.
/// @param pwd The structure containing pointers to the entry fields.
/// @param buf The buffer where the strings should be stored.
/// @param buflen The lenght of the buffer.
/// @param result A pointer to the result or NULL is stored here.
/// @return If the entry was found returns zero and set *result to pwd,
/// if the entry was not found returns zero and set *result to NULL,
/// on failure returns a number and sets and set *result to NULL.
int getpwuid_r(uid_t uid, passwd_t *pwd, char *buf, size_t buflen, passwd_t **result);
+29
View File
@@ -0,0 +1,29 @@
/// MentOS, The Mentoring Operating system project
/// @file sched.h
/// @brief Structures and functions for managing the scheduler.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/types.h"
#include "time.h"
#include "stdbool.h"
/// @brief Structure that describes scheduling parameters.
typedef struct sched_param_t {
/// Static execution priority.
int sched_priority;
/// Expected period of the task
time_t period;
/// Absolute deadline
time_t deadline;
/// Absolute time of arrival of the task
time_t arrivaltime;
/// Is task periodic?
bool_t is_periodic;
} sched_param_t;
int sched_setparam(pid_t pid, const sched_param_t *param);
int sched_getparam(pid_t pid, sched_param_t *param);
int waitperiod();
+273
View File
@@ -0,0 +1,273 @@
/// MentOS, The Mentoring Operating system project
/// @file signal.h
/// @brief Signals definition.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "sys/types.h"
/// @brief List of signals.
typedef enum {
SIGHUP = 1, ///< Hang up detected on controlling terminal or death of controlling process.
SIGINT = 2, ///< Issued if the user sends an interrupt signal (Ctrl + C).
SIGQUIT = 3, ///< Issued if the user sends a quit signal (Ctrl + D).
SIGILL = 4, ///< Illegal Instruction.
SIGTRAP = 5, ///< Trace/breakpoint trap.
SIGABRT = 6, ///< Abort signal from abort().
SIGEMT = 7, ///< Emulator trap.
SIGFPE = 8, ///< Floating-point arithmetic exception.
SIGKILL = 9, ///< If a process gets this signal it must quit immediately and will not perform any clean-up operations.
SIGBUS = 10, ///< Bus error (bad memory access).
SIGSEGV = 11, ///< Invalid memory reference.
SIGSYS = 12, ///< Bad system call (SVr4).
SIGPIPE = 13, ///< Broken pipe: write to pipe with no readers.
SIGALRM = 14, ///< Alarm clock signal (used for timers).
SIGTERM = 15, ///< Software termination signal (sent by kill by default).
SIGUSR1 = 16, ///< User-defined signal 1.
SIGUSR2 = 17, ///< User-defined signal 2.
SIGCHLD = 18, ///< Child stopped or terminated.
SIGPWR = 19, ///< Power failure.
SIGWINCH = 20, ///< Window resize signal.
SIGURG = 21, ///< Urgent condition on socket.
SIGPOLL = 22, ///< Pollable event.
SIGSTOP = 23, ///< Stop process.
SIGTSTP = 24, ///< Stop typed at terminal.
SIGCONT = 25, ///< Continue if stopped.
SIGTTIN = 26, ///< Terminal input for background process.
SIGTTOU = 27, ///< Terminal output for background process.
SIGVTALRM = 28, ///< Virtual alarm clock.
SIGPROF = 29, ///< Profiling timer expired.
SIGXCPU = 30, ///< CPU time limit exceeded.
SIGXFSZ = 31, ///< File size limit exceeded.
NSIG
} signal_type_t;
/// @brief Codes that indentify the sender of a signal.
typedef enum {
SI_NOINFO, ///< Unable to determine complete signal information.
// Signal : -
// Enabled fields : si_pid, si_uid
SI_USER, ///< Signal sent by kill(), pthread_kill(), raise(), abort() or alarm().
// Signal : -
// Enabled fields : -
SI_KERNEL, ///< Generic kernel function
// Signal : -
// Enabled fields : si_pid, si_uid, si_value
SI_QUEUE, ///< Signal was sent by sigqueue().
SI_TIMER, ///< Signal was generated by expiration of a timer set by timer_settimer().
SI_ASYNCIO, ///< Signal was generated by completion of an asynchronous I/O request.
SI_MESGQ, ///< Signal was generated by arrival of a message on an empty message queue.
// Signal : SIGILL
// Enabled fields : si_addr (address of failing instruction)
ILL_ILLOPC, ///< Illegal opcode.
ILL_ILLOPN, ///< Illegal operand.
ILL_ILLADR, ///< Illegal addressing mode.
ILL_ILLTRP, ///< Illegal trap.
ILL_PRVOPC, ///< Privileged opcode.
ILL_PRVREG, ///< Privileged register.
ILL_COPROC, ///< Coprocessor error.
ILL_BADSTK, ///< Internal stack error.
// Signal : SIGFPE
// Enabled fields : si_addr (address of failing instruction)
FPE_INTDIV, ///< Integer divide-by-zero.
FPE_INTOVF, ///< Integer overflow.
FPE_FLTDIV, ///< Floating point divide-by-zero.
FPE_FLTOVF, ///< Floating point overflow.
FPE_FLTUND, ///< Floating point underflow.
FPE_FLTRES, ///< Floating point inexact result.
FPE_FLTINV, ///< Invalid floating point operation.
FPE_FLTSUB, ///< Subscript out of range.
// Signal : SIGSEGV
// Enabled fields : si_addr (address of faulting memory reference)
SEGV_MAPERR, ///< Address not mapped.
SEGV_ACCERR, ///< Invalid permissions.
// Signal : SIGBUS
// Enabled fields : si_addr (address of faulting memory reference)
BUS_ADRALN, ///< Invalid address alignment.
BUS_ADRERR, ///< Non-existent physical address.
BUS_OBJERR, ///< Object-specific hardware error.
// Signal : SIGTRAP
// Enabled fields : -
TRAP_BRKPT, ///< Process breakpoint.
TRAP_TRACE, ///< Process trace trap.
// Signal : SIGCHLD
// Enabled fields : si_pid (child process ID)
// si_uid (real user ID of process that sent the signal)
// si_status (exit value or signal)
CLD_EXITED, ///< Child has exited.
CLD_KILLED, ///< Child has terminated abnormally and did not create a core file.
CLD_DUMPED, ///< Child has terminated abnormally and created a core file.
CLD_TRAPPED, ///< Traced child has trapped.
CLD_STOPPED, ///< Child has stopped.
CLD_CONTINUED, ///< Stopped child has continued.
// Signal : SIGIO/SIGPOLL
// Enabled fields : si_band
POLL_IN, ///< Data input available.
POLL_OUT, ///< Output buffers available.
POLL_MSG, ///< Input message available.
POLL_ERR, ///< I/O error.
POLL_PRI, ///< High priority input available.
POLL_HUP, ///< Device disconnected.
} signal_sender_code_t;
/// @brief Defines what to do with the provided signal mask.
typedef enum {
/// @brief The set of blocked signals is the union of the current set
/// and the set argument.
SIG_BLOCK,
/// @brief The signals in set are removed from the current set of
/// blocked signals. It is permissible to attempt to unblock
/// a signal which is not blocked.
SIG_UNBLOCK,
/// @brief The set of blocked signals is set to the argument set.
SIG_SETMASK
} sigmask_how_t;
/// @defgroup SigactionFlags Flags associated with a sigaction.
/// @{
#define SA_NOCLDSTOP 0x00000001U ///< Turn off SIGCHLD when children stop.
#define SA_NOCLDWAIT 0x00000002U ///< Flag on SIGCHLD to inhibit zombies.
#define SA_SIGINFO 0x00000004U ///< sa_sigaction specifies the signal-handling function for signum.
#define SA_ONSTACK 0x08000000U ///< Indicates that a registered stack_t will be used.
#define SA_RESTART 0x10000000U ///< Flag to get restarting signals (which were the default long ago)
#define SA_NODEFER 0x40000000U ///< Prevents the current signal from being masked in the handler.
#define SA_RESETHAND 0x80000000U ///< Clears the handler when the signal is delivered.
/// @}
/// Type of a signal handler.
typedef void (*sighandler_t)(int);
#define SIG_DFL ((sighandler_t)0) ///< Default signal handling.
#define SIG_IGN ((sighandler_t)1) ///< Ignore signal.
#define SIG_ERR ((sighandler_t)-1) ///< Error return from signal.
/// @brief Structure used to mask and unmask signals.
/// @details
/// Each unsigned long consists of 32 bits, thus, the maximum number of signals
/// that may be declared is 64.
/// Signals are divided into two cathegories, identified by the two unsigned longs:
/// [ 1, 31] corresponds to normal signals;
/// [32, 64] corresponds to real-time signals.
typedef struct sigset_t {
/// Signals divided into two cathegories.
unsigned long sig[2];
} sigset_t;
/// @brief Holds the information on how to handle a specific signal.
typedef struct sigaction_t {
/// This field specifies the type of action to be performed; its value can be a pointer
/// to the signal handler, SIG_DFL (that is, the value 0) to specify that the default
/// action is performed, or SIG_IGN (that is, the value 1) to specify that the signal is
/// ignored.
sighandler_t sa_handler;
/// This sigset_t variable specifies the signals to be masked when running the signal handler
sigset_t sa_mask;
/// This set of flags specifies how the signal must be handled;
unsigned int sa_flags;
} sigaction_t;
/// @brief Data passed with signal info.
typedef union sigval {
int sival_int; ///< Integer value.
void *sival_ptr; ///< Pointer value.
} sigval_t;
/// @brief Stores information about an occurrence of a specific signal.
typedef struct siginfo_t {
/// The signal number.
int si_signo;
/// A code identifying who raised the signal (see signal_sender_code_t).
int si_code;
/// Signal value.
sigval_t si_value;
/// The error code of the instruction that caused the signal to be raised, or 0 if there was no error.
int si_errno;
/// Process ID of sending process.
pid_t si_pid;
/// Real user ID of sending process.
uid_t si_uid;
/// Address at which fault occurred.
void *si_addr;
/// Exit value or signal for process termination.
int si_status;
/// Band event for SIGPOLL/SIGIO.
int si_band;
} siginfo_t;
/// @brief Send signal to a process.
/// @param pid The pid of the process to which we send the signal.
/// @param sig The type of signal to send.
/// @return On success 0, on error -1 and errno is set appropriately.
int kill(pid_t pid, int sig);
/// @brief Sets the disposition of the signal signum to handler.
/// @param signum The signal number.
/// @param handler The handler for the signal.
/// @return The previous value of the signal handler, or SIG_ERR on error.
sighandler_t signal(int signum, sighandler_t handler);
/// @brief Examine and change a signal action.
/// @param signum Specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.
/// @param act If non-NULL, the new action for signal signum is installed from act.
/// @param oldact If non-NULL, the previous action is saved in oldact.
/// @return returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
int sigaction(int signum, const sigaction_t *act, sigaction_t *oldact);
/// @brief Examine and change blocked signals.
/// @param how Determines the behavior of the call.
/// @param set The set of signals to manage by the function.
/// @param oldset If non-NULL, the previous value of the signal mask is stored here.
/// @return returns 0 on success, and -1 on error (errno is set to indicate the cause).
/// @details
/// If set is NULL, then the signal mask is unchanged (i.e., how is
/// ignored), but the current value of the signal mask is
/// nevertheless returned in oldset (if it is not NULL).
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
/// @brief Returns the string describing the given signal.
/// @param sig The signal to inquire.
/// @return String representing the signal.
const char *strsignal(int sig);
/// @brief Prepare an empty set.
/// @param set The set to manipulate.
/// @return 0 on success and -1 on error.
int sigemptyset(sigset_t *set);
/// @brief Prepare a full set.
/// @param set The set to manipulate.
/// @return 0 on success and -1 on error.
int sigfillset(sigset_t *set);
/// @brief Adds the given signal to the correct set.
/// @param set The set to manipulate.
/// @param signum The signalt to handle.
/// @return 0 on success and -1 on error.
int sigaddset(sigset_t *set, int signum);
/// @brief Removes the given signal to the correct set.
/// @param set The set to manipulate.
/// @param signum The signalt to handle.
/// @return 0 on success and -1 on error.
int sigdelset(sigset_t *set, int signum);
/// @brief Checks if the given signal is part of the set.
/// @param set The set to manipulate.
/// @param signum The signalt to handle.
/// @return 1 if signum is a member of set,
/// 0 if signum is not a member, and -1 on error.
int sigismember(sigset_t *set, int signum);
@@ -1,7 +1,7 @@
/// MentOS, The Mentoring Operating system project
/// @file stdarg.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// @brief Contains the macros required to manage variable number of arguments.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
@@ -16,7 +16,7 @@ typedef char *va_list;
/// @brief Amount of space required in an argument list (ie. the stack) for an
/// argument of type t.
#define va_size(t) \
#define va_size(t) \
(((sizeof(t) + sizeof(va_item) - 1) / sizeof(va_item)) * sizeof(va_item))
/// @brief The start of a variadic list.
+13
View File
@@ -0,0 +1,13 @@
/// MentOS, The Mentoring Operating system project
/// @file stdbool.h
/// @brief Defines the boolean values.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Define boolean value.
typedef enum bool_t {
false, ///< [0] False.
true ///< [1] True.
} __attribute__((__packed__)) bool_t;
+71
View File
@@ -0,0 +1,71 @@
/// MentOS, The Mentoring Operating system project
/// @file stddef.h
/// @brief Define basic data types.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#ifndef NULL
/// @brief Define NULL.
#define NULL ((void *)0)
#endif
#ifndef EOF
/// @brief Define End-Of-File.
#define EOF (-1)
#endif
/// @brief Define the size of a buffer.
#define BUFSIZ 512
/// Is the signed integer type of the result of subtracting two pointers.
typedef long signed int ptrdiff_t;
/// Define the byte type.
typedef unsigned char byte_t;
/// Define the generic size type.
typedef unsigned long size_t;
/// Define the generic signed size type.
typedef long ssize_t;
/// Define the type of an inode.
typedef unsigned int ino_t;
/// Used for device IDs.
typedef unsigned int dev_t;
/// The type of user-id.
typedef unsigned int uid_t;
/// The type of group-id.
typedef unsigned int gid_t;
/// The type of offset.
typedef long int off_t;
/// The type of mode.
typedef unsigned int mode_t;
/// This data-type is used to set protection bits of pages.
typedef unsigned int pgprot_t;
/// It evaluates to the offset (in bytes) of a given member within
/// a struct or union type, an expression of type size_t.
#define offsetof(type, member) \
((size_t) & (((type *)0)->member))
/// Retrieve an enclosing structure from a pointer to a nested element.
#if 1
#define container_of(ptr, type, member) \
((type *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member)))
#else
#define container_of(ptr, type, member) \
((type *)((char *)ptr - offsetof(type, member)))
#endif
/// Returns the alignment, in bytes, of the specified type.
#define alignof(type) offsetof( \
struct { char c; type member; }, member)
@@ -1,7 +1,7 @@
/// MentOS, The Mentoring Operating system project
/// @file stdint.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// @brief Standard integer data-types.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
+129
View File
@@ -0,0 +1,129 @@
/// MentOS, The Mentoring Operating system project
/// @file stdio.h
/// @brief Standard I/0 functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdarg.h"
#include "stddef.h"
/// @brief The maximum number of digits of an integer.
#define MAX_DIGITS_IN_INTEGER 11
/// @brief The size of 'gets' buffer.
#define GETS_BUFFERSIZE 255
#ifndef EOF
/// @brief Define the End-Of-File.
#define EOF (-1)
#endif
#define SEEK_SET 0 ///< The file offset is set to offset bytes.
#define SEEK_CUR 1 ///< The file offset is set to its current location plus offset bytes.
#define SEEK_END 2 ///< The file offset is set to the size of the file plus offset bytes.
/// @brief Writes the given character to the standard output (stdout).
/// @param character The character to send to stdout.
void putchar(int character);
/// @brief Writes the string pointed by str to the standard output (stdout)
/// and appends a newline character.
/// @param str The string to send to stdout.
void puts(char *str);
/// @brief Returns the next character from the standard input (stdin).
/// @return The character received from stdin.
int getchar();
/// @brief Reads characters from the standard input (stdin).
/// @param str Where the characters are stored.
/// @return The string received from standard input.
char *gets(char *str);
#ifndef __KERNEL__
/// @brief Same as getchar but reads from the given file descriptor.
/// @param fd The file descriptor from which it reads.
/// @return The read character.
int fgetc(int fd);
/// @brief Same as gets but reads from the given file descriptor.
/// @param buf The buffer where the string should be placed.
/// @param n The amount of characters to read.
/// @param fd The file descriptor from which it reads.
/// @return The read string.
char *fgets(char *buf, int n, int fd);
#endif
/// @brief Convert the given string to an integer.
/// @param str The string to convert.
/// @return The integer contained inside the string.
int atoi(const char *str);
/// @brief Converts the initial part of `str` to a long int value according to
/// the given base, which.
/// @param str This is the string containing the integral number.
/// @param endptr Set to the character after the numerical value.
/// @param base The base must be between 2 and 36 inclusive, or special 0.
/// @return Integral number as a long int value, else zero value is returned.
long strtol(const char *str, char **endptr, int base);
/// @brief Write formatted output to stdout.
/// @param fmt The format string.
/// @param ... The list of arguments.
/// @return On success, the total number of characters written is returned.
/// On failure, a negative number is returned.
int printf(const char *fmt, ...);
/// @brief Write formatted output to `str`.
/// @param str The buffer where the formatted string will be placed.
/// @param fmt Format string, following the same specifications as printf.
/// @param ... The list of arguments.
/// @return On success, the total number of characters written is returned.
/// On failure, a negative number is returned.
int sprintf(char *str, const char *fmt, ...);
#ifndef __KERNEL__
/// @brief The same as sprintf, but it putput on file.
/// @param fd The file descriptor associated with the file.
/// @param fmt Format string, following the same specifications as printf.
/// @param ... The list of arguments.
/// @return On success, the total number of characters written is returned.
/// On failure, a negative number is returned.
int fprintf(int fd, const char *fmt, ...);
#endif
/// @brief Write formatted data from variable argument list to string.
/// @param str Pointer to a buffer where the resulting C-string is stored.
/// @param fmt Format string, following the same specifications as printf.
/// @param args A variable arguments list.
/// @return On success, the total number of characters written is returned.
/// On failure, a negative number is returned.
int vsprintf(char *str, const char *fmt, va_list args);
#ifndef __KERNEL__
/// @brief Read formatted input from stdin.
/// @param fmt Format string, following the same specifications as printf.
/// @param ... The list of arguments where the values are stored.
/// @return On success, the function returns the number of items of the
/// argument list successfully filled. EOF otherwise.
int scanf(const char *fmt, ...);
#endif
/// @brief Read formatted data from string.
/// @param str String processed as source to retrieve the data.
/// @param fmt Format string, following the same specifications as printf.
/// @param ... The list of arguments where the values are stored.
/// @return On success, the function returns the number of items of the
/// argument list successfully filled. EOF otherwise.
int sscanf(const char *str, const char *fmt, ...);
#ifndef __KERNEL__
/// @brief The same as sscanf but the source is a file.
/// @param fd The file descriptor associated with the file.
/// @param fmt Format string, following the same specifications as printf.
/// @param ... The list of arguments where the values are stored.
/// @return On success, the function returns the number of items of the
/// argument list successfully filled. EOF otherwise.
int fscanf(int fd, const char *fmt, ...);
#endif
+71
View File
@@ -0,0 +1,71 @@
/// MentOS, The Mentoring Operating system project
/// @file stdlib.h
/// @brief Useful generic functions and macros.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Returns the number of usable bytes in the block pointed to by ptr.
/// @param ptr The pointer for which we want to retrieve the usable size.
/// @return The number of usable bytes in the block of allocated memory
/// pointed to by ptr. If ptr is not a valid pointer, 0 is returned.
size_t malloc_usable_size(void *ptr);
/// @brief Provides dynamically allocated memory.
/// @param size The amount of memory to allocate.
/// @return A pointer to the allocated memory.
void *malloc(unsigned int size);
/// @brief Allocates a block of memory for an array of num elements.
/// @param num The number of elements.
/// @param size The size of an element.
/// @return A pointer to the allocated memory.
void *calloc(size_t num, size_t size);
/// @brief Reallocates the given area of memory.
/// @param ptr The pointer to the memory to reallocate.
/// @param size The new size for the memory.
/// @return A pointer to the new portion of memory.
/// @details
/// It must be previously allocated by malloc(), calloc() or realloc() and
/// not yet freed with a call to free or realloc. Otherwise, the results
/// are undefined.
void *realloc(void *ptr, size_t size);
/// @brief Frees dynamically allocated memory.
/// @param ptr The pointer to the allocated memory.
void free(void *ptr);
/// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 31U) - 1U)
/// @brief Allows to set the seed of the random value generator.
/// @param x The new seed.
void srand(int x);
/// @brief Generates a random value.
/// @return The random value.
int rand();
/// @brief Cause an abnormal program termination with core-dump.
void abort();
/// @brief Tries to adds the variable to the environment.
/// @param name Name of the variable.
/// @param value Value of the variable.
/// @param overwrite Override existing variable value or not.
/// @return Zero on success, or -1 on error with errno indicating the cause.
int setenv(const char *name, const char *value, int overwrite);
/// @brief Tries to remove the variable from the environment.
/// @param name Name of the variable.
/// @return Zero on success, or -1 on error with errno indicating the cause.
int unsetenv(const char *name);
/// @brief Returns the value of the given variable.
/// @param name Name of the variable.
/// @return A pointer to the value, or NULL if there is no match.
char *getenv(const char *name);
+14
View File
@@ -0,0 +1,14 @@
/// MentOS, The Mentoring Operating system project
/// @file strerror.h
/// @brief Contains the function that transfornms an errno into a string.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include <sys/errno.h>
/// @brief Returns the string representing the error number.
/// @param errnum The error number.
/// @return The string representing the error number.
char *strerror(int errnum);
+311
View File
@@ -0,0 +1,311 @@
/// MentOS, The Mentoring Operating system project
/// @file string.h
/// @brief String routines.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Copies the first num characters of source to destination.
/// @param destination Pointer to the destination array where the content is to be copied.
/// @param source String to be copied.
/// @param num Maximum number of characters to be copied from source.
/// @return destination is returned.
char *strncpy(char *destination, const char *source, size_t num);
/// @brief Compares up to n characters of s1 to those of s2.
/// @param s1 First string to be compared.
/// @param s2 Second string to be compared.
/// @param n Maximum number of characters to compare.
/// @return
/// Returns an integral value indicating the relationship between the strings:
/// <0 the first character that does not match has a lower
/// value in s1 than in s2
/// 0 the contents of both strings are equal
/// >0 the first character that does not match has a greater
/// value in s1 than in s2
int strncmp(const char *s1, const char *s2, size_t n);
/// @brief Case insensitive string compare.
/// @param s1 First string to be compared.
/// @param s2 Second string to be compared.
/// @return
/// Returns an integral value indicating the relationship between the strings:
/// <0 the first character that does not match has a lower
/// value in s1 than in s2
/// 0 the contents of both strings are equal
/// >0 the first character that does not match has a greater
/// value in s1 than in s2
int stricmp(const char *s1, const char *s2);
/// @brief Case-insensitively compare up to n characters of s1 to those of s2.
/// @param s1 First string to be compared.
/// @param s2 Second string to be compared.
/// @param n Maximum number of characters to compare.
/// @return
/// Returns an integral value indicating the relationship between the strings:
/// <0 the first character that does not match has a lower
/// value in s1 than in s2
/// 0 the contents of both strings are equal
/// >0 the first character that does not match has a greater
/// value in s1 than in s2
int strnicmp(const char *s1, const char *s2, size_t n);
/// @brief Returns a pointer to the first occurrence of ch in str.
/// @param s The string where the search is performed.
/// @param ch Character to be located.
/// @return A pointer to the first occurrence of character in str.
char *strchr(const char *s, int ch);
/// @brief Returns a pointer to the last occurrence of ch in str.
/// @param s The string where the search is performed.
/// @param ch Character to be located.
/// @return A pointer to the last occurrence of character in str.
char *strrchr(const char *s, int ch);
/// @brief Returns a pointer to the first occurrence of s2 in s1,
/// or NULL if s2 is not part of s1.
/// @param s1 String to be scanned
/// @param s2 String containing the sequence of characters to match.
/// @return A pointer to the first occurrence in s1 of the entire
/// sequence of characters specified in s2, or a null pointer
/// if the sequence is not present in s1.
char *strstr(const char *s1, const char *s2);
/// @brief Returns the length of the initial portion of string which consists
/// only of characters that are part of control.
/// @param string String to be scanned.
/// @param control String containing the characters to match.
/// @return The number of characters in the initial segment of string which
/// consist only of characters from control.
size_t strspn(const char *string, const char *control);
/// @brief Calculates the length of the initial segment of string which
/// consists entirely of characters not in control.
/// @param string String to be scanned.
/// @param control String containing the characters to match.
/// @return The number of characters in the initial segment of string which
/// consist only of characters that are not inside control.
size_t strcspn(const char *string, const char *control);
/// @brief Finds the first character in the string string that matches any
/// character specified in control.
/// @param string String to be scanned.
/// @param control String containing the characters to match.
/// @return
/// A pointer to the first occurrence in string of any of the characters
/// that are part of control, or a null pointer if none of the characters
/// of control is found in string before the terminating null-character.
char *strpbrk(const char *string, const char *control);
/// @brief Make a copy of the given string.
/// @param s String to duplicate.
/// @return On success, returns a pointer to the duplicated string.
/// On failure, returns NULL with errno indicating the cause.
char *strdup(const char *s);
/// @brief Make a copy of at most n bytes of the given string.
/// @param s String to duplicate.
/// @param n The number of character to duplicate.
/// @return On success, returns a pointer to the duplicated string.
/// On failure, returns NULL with errno indicating the cause.
char *strndup(const char *s, size_t n);
/// @brief Appends a copy of the string src to the string dst.
/// @param dst Pointer to the destination array, which should be large enough
/// to contain the concatenated resulting string.
/// @param src String to be appended. This should not overlap dst.
/// @return destination is returned.
char *strcat(char *dst, const char *src);
/// @brief Appends a copy of the string src to the string dst, up to n bytes.
/// @param dst Pointer to the destination array, which should be large enough
/// to contain the concatenated resulting string.
/// @param src String to be appended. This should not overlap dst.
/// @param n The number of bytes to copy.
/// @return destination is returned.
char *strncat(char *dst, const char *src, size_t n);
/// @brief Fill the string s with the character c.
/// @param s The string that you want to fill.
/// @param c The character that you want to fill the string with.
/// @return The address of the string, s.
char *strset(char *s, int c);
/// @brief Fill the string s with the character c, up to the given length n.
/// @param s The string that you want to fill.
/// @param c The character that you want to fill the string with.
/// @param n The maximum number of bytes to fill.
/// @return The address of the string, s.
char *strnset(char *s, int c, size_t n);
/// @brief Reverse the string s.
/// @param s The given string which is needed to be reversed.
/// @return The address of the string, s.
char *strrev(char *s);
/// @brief Splits string into tokens.
/// @param str String to truncate.
/// @param delim String containing the delimiter characters.
/// @return If a token is found, a pointer to the beginning of the token.
/// Otherwise, a null pointer.
/// @details
/// Notice that str is modified by being broken into smaller strings (tokens).
/// A null pointer may be specified, in which case the function continues
/// scanning where a previous successful call to the function ended.
char *strtok(char *str, const char *delim);
/// @brief This function is a reentrant version strtok().
/// @param str String to truncate.
/// @param delim String containing the delimiter characters.
/// @param saveptr Pointer used internally to maintain context between calls.
/// @return
/// @details
/// The saveptr argument is a pointer to a char * variable that is used
/// internally by strtok_r() in order to maintain context between successive
/// calls that parse the same string.
/// On the first call to strtok_r(), str should point to the string to be
/// parsed, and the value of saveptr is ignored. In subsequent calls, str
/// should be NULL, and saveptr should be unchanged since the previous call.
char *strtok_r(char *str, const char *delim, char **saveptr);
/// @brief Copies the values of num bytes from the location pointed by source
/// to the memory block pointed by destination.
/// @param dst Pointer to the destination array where the content is to be
/// copied, type-casted to a pointer of type void*.
/// @param src Pointer to the source of data to be copied, type-casted to
/// a pointer of type const void*.
/// @param n Number of bytes to copy.
/// @return A pointer to dst is returned.
void *memmove(void *dst, const void *src, size_t n);
/// @brief Searches for the first occurrence of the character c (an unsigned
/// char) in the first n bytes of the string pointed to, by the
/// argument str.
/// @param ptr Pointer to the block of memory where the search is performed.
/// @param c Value to be located.
/// @param n Number of bytes to be analyzed.
/// @return A pointer to the first occurrence of value in the block of memory.
void *memchr(const void *ptr, int c, size_t n);
/// @brief Converts a given string into lowercase.
/// @param s String which we want to convert into lowercase.
/// @return A pointer to s.
char *strlwr(char *s);
/// @brief Converts a given string into uppercase.
/// @param s String which we want to convert into uppercase.
/// @return A pointer to s.
char *strupr(char *s);
/// @brief The memccpy function copies no more than n bytes from memory
/// area src to memory area dest, stopping when the character c is
/// found.
/// @param dst Points to the destination memory area.
/// @param src Points to the source memory area.
/// @param c The delimiter used to stop.
/// @param n The maximum number of copied bytes.
/// @return A pointer to the next character in dst after c, or NULL if c
/// was not found in the first n characters of src.
void *memccpy(void *dst, const void *src, int c, size_t n);
/// @brief Copy a block of memory, handling overlap.
/// @param dst Pointer to the destination.
/// @param src Pointer to the source.
/// @param num Number of bytes to be copied.
/// @return Pointer to the destination.
void *memcpy(void *dst, const void *src, size_t num);
/// @brief Compares the first n bytes of str1 and str2.
/// @param ptr1 First pointer to block of memory.
/// @param ptr2 Second pointer to block of memory.
/// @param n Number of bytes to compare.
/// @return
/// Returns an integral value indicating the relationship between
/// the memory blocks:
/// <0 the first byte that does not match has a lower
/// value in ptr1 than in ptr2
/// 0 the contents of both memory blocks are equal
/// >0 the first byte that does not match has a greater
/// value in ptr1 than in ptr2
int memcmp(const void *ptr1, const void *ptr2, size_t n);
/// @brief Sets the first num bytes of the block of memory pointed by ptr
/// to the specified value.
/// @param ptr Pointer to the block of memory to set.
/// @param value Value to be set.
/// @param num Number of bytes to be set to the given value.
/// @return The same ptr.
void *memset(void *ptr, int value, size_t num);
/// @brief Copy the string src into the array dst.
/// @param dst The destination array where the content is to be copied.
/// @param src String to be copied.
/// @return A pointer to dst is returned.
char *strcpy(char *dst, const char *src);
/// @brief Checks if the two strings are equal.
/// @param s1 First string to be compared.
/// @param s2 Second string to be compared.
/// @return
/// Returns an integral value indicating the relationship between the strings:
/// <0 the first character that does not match has a lower
/// value in s1 than in s2
/// 0 the contents of both strings are equal
/// >0 the first character that does not match has a greater
/// value in s1 than in s2
int strcmp(const char *s1, const char *s2);
/// @brief Returns the length of the string s.
/// @param s Pointer to the null-terminated byte string to be examined.
/// @return The length of the null-terminated string str.
size_t strlen(const char *s);
/// @brief Returns the number of characters inside s, excluding the
/// terminating null byte ('\0'), but at most count.
/// @param s Pointer to the null-terminated byte string to be examined.
/// @param maxlen The upperbound on the length.
/// @return Returns strlen(s), if that is less than maxlen, or maxlen
/// if there is no null terminating ('\0') among the first maxlen
/// characters pointed to by s.
size_t strnlen(const char *s, size_t maxlen);
/// @brief Removes any whitespace characters from the beginning and end of str.
/// @param str The string to trim.
/// @return A pointer to str.
char *trim(char *str);
/// @brief Separate the given string based on a given delimiter.
/// @param stringp The string to separate.
/// @param delim The delimiter used to separate the string.
/// @return Returns a pointer to stringp.
/// @details
/// Finds the first token in stringp, that is delimited by one of the bytes in
/// the string delim. This token is terminated by overwriting the delimiter
/// with a null byte ('\0'), and *stringp is updated to point past the token.
/// In case no delimiter was found, the token is taken to be the entire string
/// *stringp, and *stringp is made NULL.
char *strsep(char **stringp, const char *delim);
/// @brief Move the number "num" into a string.
/// @param buffer The string containing the number.
/// @param num The number to convert.
/// @param base The base used to convert.
/// @return A pointer to buffer.
char *itoa(char *buffer, unsigned int num, unsigned int base);
/// @brief Replaces the occurrences of find with replace inside str.
/// @param str The string to manipulate.
/// @param find The character to replace.
/// @param replace The character used to replace.
/// @return A pointer to str.
char *replace_char(char *str, char find, char replace);
/// @brief Converts a file mode (the type and permission information associated
/// with an inode) into a symbolic string which is stored in the location
/// referenced by p.
/// @param mode File mode that encodes access permissions and file type.
/// @param p Buffer used to hold the string representation of file mode m.
void strmode(mode_t mode, char *p);
+41
View File
@@ -0,0 +1,41 @@
/// MentOS, The Mentoring Operating system project
/// @file bitops.h
/// @brief Bitmasks functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#define bit_set(V, B) ((V) | (1U << (B))) ///< Sets the given bit.
#define bit_clear(V, B) ((V) & ~(1U << (B))) ///< Clears the given bit.
#define bit_flip(V, B) ((V) ^ (1U << (B))) ///< Flips the given bit.
#define bit_set_assign(V, B) ((V) |= (1U << (B))) ///< Sets the given bit, permanently.
#define bit_clear_assign(V, B) ((V) &= ~(1U << (B))) ///< Clears the given bit, permanently.
#define bit_flip_assign(V, B) ((V) ^= (1U << (B))) ///< Flips the given bit, permanently.
#define bit_check(V, B) ((V) & (1U << (B))) ///< Checks if the given bit is 1.
#define bitmask_set(V, M) ((V) | (M)) ///< Sets the bits identified by the mask.
#define bitmask_clear(V, M) ((V) & ~(M)) ///< Clears the bits identified by the mask.
#define bitmask_flip(V, M) ((V) ^ (M)) ///< Flips the bits identified by the mask.
#define bitmask_set_assign(V, M) ((V) |= (M)) ///< Sets the bits identified by the mask, permanently.
#define bitmask_clear_assign(V, M) ((V) &= ~(M)) ///< Clears the bits identified by the mask, permanently.
#define bitmask_flip_assign(V, M) ((V) ^= (M)) ///< Flips the bits identified by the mask, permanently.
#define bitmask_check(V, M) ((V) & (M)) ///< Checks if the bits identified by the mask are all 1.
/// @brief Finds the first bit at zero, starting from the less significative bit.
static inline int find_first_zero(unsigned long value)
{
for (int i = 0; i < 32; ++i)
if (!bit_check(value, i))
return i;
return 0;
}
/// @brief Finds the first bit not zero, starting from the less significative bit.
static inline int find_first_non_zero(unsigned long value)
{
for (int i = 0; i < 32; ++i)
if (bit_check(value, i))
return i;
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
/// MentOS, The Mentoring Operating system project
/// @file dirent.h
/// @brief Functions used to manage directories.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "limits.h"
#include "stddef.h"
/// File types for `d_type'.
enum {
DT_UNKNOWN = 0,
DT_FIFO = 1,
DT_CHR = 2,
DT_DIR = 4,
DT_BLK = 6,
DT_REG = 8,
DT_LNK = 10,
DT_SOCK = 12,
DT_WHT = 14
};
static const char dt_char_array[] = {
'?', // DT_UNKNOWN = 0,
'p', //DT_FIFO = 1,
'c', //DT_CHR = 2,
'*',
'd', //DT_DIR = 4,
'*',
'b', //DT_BLK = 6,
'*',
'-', //DT_REG = 8,
'*',
'l', //DT_LNK = 10,
'*',
's', //DT_SOCK = 12,
'*',
'?', //DT_WHT = 14
};
/// Directory entry.
typedef struct dirent_t {
ino_t d_ino; ///< Inode number.
off_t d_off; ///< Offset to next linux_dirent.
unsigned short d_reclen; ///< Length of this linux_dirent.
unsigned short d_type; ///< type of the directory entry.
char d_name[NAME_MAX]; ///< Filename (null-terminated)
} dirent_t;
+138
View File
@@ -0,0 +1,138 @@
/// MentOS, The Mentoring Operating system project
/// @file errno.h
/// @brief System call errors definition.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
extern int *__geterrno();
/// Provide easy access to the error number.
#define errno (*__geterrno())
#define EPERM 1 ///< Operation not permitted.
#define ENOENT 2 ///< No such file or directory.
#define ESRCH 3 ///< No such process.
#define EINTR 4 ///< Interrupted system call.
#define EIO 5 ///< I/O error.
#define ENXIO 6 ///< No such device or address.
#define E2BIG 7 ///< Arg list too long.
#define ENOEXEC 8 ///< Exec format error.
#define EBADF 9 ///< Bad file number.
#define ECHILD 10 ///< No child processes.
#define EAGAIN 11 ///< Try again.
#define ENOMEM 12 ///< Out of memory.
#define EACCES 13 ///< Permission denied.
#define EFAULT 14 ///< Bad address.
#define ENOTBLK 15 ///< Block device required.
#define EBUSY 16 ///< Device or resource busy.
#define EEXIST 17 ///< File exists.
#define EXDEV 18 ///< Cross-device link.
#define ENODEV 19 ///< No such device.
#define ENOTDIR 20 ///< Not a directory.
#define EISDIR 21 ///< Is a directory.
#define EINVAL 22 ///< Invalid argument.
#define ENFILE 23 ///< File table overflow.
#define EMFILE 24 ///< Too many open files.
#define ENOTTY 25 ///< Not a typewriter.
#define ETXTBSY 26 ///< Text file busy.
#define EFBIG 27 ///< File too large.
#define ENOSPC 28 ///< No space left on device.
#define ESPIPE 29 ///< Illegal seek.
#define EROFS 30 ///< Read-only file system.
#define EMLINK 31 ///< Too many links.
#define EPIPE 32 ///< Broken pipe.
#define EDOM 33 ///< Math argument out of domain of func.
#define ERANGE 34 ///< Math result not representable.
#define EDEADLK 35 ///< Resource deadlock would occur.
#define ENAMETOOLONG 36 ///< File name too long.
#define ENOLCK 37 ///< No record locks available.
#define ENOSYS 38 ///< Function not implemented.
#define ENOTEMPTY 39 ///< Directory not empty.
#define ELOOP 40 ///< Too many symbolic links encountered.
#define EWOULDBLOCK EAGAIN ///< Operation would block.
#define ENOMSG 42 ///< No message of desired type.
#define EIDRM 43 ///< Identifier removed.
#define ECHRNG 44 ///< Channel number out of range.
#define EL2NSYNC 45 ///< Level 2 not synchronized.
#define EL3HLT 46 ///< Level 3 halted.
#define EL3RST 47 ///< Level 3 reset.
#define ELNRNG 48 ///< Link number out of range.
#define EUNATCH 49 ///< Protocol driver not attached.
#define ENOCSI 50 ///< No CSI structure available.
#define EL2HLT 51 ///< Level 2 halted.
#define EBADE 52 ///< Invalid exchange.
#define EBADR 53 ///< Invalid request descriptor.
#define EXFULL 54 ///< Exchange full.
#define ENOANO 55 ///< No anode.
#define EBADRQC 56 ///< Invalid request code.
#define EBADSLT 57 ///< Invalid slot.
#define EDEADLOCK EDEADLK ///< Resource deadlock would occur.
#define EBFONT 59 ///< Bad font file format.
#define ENOSTR 60 ///< Device not a stream.
#define ENODATA 61 ///< No data available.
#define ETIME 62 ///< Timer expired.
#define ENOSR 63 ///< Out of streams resources.
#define ENONET 64 ///< Machine is not on the network.
#define ENOPKG 65 ///< Package not installed.
#define EREMOTE 66 ///< Object is remote.
#define ENOLINK 67 ///< Link has been severed.
#define EADV 68 ///< Advertise error.
#define ESRMNT 69 ///< Srmount error.
#define ECOMM 70 ///< Communication error on send.
#define EPROTO 71 ///< Protocol error.
#define EMULTIHOP 72 ///< Multihop attempted.
#define EDOTDOT 73 ///< RFS specific error.
#define EBADMSG 74 ///< Not a data message.
#define EOVERFLOW 75 ///< Value too large for defined data type.
#define ENOTUNIQ 76 ///< Name not unique on network.
#define EBADFD 77 ///< File descriptor in bad state.
#define EREMCHG 78 ///< Remote address changed.
#define ELIBACC 79 ///< Can not access a needed shared library.
#define ELIBBAD 80 ///< Accessing a corrupted shared library.
#define ELIBSCN 81 ///< .lib section in a.out corrupted.
#define ELIBMAX 82 ///< Attempting to link in too many shared libraries.
#define ELIBEXEC 83 ///< Cannot exec a shared library directly.
#define EILSEQ 84 ///< Illegal byte sequence.
#define ERESTART 85 ///< Interrupted system call should be restarted.
#define ESTRPIPE 86 ///< Streams pipe error.
#define EUSERS 87 ///< Too many users.
#define ENOTSOCK 88 ///< Socket operation on non-socket.
#define EDESTADDRREQ 89 ///< Destination address required.
#define EMSGSIZE 90 ///< Message too long.
#define EPROTOTYPE 91 ///< Protocol wrong type for socket.
#define ENOPROTOOPT 92 ///< Protocol not available.
#define EPROTONOSUPPORT 93 ///< Protocol not supported.
#define ESOCKTNOSUPPORT 94 ///< Socket type not supported.
#define EOPNOTSUPP 95 ///< Operation not supported on transport endpoint.
#define EPFNOSUPPORT 96 ///< Protocol family not supported.
#define EAFNOSUPPORT 97 ///< Address family not supported by protocol.
#define EADDRINUSE 98 ///< Address already in use.
#define EADDRNOTAVAIL 99 ///< Cannot assign requested address.
#define ENETDOWN 100 ///< Network is down.
#define ENETUNREACH 101 ///< Network is unreachable.
#define ENETRESET 102 ///< Network dropped connection because of reset.
#define ECONNABORTED 103 ///< Software caused connection abort.
#define ECONNRESET 104 ///< Connection reset by peer.
#define ENOBUFS 105 ///< No buffer space available.
#define EISCONN 106 ///< Transport endpoint is already connected.
#define ENOTCONN 107 ///< Transport endpoint is not connected.
#define ESHUTDOWN 108 ///< Cannot send after transport endpoint shutdown.
#define ETOOMANYREFS 109 ///< Too many references: cannot splice.
#define ETIMEDOUT 110 ///< Connection timed out.
#define ECONNREFUSED 111 ///< Connection refused.
#define EHOSTDOWN 112 ///< Host is down.
#define EHOSTUNREACH 113 ///< No route to host.
#define EALREADY 114 ///< Operation already in progress.
#define EINPROGRESS 115 ///< Operation now in progress.
#define ESTALE 116 ///< Stale NFS file handle.
#define EUCLEAN 117 ///< Structure needs cleaning.
#define ENOTNAM 118 ///< Not a XENIX named type file.
#define ENAVAIL 119 ///< No XENIX semaphores available.
#define EISNAM 120 ///< Is a named type file.
#define EREMOTEIO 121 ///< Remote I/O error.
#define EDQUOT 122 ///< Quota exceeded.
#define ENOMEDIUM 123 ///< No medium found.
#define EMEDIUMTYPE 124 ///< Wrong medium type.
#define ENOTSCHEDULABLE 125 ///< The periodc process cannot be scheduled.
+15
View File
@@ -0,0 +1,15 @@
/// MentOS, The Mentoring Operating system project
/// @file ioctl.h
/// @brief Input/Output ConTroL (IOCTL) functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Perform the I/O control operation specified by REQUEST on FD.
/// One argument may follow; its presence and type depend on REQUEST.
/// @param fd Must be an open file descriptor.
/// @param request The device-dependent request code
/// @param data An untyped pointer to memory.
/// @return Return value depends on REQUEST. Usually -1 indicates error.
int ioctl(int fd, unsigned long int request, void *data);
+36
View File
@@ -0,0 +1,36 @@
/// MentOS, The Mentoring Operating system project
/// @file reboot.h
/// @brief Defines the values required to issue a reboot.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC1 0xfee1dead
/// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC2 672274793
/// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC2A 85072278
/// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC2B 369367448
/// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC2C 537993216
// Commands accepted by the _reboot() system call.
/// Restart system using default command and mode.
#define LINUX_REBOOT_CMD_RESTART 0x01234567
/// Stop OS and give system control to ROM monitor, if any.
#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
/// Ctrl-Alt-Del sequence causes RESTART command.
#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
/// Ctrl-Alt-Del sequence sends SIGINT to init task.
#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
/// Stop OS and remove all power from system, if possible.
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
/// Restart system using given command string.
#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
/// Suspend system using software suspend if compiled in.
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
/// Restart system using a previously loaded Linux kernel
#define LINUX_REBOOT_CMD_KEXEC 0x45584543
+35
View File
@@ -0,0 +1,35 @@
/// MentOS, The Mentoring Operating system project
/// @file stat.h
/// @brief Stat functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#define __SYS_STAT_H
#include "bits/stat.h"
#include "stddef.h"
#include "time.h"
/// @brief Retrieves information about the file at the given location.
/// @param path The path to the file that is being inquired.
/// @param buf A structure where data about the file will be stored.
/// @return Returns a negative value on failure.
int stat(const char *path, stat_t *buf);
/// @brief Retrieves information about the file at the given location.
/// @param fd The file descriptor of the file that is being inquired.
/// @param buf A structure where data about the file will be stored.
/// @return Returns a negative value on failure.
int fstat(int fd, stat_t *buf);
/// @brief Creates a new directory at the given path.
/// @param path The path of the new directory.
/// @param mode The permission of the new directory.
/// @return Returns a negative value on failure.
int mkdir(const char *path, mode_t mode);
/// @brief Removes the given directory.
/// @param path The path to the directory to remove.
/// @return Returns a negative value on failure.
int rmdir(const char *path);
+70
View File
@@ -0,0 +1,70 @@
/// MentOS, The Mentoring Operating system project
/// @file types.h
/// @brief Collection of Kernel datatype
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// The type of process id.
typedef signed int pid_t;
/// The type of process user variable.
typedef unsigned int user_t;
/// The type of process status.
typedef unsigned int status_t;
/// Type for system keys.
typedef int key_t;
/// Defines the list of flags of a process.
typedef enum eflags_list {
/// Carry flag.
EFLAG_CF = (1 << 0),
/// Parity flag.
EFLAG_PF = (1 << 2),
/// Auxiliary carry flag.
EFLAG_AF = (1 << 4),
/// Zero flag.
EFLAG_ZF = (1 << 6),
/// Sign flag.
EFLAG_SF = (1 << 7),
/// Trap flag.
EFLAG_TF = (1 << 8),
/// Interrupt enable flag.
EFLAG_IF = (1 << 9),
/// Direction flag.
EFLAG_DF = (1 << 10),
/// Overflow flag.
EFLAG_OF = (1 << 11),
/// Nested task flag.
EFLAG_NT = (1 << 14),
/// Resume flag.
EFLAG_RF = (1 << 16),
/// Virtual 8086 mode flag.
EFLAG_VM = (1 << 17),
/// Alignment check flag (486+).
EFLAG_AC = (1 << 18),
/// Virutal interrupt flag.
EFLAG_VIF = (1 << 19),
/// Virtual interrupt pending flag.
EFLAG_VIP = (1 << 20),
/// ID flag.
EFLAG_ID = (1 << 21),
} eflags_list;
+223
View File
@@ -0,0 +1,223 @@
/// MentOS, The Mentoring Operating system project
/// @file unistd.h
/// @brief Functions used to manage files.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "sys/types.h"
#include "sys/dirent.h"
#include "stddef.h"
#define STDIN_FILENO 0 ///< Standard input.
#define STDOUT_FILENO 1 ///< Standard output.
#define STDERR_FILENO 2 ///< Standard error output.
/// @brief Read data from a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer.
/// @param nbytes The number of bytes to read.
/// @return The number of read characters.
ssize_t read(int fd, void *buf, size_t nbytes);
/// @brief Write data into a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer collecting data to written.
/// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t write(int fd, void *buf, size_t nbytes);
/// @brief Opens the file specified by pathname.
/// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer for
/// use in subsequent system calls.
int open(const char *pathname, int flags, mode_t mode);
/// @brief Close a file descriptor.
/// @param fd The file descriptor.
/// @return The result of the operation.
int close(int fd);
/// @brief Repositions the file offset inside a file.
/// @param fd The file descriptor of the file.
/// @param offset The offest to use for the operation.
/// @param whence The type of operation.
/// @return Upon successful completion, returns the resulting offset
/// location as measured in bytes from the beginning of the file. On
/// error, the value (off_t) -1 is returned and errno is set to
/// indicate the error.
off_t lseek(int fd, off_t offset, int whence);
/// @brief Delete a name and possibly the file it refers to.
/// @param path The path to the file.
/// @return
int unlink(const char *path);
/// @brief Wrapper for exit system call.
/// @param status The exit status.
extern void exit(int status);
/// @brief Returns the process ID (PID) of the calling process.
/// @return pid_t process identifier.
extern pid_t getpid();
///@brief Return session id of the given process.
/// If pid == 0 return the SID of the calling process
/// If pid != 0 return the SID corresponding to the process having identifier == pid
///@param pid process identifier from wich we want the SID
///@return On success return SID of the session
/// Otherwise return -1 with errno set on: EPERM or ESRCH
extern pid_t getsid(pid_t pid);
///@brief creates a new session if the calling process is not a
/// process group leader. The calling process is the leader of the
/// new session (i.e., its session ID is made the same as its process
/// ID). The calling process also becomes the process group leader
/// of a new process group in the session (i.e., its process group ID
/// is made the same as its process ID).
///@return On success return SID of the session just created
/// Otherwise return -1 with errno : EPERM
extern pid_t setsid();
///@brief returns the group ID of the calling process.
///@return GID of the current process
extern pid_t getgid();
///@brief sets the effective group ID of the calling process.
///@param pid process identifier to
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to :EINVAL or EPERM
extern int setgid(pid_t pid);
/// @brief Returns the parent process ID (PPID) of the calling process.
/// @return pid_t parent process identifier.
extern pid_t getppid();
/// @brief Clone the calling process, but without copying the whole address space.
/// The calling process is suspended until the new process exits or is
/// replaced by a call to `execve'.
/// @return Return -1 for errors, 0 to the new process, and the process ID of
/// the new process to the old process.
extern pid_t fork();
/// @brief Replaces the current process image with a new process image (argument list).
/// @param path The absolute path to the binary file to execute.
/// @param arg A list of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @param ... The argument list.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execl(const char *path, const char *arg, ...);
/// @brief Replaces the current process image with a new process image (argument list).
/// @param file The name of the binary file to execute, which is searched inside the
/// paths specified inside the PATH environmental variable.
/// @param arg A list of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @param ... The argument list.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execlp(const char *file, const char *arg, ...);
/// @brief Replaces the current process image with a new process image (argument list).
/// @param path The absolute path to the binary file to execute.
/// @param arg A list of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @param ... The argument list which contains as last argument the environment.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execle(const char *path, const char *arg, ...);
/// @brief Replaces the current process image with a new process image (argument list).
/// @param file The name of the binary file to execute, which is searched inside the
/// paths specified inside the PATH environmental variable.
/// @param arg A list of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @param ... The argument list which contains as last argument the environment.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execlpe(const char *file, const char *arg, ...);
/// @brief Replaces the current process image with a new process image (argument vector).
/// @param path The absolute path to the binary file to execute.
/// @param argv A vector of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execv(const char *path, char *const argv[]);
/// @brief Replaces the current process image with a new process image (argument vector).
/// @param file The name of the binary file to execute, which is searched inside the
/// paths specified inside the PATH environmental variable.
/// @param argv A vector of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execvp(const char *file, char *const argv[]);
/// @brief Replaces the current process image with a new process
/// image (argument vector), allows the caller to specify
/// the environment of the executed program via `envp`.
/// @param path The absolute path to the binary file to execute.
/// @param argv A vector of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @param envp A vector of one or more pointers to null-terminated strings that represent
/// the environment list available to the executed program.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execve(const char *path, char *const argv[], char *const envp[]);
/// @brief Replaces the current process image with a new process
/// image (argument vector), allows the caller to specify
/// the environment of the executed program via `envp`.
/// @param file The name of the binary file to execute, which is searched inside the
/// paths specified inside the PATH environmental variable.
/// @param argv A vector of one or more pointers to null-terminated strings that represent
/// the argument list available to the executed program.
/// @param envp A vector of one or more pointers to null-terminated strings that represent
/// the environment list available to the executed program.
/// @return Returns -1 only if an error has occurred, and sets errno.
int execvpe(const char *file, char *const argv[], char *const envp[]);
/// @brief Adds inc to the nice value for the calling thread.
/// @param inc The value to add to the nice.
/// @return On success, the new nice value is returned. On error, -1 is
/// returned, and errno is set appropriately.
int nice(int inc);
/// @brief Reboots the system, or enables/disables the reboot keystroke.
/// @param magic1 fails (with the error EINVAL) unless equals LINUX_REBOOT_MAGIC1.
/// @param magic2 fails (with the error EINVAL) unless equals LINUX_REBOOT_MAGIC2.
/// @param cmd The command to send to the reboot.
/// @param arg Argument passed with some specific commands.
/// @return For the values of cmd that stop or restart the system, a
/// successful call to reboot() does not return. For the other cmd
/// values, zero is returned on success. In all cases, -1 is
/// returned on failure, and errno is set appropriately.
int reboot(int magic1, int magic2, unsigned int cmd, void *arg);
/// @brief Get current working directory.
/// @param buf The array where the CWD will be copied.
/// @param size The size of the array.
/// @return On success, returns the same pointer to buf.
/// On failure, returnr NULL, and errno is set to indicate the error.
char *getcwd(char *buf, size_t size);
/// @brief Changes the current working directory to the given path.
/// @param path The new current working directory.
int chdir(char const *path);
/// @brief Is identical to chdir(), the only difference is that the
/// directory is given as an open file descriptor.
/// @param fd The file descriptor of the open directory.
int fchdir(int fd);
/// Provide access to the directory entries.
/// @param fd The fd pointing to the opened directory.
/// @param dirp The buffer where de data should be placed.
/// @param count The size of the buffer.
/// @return On success, the number of bytes read is returned. On end of
/// directory, 0 is returned. On error, -1 is returned, and errno is set
/// appropriately.
int getdents(int fd, dirent_t *dirp, unsigned int count);
/// @brief Send signal to calling thread after desired seconds.
int alarm(int seconds);
+30
View File
@@ -0,0 +1,30 @@
/// MentOS, The Mentoring Operating system project
/// @file utsname.h
/// @brief Functions used to provide information about the machine & OS.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Maximum length of the string used by utsname.
#define SYS_LEN 257
/// @brief Holds information concerning the machine and the os.
typedef struct utsname_t {
/// The name of the system.
char sysname[SYS_LEN];
/// The name of the node.
char nodename[SYS_LEN];
/// Operating system release (e.g., "2.6.28").
char release[SYS_LEN];
/// The version of the OS.
char version[SYS_LEN];
/// The name of the machine.
char machine[SYS_LEN];
} utsname_t;
/// @brief Returns system information in the structure pointed to by buf.
/// @param buf Buffer where the info will be placed.
/// @return 0 on success, a negative value on failure.
int uname(utsname_t* buf);
+22 -5
View File
@@ -1,13 +1,11 @@
/// MentOS, The Mentoring Operating system project
/// @file wait.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// @brief Event management functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "types.h"
/// @brief Return immediately if no child is there to be waited for.
#define WNOHANG 0x00000001
@@ -43,10 +41,30 @@
/// This macro can only be evaluated if WIFSTOPPED() returned nonzero.
#define WSTOPSIG(status) (WEXITSTATUS(status))
//==== Task States ============================================================
#define TASK_RUNNING 0x00 ///< The process is either: 1) running on CPU or 2) waiting in a run queue.
#define TASK_INTERRUPTIBLE (1 << 0) ///< The process is sleeping, waiting for some event to occur.
#define TASK_UNINTERRUPTIBLE (1 << 1) ///< Similar to TASK_INTERRUPTIBLE, but it doesn't process signals.
#define TASK_STOPPED (1 << 2) ///< Stopped, it's not running, and not able to run.
#define TASK_TRACED (1 << 3) ///< Is being monitored by other processes such as debuggers.
#define EXIT_ZOMBIE (1 << 4) ///< The process has terminated.
#define EXIT_DEAD (1 << 5) ///< The final state.
//==============================================================================
/// @brief Suspends the execution of the calling thread until ANY child has
/// changed state.
/// @param status Variable where the new status of the child is stored.
/// @return On error, -1 is returned, otherwise it returns the pid of the
/// child that has unlocked the wait.
extern pid_t wait(int *status);
/// @brief Suspends the execution of the calling thread until a child
/// specified by pid argument has changed state.
/// @param pid Se details below for more information.
/// @param status Variable where the new status of the child is stored.
/// @param options Waitpid options.
/// @return On error, -1 is returned, otherwise it returns the pid of the
/// child that has unlocked the wait.
/// @details
/// By default, waitpid() waits only for terminated children, but this
/// behavior is modifiable via the options argument, as described below.
@@ -56,5 +74,4 @@ extern pid_t wait(int *status);
/// equal to that of the calling process.
/// > 0 meaning wait for the child whose process ID is equal to the
/// value of pid.
/// @return On error, -1 is returned.
extern pid_t waitpid(pid_t pid, int *status, int options);
+308
View File
@@ -0,0 +1,308 @@
/// MentOS, The Mentoring Operating system project
/// @file syscall_types.h
/// @brief System Call numbers.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#define __NR_exit 1 ///< System-call number for `exit`
#define __NR_fork 2 ///< System-call number for `fork`
#define __NR_read 3 ///< System-call number for `read`
#define __NR_write 4 ///< System-call number for `write`
#define __NR_open 5 ///< System-call number for `open`
#define __NR_close 6 ///< System-call number for `close`
#define __NR_waitpid 7 ///< System-call number for `waitpid`
#define __NR_creat 8 ///< System-call number for `creat`
#define __NR_link 9 ///< System-call number for `link`
#define __NR_unlink 10 ///< System-call number for `unlink`
#define __NR_execve 11 ///< System-call number for `execve`
#define __NR_chdir 12 ///< System-call number for `chdir`
#define __NR_time 13 ///< System-call number for `time`
#define __NR_mknod 14 ///< System-call number for `mknod`
#define __NR_chmod 15 ///< System-call number for `chmod`
#define __NR_lchown 16 ///< System-call number for `lchown`
#define __NR_stat 18 ///< System-call number for `stat`
#define __NR_lseek 19 ///< System-call number for `lseek`
#define __NR_getpid 20 ///< System-call number for `getpid`
#define __NR_mount 21 ///< System-call number for `mount`
#define __NR_oldumount 22 ///< System-call number for `oldumount`
#define __NR_setuid 23 ///< System-call number for `setuid`
#define __NR_getuid 24 ///< System-call number for `getuid`
#define __NR_stime 25 ///< System-call number for `stime`
#define __NR_ptrace 26 ///< System-call number for `ptrace`
#define __NR_alarm 27 ///< System-call number for `alarm`
#define __NR_fstat 28 ///< System-call number for `fstat`
#define __NR_pause 29 ///< System-call number for `pause`
#define __NR_utime 30 ///< System-call number for `utime`
#define __NR_access 33 ///< System-call number for `access`
#define __NR_nice 34 ///< System-call number for `nice`
#define __NR_sync 36 ///< System-call number for `sync`
#define __NR_kill 37 ///< System-call number for `kill`
#define __NR_rename 38 ///< System-call number for `rename`
#define __NR_mkdir 39 ///< System-call number for `mkdir`
#define __NR_rmdir 40 ///< System-call number for `rmdir`
#define __NR_dup 41 ///< System-call number for `dup`
#define __NR_pipe 42 ///< System-call number for `pipe`
#define __NR_times 43 ///< System-call number for `times`
#define __NR_brk 45 ///< System-call number for `brk`
#define __NR_setgid 46 ///< System-call number for `setgid`
#define __NR_getgid 47 ///< System-call number for `getgid`
#define __NR_signal 48 ///< System-call number for `signal`
#define __NR_geteuid 49 ///< System-call number for `geteuid`
#define __NR_getegid 50 ///< System-call number for `getegid`
#define __NR_acct 51 ///< System-call number for `acct`
#define __NR_umount 52 ///< System-call number for `umount`
#define __NR_ioctl 54 ///< System-call number for `ioctl`
#define __NR_fcntl 55 ///< System-call number for `fcntl`
#define __NR_setpgid 57 ///< System-call number for `setpgid`
#define __NR_olduname 59 ///< System-call number for `olduname`
#define __NR_umask 60 ///< System-call number for `umask`
#define __NR_chroot 61 ///< System-call number for `chroot`
#define __NR_ustat 62 ///< System-call number for `ustat`
#define __NR_dup2 63 ///< System-call number for `dup2`
#define __NR_getppid 64 ///< System-call number for `getppid`
#define __NR_getpgrp 65 ///< System-call number for `getpgrp`
#define __NR_setsid 66 ///< System-call number for `setsid`
#define __NR_sigaction 67 ///< System-call number for `sigaction`
#define __NR_sgetmask 68 ///< System-call number for `sgetmask`
#define __NR_ssetmask 69 ///< System-call number for `ssetmask`
#define __NR_setreuid 70 ///< System-call number for `setreuid`
#define __NR_setregid 71 ///< System-call number for `setregid`
#define __NR_sigsuspend 72 ///< System-call number for `sigsuspend`
#define __NR_sigpending 73 ///< System-call number for `sigpending`
#define __NR_sethostname 74 ///< System-call number for `sethostname`
#define __NR_setrlimit 75 ///< System-call number for `setrlimit`
#define __NR_getrlimit 76 ///< System-call number for `getrlimit`
#define __NR_getrusage 77 ///< System-call number for `getrusage`
#define __NR_gettimeofday 78 ///< System-call number for `gettimeofday`
#define __NR_settimeofday 79 ///< System-call number for `settimeofday`
#define __NR_getgroups 80 ///< System-call number for `getgroups`
#define __NR_setgroups 81 ///< System-call number for `setgroups`
#define __NR_symlink 83 ///< System-call number for `symlink`
#define __NR_lstat 84 ///< System-call number for `lstat`
#define __NR_readlink 85 ///< System-call number for `readlink`
#define __NR_uselib 86 ///< System-call number for `uselib`
#define __NR_swapon 87 ///< System-call number for `swapon`
#define __NR_reboot 88 ///< System-call number for `reboot`
#define __NR_readdir 89 ///< System-call number for `readdir`
#define __NR_mmap 90 ///< System-call number for `mmap`
#define __NR_munmap 91 ///< System-call number for `munmap`
#define __NR_truncate 92 ///< System-call number for `truncate`
#define __NR_ftruncate 93 ///< System-call number for `ftruncate`
#define __NR_fchmod 94 ///< System-call number for `fchmod`
#define __NR_fchown 95 ///< System-call number for `fchown`
#define __NR_getpriority 96 ///< System-call number for `getpriority`
#define __NR_setpriority 97 ///< System-call number for `setpriority`
#define __NR_statfs 99 ///< System-call number for `statfs`
#define __NR_fstatfs 100 ///< System-call number for `fstatfs`
#define __NR_ioperm 101 ///< System-call number for `ioperm`
#define __NR_socketcall 102 ///< System-call number for `socketcall`
#define __NR_syslog 103 ///< System-call number for `syslog`
#define __NR_setitimer 104 ///< System-call number for `setitimer`
#define __NR_getitimer 105 ///< System-call number for `getitimer`
#define __NR_newstat 106 ///< System-call number for `newstat`
#define __NR_newlstat 107 ///< System-call number for `newlstat`
#define __NR_newfstat 108 ///< System-call number for `newfstat`
#define __NR_uname 109 ///< System-call number for `uname`
#define __NR_iopl 110 ///< System-call number for `iopl`
#define __NR_vhangup 111 ///< System-call number for `vhangup`
#define __NR_idle 112 ///< System-call number for `idle`
#define __NR_vm86old 113 ///< System-call number for `vm86old`
#define __NR_wait4 114 ///< System-call number for `wait4`
#define __NR_swapoff 115 ///< System-call number for `swapoff`
#define __NR_sysinfo 116 ///< System-call number for `sysinfo`
#define __NR_ipc 117 ///< System-call number for `ipc`
#define __NR_fsync 118 ///< System-call number for `fsync`
#define __NR_sigreturn 119 ///< System-call number for `sigreturn`
#define __NR_clone 120 ///< System-call number for `clone`
#define __NR_setdomainname 121 ///< System-call number for `setdomainname`
#define __NR_newuname 122 ///< System-call number for `newuname`
#define __NR_modify_ldt 123 ///< System-call number for `modify_ldt`
#define __NR_adjtimex 124 ///< System-call number for `adjtimex`
#define __NR_mprotect 125 ///< System-call number for `mprotect`
#define __NR_sigprocmask 126 ///< System-call number for `sigprocmask`
#define __NR_create_module 127 ///< System-call number for `create_module`
#define __NR_init_module 128 ///< System-call number for `init_module`
#define __NR_delete_module 129 ///< System-call number for `delete_module`
#define __NR_get_kernel_syms 130 ///< System-call number for `get_kernel_syms`
#define __NR_quotactl 131 ///< System-call number for `quotactl`
#define __NR_getpgid 132 ///< System-call number for `getpgid`
#define __NR_fchdir 133 ///< System-call number for `fchdir`
#define __NR_bdflush 134 ///< System-call number for `bdflush`
#define __NR_sysfs 135 ///< System-call number for `sysfs`
#define __NR_personality 136 ///< System-call number for `personality`
#define __NR_setfsuid 138 ///< System-call number for `setfsuid`
#define __NR_setfsgid 139 ///< System-call number for `setfsgid`
#define __NR_llseek 140 ///< System-call number for `llseek`
#define __NR_getdents 141 ///< System-call number for `getdents`
#define __NR_select 142 ///< System-call number for `select`
#define __NR_flock 143 ///< System-call number for `flock`
#define __NR_msync 144 ///< System-call number for `msync`
#define __NR_readv 145 ///< System-call number for `readv`
#define __NR_writev 146 ///< System-call number for `writev`
#define __NR_getsid 147 ///< System-call number for `getsid`
#define __NR_fdatasync 148 ///< System-call number for `fdatasync`
#define __NR_sysctl 149 ///< System-call number for `sysctl`
#define __NR_mlock 150 ///< System-call number for `mlock`
#define __NR_munlock 151 ///< System-call number for `munlock`
#define __NR_mlockall 152 ///< System-call number for `mlockall`
#define __NR_munlockall 153 ///< System-call number for `munlockall`
#define __NR_sched_setparam 154 ///< System-call number for `sched_setparam`
#define __NR_sched_getparam 155 ///< System-call number for `sched_getparam`
#define __NR_sched_setscheduler 156 ///< System-call number for `sched_setscheduler`
#define __NR_sched_getscheduler 157 ///< System-call number for `sched_getscheduler`
#define __NR_sched_yield 158 ///< System-call number for `sched_yield`
#define __NR_sched_get_priority_max 159 ///< System-call number for `sched_get_priority_max`
#define __NR_sched_get_priority_min 160 ///< System-call number for `sched_get_priority_min`
#define __NR_sched_rr_get_interval 161 ///< System-call number for `sched_rr_get_interval`
#define __NR_nanosleep 162 ///< System-call number for `nanosleep`
#define __NR_mremap 163 ///< System-call number for `mremap`
#define __NR_setresuid 164 ///< System-call number for `setresuid`
#define __NR_getresuid 165 ///< System-call number for `getresuid`
#define __NR_vm86 166 ///< System-call number for `vm86`
#define __NR_query_module 167 ///< System-call number for `query_module`
#define __NR_poll 168 ///< System-call number for `poll`
#define __NR_nfsservctl 169 ///< System-call number for `nfsservctl`
#define __NR_setresgid 170 ///< System-call number for `setresgid`
#define __NR_getresgid 171 ///< System-call number for `getresgid`
#define __NR_prctl 172 ///< System-call number for `prctl`
#define __NR_rt_sigreturn 173 ///< System-call number for `rt_sigreturn`
#define __NR_rt_sigaction 174 ///< System-call number for `rt_sigaction`
#define __NR_rt_sigprocmask 175 ///< System-call number for `rt_sigprocmask`
#define __NR_rt_sigpending 176 ///< System-call number for `rt_sigpending`
#define __NR_rt_sigtimedwait 177 ///< System-call number for `rt_sigtimedwait`
#define __NR_rt_sigqueueinfo 178 ///< System-call number for `rt_sigqueueinfo`
#define __NR_rt_sigsuspend 179 ///< System-call number for `rt_sigsuspend`
#define __NR_pread 180 ///< System-call number for `pread`
#define __NR_pwrite 181 ///< System-call number for `pwrite`
#define __NR_chown 182 ///< System-call number for `chown`
#define __NR_getcwd 183 ///< System-call number for `getcwd`
#define __NR_capget 184 ///< System-call number for `capget`
#define __NR_capset 185 ///< System-call number for `capset`
#define __NR_sigaltstack 186 ///< System-call number for `sigaltstack`
#define __NR_sendfile 187 ///< System-call number for `sendfile`
#define __NR_waitperiod 188 ///< System-call number for `waitperiod`
#define __NR_msgctl 189 ///< System-call number for `msgctl`
#define __NR_msgget 190 ///< System-call number for `msgget`
#define __NR_msgrcv 191 ///< System-call number for `msgrcv`
#define __NR_msgsnd 192 ///< System-call number for `msgsnd`
#define __NR_semctl 193 ///< System-call number for `semctl`
#define __NR_semget 194 ///< System-call number for `semget`
#define __NR_semop 195 ///< System-call number for `semop`
#define __NR_shmat 196 ///< System-call number for `shmat`
#define __NR_shmctl 197 ///< System-call number for `shmctl`
#define __NR_shmdt 198 ///< System-call number for `shmdt`
#define __NR_shmget 199 ///< System-call number for `shmget`
#define SYSCALL_NUMBER 200 ///< The total number of system-calls.
/// @brief Handle the value returned from a system call.
/// @param type Specifies the type of the returned value.
/// @param res The name of the variable where the result of the SC is stored.
#define __syscall_return(type, res) \
do { \
if ((unsigned int)(res) >= (unsigned int)(-125)) { \
errno = -(res); \
(res) = -1; \
} \
return (type)(res); \
} while (0)
/// @brief Heart of the code that calls a system call with 0 parameters.
#define __inline_syscall0(res, name) \
__asm__ __volatile__("int $0x80" \
: "=a"(res) \
: "0"(__NR_##name))
/// @brief Heart of the code that calls a system call with 1 parameter.
#define __inline_syscall1(res, name, arg1) \
__asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a"(res) \
: "0"(__NR_##name), "ri"((int)(arg1)) \
: "memory");
/// @brief Heart of the code that calls a system call with 2 parameters.
#define __inline_syscall2(res, name, arg1, arg2) \
__asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a"(res) \
: "0"(__NR_##name), "ri"((int)(arg1)), "c"((int)(arg2)) \
: "memory");
/// @brief Heart of the code that calls a system call with 3 parameters.
#define __inline_syscall3(res, name, arg1, arg2, arg3) \
__asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a"(res) \
: "0"(__NR_##name), "ri"((int)(arg1)), "c"((int)(arg2)), \
"d"((int)(arg3)) \
: "memory");
/// @brief Heart of the code that calls a system call with 4 parameters.
#define __inline_syscall4(res, name, arg1, arg2, arg3, arg4) \
__asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a"(res) \
: "0"(__NR_##name), "ri"((int)(arg1)), "c"((int)(arg2)), \
"d"((int)(arg3)), "S"((int)(arg4)) \
: "memory");
/// @brief Heart of the code that calls a system call with 5 parameters.
#define __inline_syscall5(res, name, arg1, arg2, arg3, arg4, arg5) \
__asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \
"int $0x80 ; pop %%ebx" \
: "=a"(res) \
: "i"(__NR_##name), "ri"((int)(arg1)), "c"((int)(arg2)), \
"d"((int)(arg3)), "S"((int)(arg4)), "D"((int)(arg5)) \
: "memory");
/// @brief System call with 0 parameters.
#define _syscall0(type, name) \
type name(void) \
{ \
long __res; \
__inline_syscall0(__res, name); \
__syscall_return(type, __res); \
}
/// @brief System call with 1 parameter.
#define _syscall1(type, name, type1, arg1) \
type name(type1 arg1) \
{ \
long __res; \
__inline_syscall1(__res, name, arg1); \
__syscall_return(type, __res); \
}
/// @brief System call with 2 parameters.
#define _syscall2(type, name, type1, arg1, type2, arg2) \
type name(type1 arg1, type2 arg2) \
{ \
long __res; \
__inline_syscall2(__res, name, arg1, arg2); \
__syscall_return(type, __res); \
}
/// @brief System call with 3 parameters.
#define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
type name(type1 arg1, type2 arg2, type3 arg3) \
{ \
long __res; \
__inline_syscall3(__res, name, arg1, arg2, arg3); \
__syscall_return(type, __res); \
}
/// @brief System call with 4 parameters.
#define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \
long __res; \
__inline_syscall4(__res, name, arg1, arg2, arg3, arg4); \
__syscall_return(type, __res); \
}
/// @brief System call with 5 parameters.
#define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
{ \
long __res; \
__inline_syscall5(__res, name, arg1, arg2, arg3, arg4, arg5); \
__syscall_return(type, __res); \
}
+22
View File
@@ -0,0 +1,22 @@
/// MentOS, The Mentoring Operating system project
/// @file termios.h
/// @brief Defines the termios functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "bits/termios-struct.h"
/// @brief Put the state of FD into *TERMIOS_P.
/// @param fd
/// @param termios_p
/// @return
extern int tcgetattr(int fd, termios *termios_p);
/// @brief Set the state of FD to *TERMIOS_P.
/// @param fd
/// @param optional_actions
/// @param termios_p
/// @return
extern int tcsetattr(int fd, int optional_actions, const termios *termios_p);
+110
View File
@@ -0,0 +1,110 @@
/// MentOS, The Mentoring Operating system project
/// @file time.h
/// @brief Time-related functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// Domains of interval timers
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
/// Used to store time values.
typedef unsigned int time_t;
/// Used to get information about the current time.
typedef struct tm_t {
/// Seconds [0 to 59]
int tm_sec;
/// Minutes [0 to 59]
int tm_min;
/// Hours [0 to 23]
int tm_hour;
/// Day of the month [1 to 31]
int tm_mday;
/// Month [0 to 11]
int tm_mon;
/// Year [since 1900]
int tm_year;
/// Day of the week [0 to 6]
int tm_wday;
/// Day in the year [0 to 365]
int tm_yday;
/// Is Daylight Saving Time.
int tm_isdst;
} tm_t;
/// Rappresents time
typedef struct _timeval {
time_t tv_sec; /* seconds */
time_t tv_usec; /* microseconds */
} timeval;
/// Rappresents a time interval
typedef struct _itimerval {
timeval it_interval; /* next value */
timeval it_value; /* current value */
} itimerval;
/// @brief Specify intervals of time with nanosecond precision.
typedef struct timespec {
time_t tv_sec; ///< Seconds.
long tv_nsec; ///< Nanoseconds.
} timespec;
/// @brief Returns the current time.
/// @param t Where the time should be stored.
/// @return The current time.
time_t time(time_t *t);
/// @brief Return the difference between the two time values.
/// @param time1 The first time value.
/// @param time2 The second time value.
/// @return The difference in terms of seconds.
time_t difftime(time_t time1, time_t time2);
/// @brief The current time broken down into a tm_t structure.
/// @param timep A pointer to a variable holding the current time.
/// @return The time broken down.
tm_t *localtime(const time_t *timep);
/// @brief Formats the time tm according to the format specification format
/// and places the result in the character array s of size max.
/// @param s The destination buffer.
/// @param max The maximum length of the buffer.
/// @param format The buffer used to generate the time.
/// @param tm The broken-down time.
/// @return The number of bytes (excluding the terminating null) placed in s.
size_t strftime(char *s, size_t max, const char *format, const tm_t *tm);
/// @brief Suspends the execution of the calling thread.
/// @param req The amount of time we want to sleep.
/// @param rem The remaining time we did not sleep.
/// @return If the call is interrupted by a signal handler, nanosleep()
/// returns -1, sets errno to EINTR, and writes the remaining time
/// into the structure pointed to by rem unless rem is NULL.
/// @details
/// The execution is suspended until either at least the time specified
/// in *req has elapsed, or the delivery of a signal that triggers the
/// invocation of a handler in the calling thread or that terminates
/// the process.
int nanosleep(const timespec *req, timespec *rem);
/// @brief Causes the calling thread to sleep either until the number of
/// real-time seconds specified in seconds have elapsed or
/// until a signal arrives which is not ignored.
/// @param seconds The number of seconds we want to sleep.
/// @return Zero if the requested time has elapsed, or the number of seconds
/// left to sleep, if the call was interrupted by a signal handler.
unsigned int sleep(unsigned int seconds);
/// @brief Fills the structure pointed to by curr_value with the current setting for the timer specified by which.
int getitimer(int which, itimerval *curr_value);
/// @brief The system provides each process with three interval timers, each decrementing in a distinct time domain.
/// When any timer expires, a signal is sent to the process, and the timer (potentially) restarts.
int setitimer(int which, const itimerval *new_value, itimerval *old_value);
+81
View File
@@ -0,0 +1,81 @@
/// MentOS, The Mentoring Operating system project
/// @file abort.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "string.h"
#include "signal.h"
#include "stdio.h"
// Since there could be signal handlers listening for the abort, we
// need to keep track at which stage of the abort we are.
static int stage = 0;
void abort(void)
{
sigaction_t action;
sigset_t sigset;
/* Unblock SIGABRT. */
if (stage == 0) {
++stage;
sigemptyset(&sigset);
sigaddset(&sigset, SIGABRT);
sigprocmask(SIG_UNBLOCK, &sigset, 0);
}
/* Send signal which possibly calls a user handler. */
if (stage == 1) {
// We must allow recursive calls of abort
int save_stage = stage;
stage = 0;
kill(getpid(), SIGABRT);
stage = save_stage + 1;
}
/* There was a handler installed. Now remove it. */
if (stage == 2) {
++stage;
memset(&action, 0, sizeof(action));
action.sa_handler = SIG_DFL;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGABRT, &action, NULL);
}
/* Try again. */
if (stage == 3) {
++stage;
kill(getpid(), SIGABRT);
}
/* Now try to abort using the system specific command. */
if (stage == 4) {
++stage;
__asm__ __volatile__("hlt");
}
/* If we can't signal ourselves and the abort instruction failed, exit. */
if (stage == 5) {
++stage;
exit(127);
}
// If even this fails try to use the provided instruction to crash
// or otherwise make sure we never return.
#pragma clang diagnostic push
#pragma ide diagnostic ignored "EndlessLoop"
while (1) __asm__ __volatile__("hlt");
#pragma clang diagnostic pop
}
+19
View File
@@ -0,0 +1,19 @@
/// MentOS, The Mentoring Operating system project
/// @file assert.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "assert.h"
#include "stdlib.h"
#include "stdio.h"
void __assert_fail(const char *assertion, const char *file, const char *function, unsigned int line)
{
printf("FILE: %s\n"
"FUNC: %s\n"
"LINE: %d\n\n"
"Assertion `%s` failed.\n",
file, (function ? function : "NO_FUN"), line, assertion);
abort();
}
+15
View File
@@ -0,0 +1,15 @@
extern main
extern __libc_start_main
global _start
; -----------------------------------------------------------------------------
; SECTION (text)
; -----------------------------------------------------------------------------
section .text
_start: ; _start is the entry point known to the linker
mov ebp, 0 ; Set ebp to 0 as x86 programs require
push main ; Push the pointer to `main` to the stack.
call __libc_start_main ; Call the libc initialization function.
mov ebx, eax ; Move `main` return value to ebx.
mov eax, 1 ; Call the `exit` function by using `int 80` (i.e., a system call)
int 0x80
+63
View File
@@ -0,0 +1,63 @@
/// MentOS, The Mentoring Operating system project
/// @file ctype.c
/// @brief Functions related to character handling.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "ctype.h"
/// Distance from a uppercase character to the correspondent lowercase in ASCII.
#define OFFSET 32
int isdigit(int c)
{
return (c >= 48 && c <= 57);
}
int isalpha(int c)
{
return ((c >= 65 && c <= 90) || (c >= 97 && c <= 122));
}
int isalnum(int c)
{
return (isalpha(c) || isdigit(c));
}
int isxdigit(int c)
{
return (isdigit(c) || (c >= 65 && c <= 70));
}
int islower(int c)
{
return (c >= 97 && c <= 122);
}
int isupper(int c)
{
return (c >= 65 && c <= 90);
}
int tolower(int c)
{
if (isalpha(c) == 0 || islower(c)) {
return c;
}
return c + OFFSET;
}
int toupper(int c)
{
if (isalpha(c) == 0 || isupper(c)) {
return c;
}
return c - OFFSET;
}
int isspace(int c)
{
return (c == ' ');
}
+105
View File
@@ -0,0 +1,105 @@
/// MentOS, The Mentoring Operating system project
/// @file debug.c
/// @brief Debugging primitives.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include <debug.h>
#include <stddef.h>
#include <io/port_io.h>
#include <stdio.h>
#include <string.h>
#include <sys/bitops.h>
/// Serial port for QEMU.
#define SERIAL_COM1 (0x03F8)
void dbg_putchar(char c)
{
#if (defined(DEBUG_STDIO) || defined(DEBUG_LOG))
outportb(SERIAL_COM1, (uint8_t)c);
#endif
}
void dbg_puts(const char *s)
{
#if (defined(DEBUG_STDIO) || defined(DEBUG_LOG))
while ((*s) != 0)
dbg_putchar(*s++);
#endif
}
static inline void __debug_print_header(const char *file, const char *fun, int line)
{
static char tmp_prefix[BUFSIZ], final_prefix[BUFSIZ];
dbg_puts("[ LB |");
sprintf(tmp_prefix, "%s:%d", file, line);
sprintf(final_prefix, " %-20s ", tmp_prefix);
dbg_puts(final_prefix);
dbg_putchar('|');
sprintf(final_prefix, " %-25s ] ", fun);
dbg_puts(final_prefix);
}
void dbg_printf(const char *file, const char *fun, int line, const char *format, ...)
{
// Define a buffer for the formatted string.
static char formatted[BUFSIZ];
static short new_line = 1;
// Stage 1: FORMAT
if (strlen(format) >= BUFSIZ)
return;
// Start variabile argument's list.
va_list ap;
va_start(ap, format);
// Format the message.
vsprintf(formatted, format, ap);
// End the list of arguments.
va_end(ap);
// Stage 2: SEND
if (new_line) {
__debug_print_header(file, fun, line);
new_line = 0;
}
for (size_t it = 0; (formatted[it] != 0) && (it < BUFSIZ); ++it) {
dbg_putchar(formatted[it]);
if (formatted[it] != '\n') {
continue;
}
if ((it + 1) >= BUFSIZ) {
continue;
}
if (formatted[it + 1] == 0) {
new_line = 1;
} else {
__debug_print_header(file, fun, line);
}
}
}
const char *to_human_size(unsigned long bytes)
{
static char output[200];
const char *suffix[] = { "B", "KB", "MB", "GB", "TB" };
char length = sizeof(suffix) / sizeof(suffix[0]);
int i = 0;
double dblBytes = bytes;
if (bytes > 1024) {
for (i = 0; (bytes / 1024) > 0 && i < length - 1; i++, bytes /= 1024)
dblBytes = bytes / 1024.0;
}
sprintf(output, "%.03lf %2s", dblBytes, suffix[i]);
return output;
}
const char *dec_to_binary(unsigned long value)
{
static char buffer[33];
for (int i = 0; i < 32; ++i)
buffer[i] = bit_check(value, 31 - i) ? '1' : '0';
return buffer;
}
+104
View File
@@ -0,0 +1,104 @@
/// MentOS, The Mentoring Operating system project
/// @file fcvt.c
/// @brief Define the functions required to turn double values into a string.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "fcvt.h"
#include "math.h"
static void cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, unsigned buf_size, int eflag)
{
int r2;
double fi, fj;
char *p, *p1;
char *buf_end = (buf + buf_size);
if (ndigits < 0) {
ndigits = 0;
}
if (ndigits >= buf_size - 1) {
ndigits = buf_size - 2;
}
r2 = 0;
*sign = 0;
p = &buf[0];
if (arg < 0) {
*sign = 1;
arg = -arg;
}
arg = modf(arg, &fi);
p1 = buf_end;
if (fi != 0) {
p1 = buf_end;
while (fi != 0) {
fj = modf(fi / 10, &fi);
*--p1 = (int)((fj + .03) * 10) + '0';
r2++;
}
while (p1 < buf_end) {
*p++ = *p1++;
}
} else if (arg > 0) {
while ((fj = arg * 10) < 1) {
arg = fj;
r2--;
}
}
p1 = &buf[ndigits];
if (eflag == 0) {
p1 += r2;
}
*decpt = r2;
if (p1 < &buf[0]) {
buf[0] = '\0';
return;
}
while (p <= p1 && p < buf_end) {
arg *= 10;
arg = modf(arg, &fj);
*p++ = (int)fj + '0';
}
if (p1 >= buf_end) {
buf[buf_size - 1] = '\0';
return;
}
p = p1;
*p1 += 5;
while (*p1 > '9') {
*p1 = '0';
if (p1 > buf) {
++*--p1;
} else {
*p1 = '1';
(*decpt)++;
if (eflag == 0) {
if (p > buf)
*p = '0';
p++;
}
}
}
*p = '\0';
}
void ecvtbuf(double arg, int chars, int *decpt, int *sign, char *buf, unsigned buf_size)
{
cvt(arg, chars, decpt, sign, buf, buf_size, 1);
}
void fcvtbuf(double arg, int decimals, int *decpt, int *sign, char *buf, unsigned buf_size)
{
cvt(arg, decimals, decpt, sign, buf, buf_size, 0);
}
+238
View File
@@ -0,0 +1,238 @@
/// MentOS, The Mentoring Operating system project
/// @file grp.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "grp.h"
#include "sys/unistd.h"
#include "sys/errno.h"
#include "assert.h"
#include "string.h"
#include "stdio.h"
#include "debug.h"
#include "fcntl.h"
static inline void __parse_line(struct group* grp, char *buf)
{
assert(grp && "Received null grp!");
char *token;
// Parse the group name.
if ((token = strtok(buf, ":")) != NULL)
grp->gr_name = token;
// Parse the group passwd.
if ((token = strtok(NULL, ":")) != NULL)
grp->gr_passwd = token;
// Parse the group id.
if ((token = strtok(NULL, ":")) != 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";
}
static inline char *__search_entry(int fd, char *buf, int buflen, const char *name, gid_t gid)
{
int ret;
char c;
int pos = 0;
while ((ret = read(fd, &c, 1U))) {
// Skip carriage return.
if (c == '\r')
continue;
if (pos >= buflen) {
errno = ERANGE;
return NULL;
}
// If we have found a newline or the EOF, parse the entry.
if ((c == '\n') || (ret == EOF)) {
// Close the buffer.
buf[pos] = 0;
// Check the entry.
if (name) {
if (strncmp(buf, name, strlen(name)) == 0)
return buf;
} else {
int gid_start = -1, col_count = 0;
for (int i = 0; i < pos; ++i) {
if (buf[i] == ':') {
if (++col_count == 2) {
gid_start = i + 1;
break;
}
}
}
if ((gid_start != -1) && (gid_start < pos)) {
// Parse the gid.
int found_gid = atoi(&buf[gid_start]);
// Check the gid.
if (found_gid == gid)
return buf;
}
}
// Reset the index.
pos = 0;
// If we have reached the EOF stop.
if (ret == EOF)
break;
} else {
buf[pos++] = c;
}
}
errno = ENOENT;
return NULL;
}
struct group* getgrgid(gid_t gid) {
static group grp;
static char buffer[BUFSIZ];
group *result;
if (!getgrgid_r(gid, &grp, buffer, BUFSIZ, &result))
return NULL;
return &grp;
}
struct group *getgrnam(const char* name) {
if (name == NULL)
return NULL;
static group grp;
static char buffer[BUFSIZ];
group *result;
if (!getgrnam_r(name, &grp, buffer, BUFSIZ, &result))
return NULL;
return &grp;
}
int getgrgid_r(gid_t gid, struct group* group, char* buf, size_t buflen, struct group ** result) {
int fd = open("/etc/group", O_RDONLY, 0);
if (fd == -1) {
errno = ENOENT;
*result = NULL;
return 0;
}
char *entry = __search_entry(fd, buf, buflen, NULL, gid);
if (entry != NULL) {
// Close the file.
close(fd);
// Parse the line.
__parse_line(group, entry);
// Return success.
return 1;
}
// Close the file.
close(fd);
// Return fail.
return 0;
}
int getgrnam_r(const char* name, struct group* group, char* buf, size_t buflen, struct group** result) {
int fd = open("/etc/group", O_RDONLY, 0);
if (fd == -1) {
errno = ENOENT;
*result = NULL;
return 0;
}
char *entry = __search_entry(fd, buf, buflen, name, 0);
if (entry != NULL) {
// Close the file.
close(fd);
// Parse the line.
__parse_line(group, entry);
// Return success.
return 1;
}
// Close the file.
close(fd);
// Return fail.
return 0;
}
static int fd = -1;
struct group* getgrent(void) {
static group result;
if (fd == -1) {
//pr_debug("Opening group file\n");
fd = open("/etc/group", O_RDONLY, 0);
if (fd == -1) {
errno = ENOENT;
return 0;
}
}
int ret;
char c;
int pos = 0;
static char buffer[BUFSIZ];
while ((ret = read(fd, &c, 1U))) {
// Skip carriage return.
if (c == '\r')
continue;
if (pos >= BUFSIZ) {
errno = ERANGE;
return NULL;
}
// If we have found a newline or the EOF, parse the entry.
if ((c == '\n') || (ret == EOF)) {
// Close the buffer.
buffer[pos] = 0;
// Check the entry.
if (strlen(buffer) != 0) {
//pr_debug("Found entry in group file: %s\n", buffer);
__parse_line(&result, buffer);
return &result;
}
// If we have reached the EOF stop.
if (ret == EOF)
break;
} else {
buffer[pos++] = c;
}
}
errno = ENOENT;
return NULL;
}
void endgrent(void) {
//pr_debug("Closing group file\n");
close(fd);
fd = -1;
}
void setgrent(void) {
//pr_debug("Resetting pointer to beginning of group file\n");
lseek(fd, 0, SEEK_SET);
}
+37
View File
@@ -0,0 +1,37 @@
/// MentOS, The Mentoring Operating system project
/// @file mm_io.c
/// @brief Memory Mapped IO functions implementation.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "io/mm_io.h"
uint8_t in_memb(uint32_t addr)
{
return *((uint8_t *) (addr));
}
uint16_t in_mems(uint32_t addr)
{
return *((uint16_t *) (addr));
}
uint32_t in_meml(uint32_t addr)
{
return *((uint32_t *) (addr));
}
void out_memb(uint32_t addr, uint8_t value)
{
(*((uint8_t *) (addr))) = (value);
}
void out_mems(uint32_t addr, uint16_t value)
{
(*((uint16_t *) (addr))) = (value);
}
void out_meml(uint32_t addr, uint32_t value)
{
(*((uint32_t *) (addr))) = (value);
}
+59
View File
@@ -0,0 +1,59 @@
/// MentOS, The Mentoring Operating system project
/// @file port_io.c
/// @brief Byte I/O on ports prototypes.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "io/port_io.h"
inline uint8_t inportb(uint16_t port)
{
unsigned char data = 0;
__asm__ __volatile__("inb %%dx, %%al" : "=a"(data) : "d"(port));
return data;
}
inline uint16_t inports(uint16_t port)
{
uint16_t rv;
__asm__ __volatile__("inw %1, %0" : "=a"(rv) : "dN"(port));
return rv;
}
void inportsm(uint16_t port, uint8_t *data, unsigned long size)
{
__asm__ __volatile__("rep insw"
: "+D"(data), "+c"(size)
: "d"(port)
: "memory");
}
inline uint32_t inportl(uint16_t port)
{
uint32_t rv;
__asm__ __volatile__("inl %%dx, %%eax" : "=a"(rv) : "dN"(port));
return rv;
}
inline void outportb(uint16_t port, uint8_t data)
{
__asm__ __volatile__("outb %%al, %%dx" ::"a"(data), "d"(port));
}
inline void outports(uint16_t port, uint16_t data)
{
__asm__ __volatile__("outw %1, %0" : : "dN"(port), "a"(data));
}
void outportsm(uint16_t port, uint8_t *data, uint16_t size)
{
asm volatile("rep outsw" : "+S"(data), "+c"(size) : "d"(port));
}
inline void outportl(uint16_t port, uint32_t data)
{
__asm__ __volatile__("outl %%eax, %%dx" : : "dN"(port), "a"(data));
}
+36
View File
@@ -0,0 +1,36 @@
/// MentOS, The Mentoring Operating system project
/// @file ipc.c
/// @brief Inter-Process Communication (IPC) system call implementation.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
#include "stddef.h"
#include "ipc/sem.h"
#include "ipc/shm.h"
#include "ipc/msg.h"
_syscall3(long, shmat, int, shmid, char *, shmaddr, int, shmflg)
_syscall3(long, shmget, key_t, key, size_t, size, int, flag)
_syscall1(long, shmdt, char *, shmaddr)
_syscall3(long, shmctl, int, shmid, int, cmd, struct shmid_ds *, buf)
_syscall3(long, semget, key_t, key, int, nsems, int, semflg)
_syscall3(long, semop, int, semid, struct sembuf *, sops, unsigned, nsops)
_syscall4(long, semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
_syscall2(long, msgget, key_t, key, int, msgflg)
_syscall4(long, msgsnd, int, msqid, struct msgbuf *, msgp, size_t, msgsz, int, msgflg)
_syscall5(long, msgrcv, int, msqid, struct msgbuf *, msgp, size_t, msgsz, long, msgtyp, int, msgflg)
_syscall3(long, msgctl, int, msqid, int, cmd, struct msqid_ds *, buf)
+40
View File
@@ -0,0 +1,40 @@
/// @file libc_start.c
/// @brief Contains the programs initialization procedure.
#include "sys/unistd.h"
#include "stdlib.h"
#include "string.h"
#include "assert.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
/// @brief Reference to the `environ` variable in `setenv.c`.
extern char **environ;
/// @brief The entry point to every program.
/// @param main Pointer to the main function.
/// @param argc The number of arguments.
/// @param argv The pointer to the arguments.
/// @param envp The pointer to the environmental variables.
/// @return The return of the `main` function.
int __libc_start_main(int (*main)(int, char **, char **), int argc, char *argv[], char *envp[])
{
//dbg_print("== START %-30s =======================================\n", argv[0]);
//dbg_print("__libc_start_main(%p, %d, %p, %p)\n", main, argc, argv, envp);
assert(main && "There is no `main` function.");
assert(argv && "There is no `argv` array.");
assert(envp && "There is no `envp` array.");
//dbg_print("environ : %p\n", environ);
// Copy the environ.
environ = envp;
// Call the main function.
int result = main(argc, argv, envp);
// Free the environ.
//dbg_print("== END %-30s =======================================\n", argv[0]);
return result;
}
// WARNING: This declaration must be here, because libc_start is compiled
// with all the programs, and all the programs NEED to have the `sigreturn`
// symbol. It must be this way, period.
_syscall0(int, sigreturn)
+141
View File
@@ -0,0 +1,141 @@
/// MentOS, The Mentoring Operating system project
/// @file libgen.c
/// @brief String routines.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include <assert.h>
#include <stdlib.h>
#include <sys/unistd.h>
#include "libgen.h"
#include "string.h"
#include "limits.h"
int parse_path(char *out, char **cur, char sep, size_t max)
{
if (**cur == '\0') {
return 0;
}
*out++ = **cur;
++*cur;
--max;
while ((max > 0) && (**cur != '\0') && (**cur != sep)) {
*out++ = **cur;
++*cur;
--max;
}
*out = '\0';
return 1;
}
char *dirname(const char *path)
{
static char s[PATH_MAX];
static char dot[2] = ".";
// Check the input path.
if (path == NULL) {
return dot;
}
// Copy the path to the support string.
strcpy(s, path);
// Get the last occurrence of '/'.
char *last_slash = strrchr(s, '/');
if (last_slash == s) {
// If the slash is acutally the first character of the string, move the
// pointer to the last slash after it.
++last_slash;
} else if ((last_slash != NULL) && (last_slash[1] == '\0')) {
// If the slash is the last character, we need to search before it.
last_slash = memchr(s, '/', last_slash - s);
}
if (last_slash != NULL) {
// If we have found it, close the string.
last_slash[0] = '\0';
} else {
// Otherwise, return '.'.
return dot;
}
return s;
}
char *basename(const char *path)
{
char *p = strrchr(path, '/');
return p ? p + 1 : (char *)path;
}
char *realpath(const char *path, char *resolved)
{
assert(path && "Provided null path.");
if (resolved == NULL)
resolved = malloc(sizeof(char) * PATH_MAX);
char abspath[PATH_MAX];
// Initialize the absolute path.
memset(abspath, '\0', PATH_MAX);
int remaining;
if (path[0] != '/') {
// Get the current task.
getcwd(abspath, PATH_MAX);
// Check the current task.
assert((strlen(abspath) > 0) && "There is no current task.");
// Check that the current working directory is an absolute path.
assert((abspath[0] == '/') && "Current working directory is not an absolute path.");
// Count the remaining space in the absolute path.
remaining = PATH_MAX - strlen(abspath) - 1;
// Add the separator to the end (se strncat for safety).
strncat(abspath, "/", remaining);
// Set the number of characters that should be copied,
// based on the current absolute path.
remaining = PATH_MAX - strlen(abspath) - 1;
// Append the path.
strncat(abspath, path, remaining);
} else {
// Copy the path into the absolute path.
strncpy(abspath, path, PATH_MAX - 1);
}
// Count the remaining space in the absolute path.
remaining = PATH_MAX - strlen(abspath) - 1;
// Add the separator to the end (se strncat for safety).
strncat(abspath, "/", remaining);
int absidx = 0, pathidx = 0;
while (abspath[absidx]) {
// Skip multiple consecutive / characters
if (!strncmp("//", abspath + absidx, 2)) {
absidx++;
}
// Go to previous directory if /../ is found
else if (!strncmp("/../", abspath + absidx, 4)) {
// Go to a valid path character (pathidx points to the next one)
if (pathidx)
pathidx--;
while (pathidx && resolved[pathidx] != '/') {
pathidx--;
}
absidx += 3;
} else if (!strncmp("/./", abspath + absidx, 3)) {
absidx += 2;
} else {
resolved[pathidx++] = abspath[absidx++];
}
}
// Remove the last /
if (pathidx > 1)
resolved[pathidx - 1] = '\0';
else
resolved[1] = '\0';
return resolved;
}
+180
View File
@@ -0,0 +1,180 @@
/// MentOS, The Mentoring Operating system project
/// @file math.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "math.h"
#include "stdint.h"
double round(double x)
{
double out;
__asm__ __volatile__("fldln2; fldl %1; frndint"
: "=t"(out)
: "m"(x));
return out;
}
double floor(double x)
{
if (x > -1.0 && x < 1.0) {
if (x >= 0)
return 0.0;
return -1.0;
}
int i = (int)x;
if (x < 0)
return (double)(i - 1);
return (double)i;
}
double ceil(double x)
{
if (x > -1.0 && x < 1.0) {
if (x <= 0)
return 0.0;
return 1.0;
}
int i = (int)x;
if (x > 0)
return (double)(i + 1);
return (double)i;
}
double pow(double base, double exponent)
{
double out;
__asm__ __volatile__("fyl2x;"
"fld %%st;"
"frndint;"
"fsub %%st,%%st(1);"
"fxch;"
"fchs;"
"f2xm1;"
"fld1;"
"faddp;"
"fxch;"
"fld1;"
"fscale;"
"fstp %%st(1);"
"fmulp;"
: "=t"(out)
: "0"(base), "u"(exponent)
: "st(1)");
return out;
}
double exp(double x)
{
return pow(M_E, x);
}
double fabs(double x)
{
double out;
__asm__ __volatile__("fldln2; fldl %1; fabs"
: "=t"(out)
: "m"(x));
return out;
}
float fabsf(float x)
{
float out;
__asm__ __volatile__("fldln2; fldl %1; fabs"
: "=t"(out)
: "m"(x));
return out;
}
double sqrt(double x)
{
double out;
__asm__ __volatile__("fldln2; fldl %1; fsqrt"
: "=t"(out)
: "m"(x));
return out;
}
float sqrtf(float x)
{
float out;
__asm__ __volatile__("fldln2; fldl %1; fsqrt"
: "=t"(out)
: "m"(x));
return out;
}
int isinf(double x)
{
union {
unsigned long long u;
double f;
} ieee754;
ieee754.f = x;
return ((unsigned)(ieee754.u >> 32U) & 0x7fffffffU) == 0x7ff00000U &&
((unsigned)ieee754.u == 0);
}
int isnan(double x)
{
union {
unsigned long long u;
double f;
} ieee754;
ieee754.f = x;
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
((unsigned)ieee754.u != 0) >
0x7ff00000;
}
double log10(double x)
{
return ln(x) / ln(10);
}
double ln(double x)
{
double out;
__asm__ __volatile__("fldln2; fldl %1; fyl2x"
: "=t"(out)
: "m"(x));
return out;
}
double logx(double x, double y)
{
// Base may not equal 1 or be negative.
if (y == 1.f || y < 0.f || ln(y) == 0.f)
return 0.f;
return ln(x) / ln(y);
}
/// Max power for forward and reverse projections.
#define MAXPOWTWO 4.503599627370496000E+15
double modf(double x, double *intpart)
{
register double absvalue;
if ((absvalue = (x >= 0.0) ? x : -x) >= MAXPOWTWO) {
// It must be an integer.
(*intpart) = x;
} else {
// Shift fraction off right.
(*intpart) = absvalue + MAXPOWTWO;
// Shift back without fraction.
(*intpart) -= MAXPOWTWO;
// Above arithmetic might round.
while ((*intpart) > absvalue) {
// Test again just to be sure.
(*intpart) -= 1.0;
}
if (x < 0.0) {
(*intpart) = -(*intpart);
}
}
// Signed fractional part.
return (x - (*intpart));
}
+162
View File
@@ -0,0 +1,162 @@
/// MentOS, The Mentoring Operating system project
/// @file pwd.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "pwd.h"
#include "sys/unistd.h"
#include "sys/errno.h"
#include "assert.h"
#include "string.h"
#include "stdio.h"
#include "fcntl.h"
static inline void __parse_line(passwd_t *pwd, char *buf)
{
assert(pwd && "Received null pwd!");
char *token;
// Parse the username.
if ((token = strtok(buf, ":")) != NULL)
pwd->pw_name = token;
// Parse the password.
if ((token = strtok(NULL, ":")) != NULL)
pwd->pw_passwd = token;
// Parse the user ID.
if ((token = strtok(NULL, ":")) != NULL)
pwd->pw_uid = atoi(token);
// Parse the group ID.
if ((token = strtok(NULL, ":")) != NULL)
pwd->pw_gid = atoi(token);
// Parse the user information.
if ((token = strtok(NULL, ":")) != NULL)
pwd->pw_gecos = token;
// Parse the dir.
if ((token = strtok(NULL, ":")) != NULL)
pwd->pw_dir = token;
// Parse the shell.
if ((token = strtok(NULL, ":")) != NULL)
pwd->pw_shell = token;
}
static inline char *__search_entry(int fd, char *buf, int buflen, const char *name, uid_t uid)
{
int ret;
char c;
int pos = 0;
while ((ret = read(fd, &c, 1U))) {
// Skip carriage return.
if (c == '\r')
continue;
if (pos >= buflen) {
errno = ERANGE;
return NULL;
}
// If we have found a newline or the EOF, parse the entry.
if ((c == '\n') || (ret == EOF)) {
// Close the buffer.
buf[pos] = 0;
// Check the entry.
if (name) {
if (strncmp(buf, name, strlen(name)) == 0)
return buf;
} else {
int uid_start = -1, col_count = 0;
for (int i = 0; i < pos; ++i) {
if (buf[i] == ':') {
if (++col_count == 2) {
uid_start = i + 1;
break;
}
}
}
if ((uid_start != -1) && (uid_start < pos)) {
// Parse the uid.
int found_uid = atoi(&buf[uid_start]);
// Check the uid.
if (found_uid == uid)
return buf;
}
}
// Reset the index.
pos = 0;
// If we have reached the EOF stop.
if (ret == EOF)
break;
} else {
buf[pos++] = c;
}
}
errno = ENOENT;
return NULL;
}
passwd_t *getpwnam(const char *name)
{
if (name == NULL)
return NULL;
static passwd_t pwd;
static char buffer[BUFSIZ];
passwd_t *result;
if (!getpwnam_r(name, &pwd, buffer, BUFSIZ, &result))
return NULL;
return &pwd;
}
passwd_t *getpwuid(uid_t uid)
{
static passwd_t pwd;
static char buffer[BUFSIZ];
passwd_t *result;
if (!getpwuid_r(uid, &pwd, buffer, BUFSIZ, &result))
return NULL;
return &pwd;
}
int getpwnam_r(const char *name, passwd_t *pwd, char *buf, size_t buflen, passwd_t **result)
{
if (name == NULL)
return 0;
int fd = open("/etc/passwd", O_RDONLY, 0);
if (fd == -1) {
errno = ENOENT;
*result = NULL;
return 0;
}
char *entry = __search_entry(fd, buf, buflen, name, 0);
if (entry != NULL) {
// Close the file.
close(fd);
// Parse the line.
__parse_line(pwd, entry);
// Return success.
return 1;
}
// Close the file.
close(fd);
// Return fail.
return 0;
}
int getpwuid_r(uid_t uid, passwd_t *pwd, char *buf, size_t buflen, passwd_t **result)
{
int fd = open("/etc/passwd", O_RDONLY, 0);
if (fd == -1) {
errno = ENOENT;
*result = NULL;
return 0;
}
char *entry = __search_entry(fd, buf, buflen, NULL, uid);
if (entry != NULL) {
// Close the file.
close(fd);
// Parse the line.
__parse_line(pwd, entry);
// Return success.
return 1;
}
// Close the file.
close(fd);
// Return fail.
return 0;
}
+13
View File
@@ -0,0 +1,13 @@
//
// Created by enryf on 24/09/2020.
//
#include "system/syscall_types.h"
#include "sys/errno.h"
#include "sched.h"
_syscall2(int, sched_setparam, pid_t, pid, const sched_param_t *, param)
_syscall2(int, sched_getparam, pid_t, pid, sched_param_t *, param)
_syscall0(int, waitperiod)
+146
View File
@@ -0,0 +1,146 @@
/// @file setenv.c
/// @brief Defines the functions used to manipulate the environmental variables.
#include <assert.h>
#include "sys/errno.h"
#include "string.h"
#include "stdlib.h"
char **environ;
static char **__environ = NULL;
static size_t __environ_size = 0;
static inline int __find_entry(const char *name, const size_t name_len)
{
if (environ) {
int index = 0;
for (char **ptr = environ; *ptr; ++ptr, ++index)
if (!strncmp((*ptr), name, name_len) && (*ptr)[name_len] == '=')
return index;
}
return -1;
}
static void __clone_environ()
{
if (environ) {
// Count the number of variables.
__environ_size = 0;
for (char **ptr = environ; *ptr; ++ptr) { ++__environ_size; }
// Allocate the space.
__environ = malloc(sizeof(char *) * (__environ_size + 2));
for (int i = 0; i < __environ_size; ++i) {
size_t entry_len = strlen(environ[i]) + 1;
__environ[i] = malloc(sizeof(char) * entry_len);
memcpy(__environ[i], environ[i], entry_len);
}
__environ[__environ_size] = (char *)NULL;
__environ[__environ_size + 1] = (char *)NULL;
__environ_size += 2;
// Set the new environ.
environ = __environ;
}
}
int setenv(const char *name, const char *value, int replace)
{
// There must be always an environ variable set.
assert(environ && "There is no `environ` set.");
// Check the name.
if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
errno = EINVAL;
return -1;
}
if (__environ == NULL) {
__clone_environ();
environ = __environ;
}
const size_t name_len = strlen(name);
const size_t value_len = strlen(value) + 1;
const size_t total_len = name_len + value_len + 1;
//LOCK;
if (environ == NULL) {
return -1;
}
// Find the entry.
int index = __find_entry(name, name_len);
if (index >= 0) {
if (!replace) {
//UNLOCK;
return -1;
}
} else {
// Get the size of environ;
index = __environ_size - 2;
// Extend the environ dynamically allocated memory.
char **new_environ = (char **)realloc(environ, sizeof(char *) * (__environ_size + 1));
// Check the pointer.
if (new_environ == NULL) {
//UNLOCK;
return -1;
}
// Increment the size.
__environ_size += 1;
// Close the environment.
new_environ[__environ_size - 2] = NULL;
new_environ[__environ_size - 1] = NULL;
// Update all the variables.
environ = __environ = new_environ;
}
// Free the previous entry.
if (environ[index])
free(environ[index]);
// Allocate the new entry.
environ[index] = malloc(total_len);
// Memcopy because we do not want the null terminating character.
memcpy(environ[index], name, name_len);
// Set the equal.
environ[index][name_len] = '=';
// Add the value.
memcpy(&environ[index][name_len + 1], value, value_len);
//UNLOCK;
return 0;
}
int unsetenv(const char *name)
{
if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
errno = EINVAL;
return -1;
}
if (__environ == NULL) {
__clone_environ();
environ = __environ;
}
size_t len = strlen(name);
//LOCK;
char **ep = environ;
while (*ep != NULL) {
if (!strncmp(*ep, name, len) && (*ep)[len] == '=') {
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
do dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
} else {
++ep;
}
}
//UNLOCK;
return 0;
}
char *getenv(const char *name)
{
size_t name_len = strlen(name);
int index = __find_entry(name, name_len);
if (index < 0) {
return NULL;
}
size_t env_len = strlen(environ[index]);
if ((name_len + 1) < env_len) {
return &environ[index][name_len + 1];
}
return NULL;
}
+207
View File
@@ -0,0 +1,207 @@
/// @file stdio.c
/// @brief Standard I/0 functions.
/// @date Apr 2019
#include <sys/errno.h>
#include "stdio.h"
#include "ctype.h"
#include "string.h"
#include "stdbool.h"
#include "sys/unistd.h"
void putchar(int character)
{
write(STDOUT_FILENO, &character, 1);
}
void puts(char *str)
{
write(STDOUT_FILENO, str, strlen(str));
}
int getchar(void)
{
char c;
while (read(STDIN_FILENO, &c, 1) == 0)
continue;
return c;
}
char *gets(char *str)
{
// Check the input string.
if (str == NULL)
return NULL;
// Buffer for reading input.
char buffer[GETS_BUFFERSIZE];
memset(buffer, '\0', GETS_BUFFERSIZE);
// Char pointer to the buffer.
char *cptr = buffer;
// Character storage and counter to prevent overflow.
int ch, counter = 0;
// Read until we find a newline or we exceed the buffer size.
while (((ch = getchar()) != '\n') && (counter++ < GETS_BUFFERSIZE)) {
// If we encounter EOF, stop.
if (ch == EOF) {
// EOF at start of line return NULL.
if (cptr == str) {
return NULL;
}
break;
}
// Backspace key
if (ch == '\b') {
if (counter > 0) {
counter--;
--cptr;
putchar('\b');
}
} else {
// The character is stored at address, and the pointer is incremented.
*cptr++ = ch;
}
}
// Add the null-terminating character.
*cptr = '\0';
// Copy the string we have read.
strcpy(str, buffer);
// Return a pointer to the original string.
return str;
}
int atoi(const char *str)
{
// Check the input string.
if (str == NULL)
return 0;
// Initialize sign, the result variable, and two indices.
int sign = (str[0] == '-') ? -1 : +1, result = 0, i;
// Find where the number ends.
for (i = (sign == -1) ? 1 : 0; (str[i] != '\0') && isdigit(str[i]); ++i)
result = (result * 10) + str[i] - '0';
return sign * result;
}
long strtol(const char *str, char **endptr, int base)
{
const char *s;
long acc, cutoff;
int c;
int neg, any, cutlim;
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
s = str;
do {
c = (unsigned char)*s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? LONG_MIN : LONG_MAX;
cutlim = cutoff % base;
cutoff /= base;
if (neg) {
if (cutlim > 0) {
cutlim -= base;
cutoff += 1;
}
cutlim = -cutlim;
}
for (acc = 0, any = 0;; c = (unsigned char)*s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (neg) {
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = LONG_MIN;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc -= c;
}
} else {
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = LONG_MAX;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc += c;
}
}
}
if (endptr != 0)
*endptr = (char *)(any ? s - 1 : str);
return (acc);
}
int fgetc(int fd)
{
unsigned char c;
if (read(fd, &c, 1) <= 0)
return EOF;
return c;
}
char *fgets(char *buf, int n, int fd)
{
int c;
char *p;
/* get max bytes or upto a newline */
for (p = buf, n--; n > 0; n--) {
if ((c = fgetc(fd)) == EOF)
break;
*p++ = c;
if (c == '\n')
break;
}
*p = 0;
if (p == buf || c == EOF)
return NULL;
return (p);
}
+91
View File
@@ -0,0 +1,91 @@
/// MentOS, The Mentoring Operating system project
/// @file stdlib.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "system/syscall_types.h"
#include "stdlib.h"
#include "string.h"
#include "assert.h"
/// @brief Number which identifies a memory area allocated through a call to
/// malloc(), calloc() or realloc().
#define MALLOC_MAGIC_NUMBER 0x600DC0DE
static inline int __malloc_is_valid_ptr(void *ptr)
{
return (ptr && (((size_t *)ptr)[-1] == MALLOC_MAGIC_NUMBER));
}
size_t malloc_usable_size(void *ptr)
{
if (__malloc_is_valid_ptr(ptr))
return ((size_t *)ptr)[-2];
return 0;
}
void *malloc(unsigned int size)
{
size_t *_res, _size = 2 * sizeof(size_t) + size;
__inline_syscall1(_res, brk, _size);
_res[0] = size;
_res[1] = MALLOC_MAGIC_NUMBER;
return &_res[2];
}
void *calloc(size_t num, size_t size)
{
void *ptr = malloc(num * size);
if (ptr) {
memset(ptr, 0, num * size);
}
return ptr;
}
void *realloc(void *ptr, size_t size)
{
// C standard implementation: When NULL is passed to realloc,
// simply malloc the requested size and return a pointer to that.
if (__builtin_expect(ptr == NULL, 0)) {
return malloc(size);
}
// C standard implementation: For a size of zero, free the
// pointer and return NULL, allocating no new memory.
if (__builtin_expect(size == 0, 0)) {
free(ptr);
return NULL;
}
// Get the old size.
size_t old_size = malloc_usable_size(ptr);
// Create the new pointer.
void *newp = malloc(size);
memset(newp, 0, size);
memcpy(newp, ptr, old_size);
free(ptr);
return newp;
}
void free(void *ptr)
{
int _res;
if (__malloc_is_valid_ptr(ptr)) {
size_t *_ptr = (size_t *)ptr - 2;
__inline_syscall1(_res, brk, _ptr);
} else {
__inline_syscall1(_res, brk, ptr);
}
}
/// Seed used to generate random numbers.
static int rseed = 0;
void srand(int x)
{
rseed = x;
}
int rand()
{
return rseed = (rseed * 1103515245U + 12345U) & RAND_MAX;
}
+480
View File
@@ -0,0 +1,480 @@
/// MentOS, The Mentoring Operating system project
/// @file strerror.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "strerror.h"
#include "string.h"
char *strerror(int errnum)
{
static char error[1024];
switch (errnum) {
case 0:
strcpy(error, "Success");
break;
#ifdef ENOENT
case ENOENT:
strcpy(error, "No such file or directory");
break;
#endif
#ifdef ESRCH
case ESRCH:
strcpy(error, "No such process");
break;
#endif
#ifdef EINTR
case EINTR:
strcpy(error, "Interrupted system call");
break;
#endif
#ifdef EIO
case EIO:
strcpy(error, "I/O error");
break;
#endif
#if defined(ENXIO) && (!defined(ENODEV) || (ENXIO != ENODEV))
case ENXIO:
strcpy(error, "No such device or address");
break;
#endif
#ifdef E2BIG
case E2BIG:
strcpy(error, "Arg list too long");
break;
#endif
#ifdef ENOEXEC
case ENOEXEC:
strcpy(error, "Exec format error");
break;
#endif
#ifdef EALREADY
case EALREADY:
strcpy(error, "Socket already connected");
break;
#endif
#ifdef EBADF
case EBADF:
strcpy(error, "Bad file number");
break;
#endif
#ifdef ECHILD
case ECHILD:
strcpy(error, "No children");
break;
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ:
strcpy(error, "Destination address required");
break;
#endif
#ifdef EAGAIN
case EAGAIN:
strcpy(error, "No more processes");
break;
#endif
#ifdef ENOMEM
case ENOMEM:
strcpy(error, "Not enough space");
break;
#endif
#ifdef EACCES
case EACCES:
strcpy(error, "Permission denied");
break;
#endif
#ifdef EFAULT
case EFAULT:
strcpy(error, "Bad address");
break;
#endif
#ifdef ENOTBLK
case ENOTBLK:
strcpy(error, "Block device required");
break;
#endif
#ifdef EBUSY
case EBUSY:
strcpy(error, "Device or resource busy");
break;
#endif
#ifdef EEXIST
case EEXIST:
strcpy(error, "File exists");
break;
#endif
#ifdef EXDEV
case EXDEV:
strcpy(error, "Cross-device link");
break;
#endif
#ifdef ENODEV
case ENODEV:
strcpy(error, "No such device");
break;
#endif
#ifdef ENOTDIR
case ENOTDIR:
strcpy(error, "Not a directory");
break;
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN:
strcpy(error, "Host is down");
break;
#endif
#ifdef EINPROGRESS
case EINPROGRESS:
strcpy(error, "Connection already in progress");
break;
#endif
#ifdef EISDIR
case EISDIR:
strcpy(error, "Is a directory");
break;
#endif
#ifdef EINVAL
case EINVAL:
strcpy(error, "Invalid argument");
break;
#endif
#ifdef EISNAM
case EISNAM:
strcpy(error, "Is a named type file");
break;
#endif
#ifdef ENETDOWN
case ENETDOWN:
strcpy(error, "Network interface is not configured");
break;
#endif
#ifdef ENFILE
case ENFILE:
strcpy(error, "Too many open files in system");
break;
#endif
#ifdef EMFILE
case EMFILE:
strcpy(error, "Too many open files");
break;
#endif
#ifdef ENOTTY
case ENOTTY:
strcpy(error, "Not a character device");
break;
#endif
#ifdef ETXTBSY
case ETXTBSY:
strcpy(error, "Text file busy");
break;
#endif
#ifdef EFBIG
case EFBIG:
strcpy(error, "File too large");
break;
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH:
strcpy(error, "Host is unreachable");
break;
#endif
#ifdef ENOSPC
case ENOSPC:
strcpy(error, "No space left on device");
break;
#endif
#ifdef ENOTSUP
case ENOTSUP:
strcpy(error, "Not supported");
break;
#endif
#ifdef ESPIPE
case ESPIPE:
strcpy(error, "Illegal seek");
break;
#endif
#ifdef EROFS
case EROFS:
strcpy(error, "Read-only file system");
break;
#endif
#ifdef EMLINK
case EMLINK:
strcpy(error, "Too many links");
break;
#endif
#ifdef EPIPE
case EPIPE:
strcpy(error, "Broken pipe");
break;
#endif
#ifdef EDOM
case EDOM:
strcpy(error, "Math argument");
break;
#endif
#ifdef ERANGE
case ERANGE:
strcpy(error, "Result too large");
break;
#endif
#ifdef ENOMSG
case ENOMSG:
strcpy(error, "No message of desired type");
break;
#endif
#ifdef EIDRM
case EIDRM:
strcpy(error, "Identifier removed");
break;
#endif
#ifdef EDEADLK
case EDEADLK:
strcpy(error, "Deadlock");
break;
#endif
#ifdef ENETUNREACH
case ENETUNREACH:
strcpy(error, "Network is unreachable");
break;
#endif
#ifdef ENOLCK
case ENOLCK:
strcpy(error, "No lock");
break;
#endif
#ifdef ENOSTR
case ENOSTR:
strcpy(error, "Not a stream");
break;
#endif
#ifdef ETIME
case ETIME:
strcpy(error, "Stream ioctl timeout");
break;
#endif
#ifdef ENOSR
case ENOSR:
strcpy(error, "No stream resources");
break;
#endif
#ifdef ENONET
case ENONET:
strcpy(error, "Machine is not on the network");
break;
#endif
#ifdef ENOPKG
case ENOPKG:
strcpy(error, "No package");
break;
#endif
#ifdef EREMOTE
case EREMOTE:
strcpy(error, "Resource is remote");
break;
#endif
#ifdef ENOLINK
case ENOLINK:
strcpy(error, "Virtual circuit is gone");
break;
#endif
#ifdef EADV
case EADV:
strcpy(error, "Advertise error");
break;
#endif
#ifdef ESRMNT
case ESRMNT:
strcpy(error, "Srmount error");
break;
#endif
#ifdef ECOMM
case ECOMM:
strcpy(error, "Communication error");
break;
#endif
#ifdef EPROTO
case EPROTO:
strcpy(error, "Protocol error");
break;
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT:
strcpy(error, "Unknown protocol");
break;
#endif
#ifdef EMULTIHOP
case EMULTIHOP:
strcpy(error, "Multihop attempted");
break;
#endif
#ifdef EBADMSG
case EBADMSG:
strcpy(error, "Bad message");
break;
#endif
#ifdef ELIBACC
case ELIBACC:
strcpy(error, "Cannot access a needed shared library");
break;
#endif
#ifdef ELIBBAD
case ELIBBAD:
strcpy(error, "Accessing a corrupted shared library");
break;
#endif
#ifdef ELIBSCN
case ELIBSCN:
strcpy(error, ".lib section in a.out corrupted");
break;
#endif
#ifdef ELIBMAX
case ELIBMAX:
strcpy(error,
"Attempting to link in more shared libraries than system limit");
break;
#endif
#ifdef ELIBEXEC
case ELIBEXEC:
strcpy(error, "Cannot exec a shared library directly");
break;
#endif
#ifdef ENOSYS
case ENOSYS:
strcpy(error, "Function not implemented");
break;
#endif
#ifdef ENMFILE
case ENMFILE:
strcpy(error, "No more files");
break;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY:
strcpy(error, "Directory not empty");
break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
strcpy(error, "File or path name too long");
break;
#endif
#ifdef ELOOP
case ELOOP:
strcpy(error, "Too many symbolic links");
break;
#endif
#ifdef ENOBUFS
case ENOBUFS:
strcpy(error, "No buffer space available");
break;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT:
strcpy(error, "Address family not supported by protocol family");
break;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE:
strcpy(error, "Protocol wrong type for socket");
break;
#endif
#ifdef ENOTSOCK
case ENOTSOCK:
strcpy(error, "Socket operation on non-socket");
break;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT:
strcpy(error, "Protocol not available");
break;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN:
strcpy(error, "Can't send after socket shutdown");
break;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED:
strcpy(error, "Connection refused");
break;
#endif
#ifdef EADDRINUSE
case EADDRINUSE:
strcpy(error, "Address already in use");
break;
#endif
#ifdef ECONNABORTED
case ECONNABORTED:
strcpy(error, "Software caused connection abort");
break;
#endif
#if (defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)))
case EWOULDBLOCK:
strcpy(error, "Operation would block");
break;
#endif
#ifdef ENOTCONN
case ENOTCONN:
strcpy(error, "Socket is not connected");
break;
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT:
strcpy(error, "Socket type not supported");
break;
#endif
#ifdef EISCONN
case EISCONN:
strcpy(error, "Socket is already connected");
break;
#endif
#ifdef ECANCELED
case ECANCELED:
strcpy(error, "Operation canceled");
break;
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE:
strcpy(error, "State not recoverable");
break;
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD:
strcpy(error, "Previous owner died");
break;
#endif
#ifdef ESTRPIPE
case ESTRPIPE:
strcpy(error, "Streams pipe error");
break;
#endif
#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
case EOPNOTSUPP:
strcpy(error, "Operation not supported on socket");
break;
#endif
#ifdef EMSGSIZE
case EMSGSIZE:
strcpy(error, "Message too long");
break;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT:
strcpy(error, "Connection timed out");
break;
#endif
#ifdef ENOTSCHEDULABLE
case ENOTSCHEDULABLE:
strcpy(error, "The process cannot be scheduled");
break;
#endif
default:
strcpy(error, "Unknown error");
break;
}
return error;
}
+702
View File
@@ -0,0 +1,702 @@
/// MentOS, The Mentoring Operating system project
/// @file string.c
/// @brief String routines.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include <fcntl.h>
#include "string.h"
#include "ctype.h"
#include "stdio.h"
#include "stdlib.h"
char *strncpy(char *destination, const char *source, size_t num)
{
char *start = destination;
while (num && (*destination++ = *source++)) {
num--;
}
if (num) {
while (--num) {
*destination++ = '\0';
}
}
return start;
}
int strncmp(const char *s1, const char *s2, size_t n)
{
if (!n)
return 0;
while ((--n > 0) && (*s1) && (*s2) && (*s1 == *s2)) {
s1++;
s2++;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
int stricmp(const char *s1, const char *s2)
{
while (*s2 != 0 && toupper(*s1) == toupper(*s2)) {
s1++, s2++;
}
return (toupper(*s1) - toupper(*s2));
}
int strnicmp(const char *s1, const char *s2, size_t n)
{
int f, l;
do {
if (((f = (unsigned char)(*(s1++))) >= 'A') && (f <= 'Z')) {
f -= 'A' - 'a';
}
if (((l = (unsigned char)(*(s2++))) >= 'A') && (l <= 'Z')) {
l -= 'A' - 'a';
}
} while (--n && f && (f == l));
return f - l;
}
char *strchr(const char *s, int ch)
{
while (*s && *s != (char)ch) {
s++;
}
if (*s == (char)ch)
return (char *)s;
{
return NULL;
}
}
char *strrchr(const char *s, int ch)
{
char *start = (char *)s;
while (*s++) {}
while (--s != start && *s != (char)ch) {}
if (*s == (char)ch) {
return (char *)s;
}
return NULL;
}
char *strstr(const char *str1, const char *str2)
{
char *cp = (char *)str1;
char *s1, *s2;
if (!*str2) {
return (char *)str1;
}
while (*cp) {
s1 = cp;
s2 = (char *)str2;
while (*s1 && *s2 && !(*s1 - *s2)) {
s1++, s2++;
}
if (!*s2) {
return cp;
}
cp++;
}
return NULL;
}
size_t strspn(const char *string, const char *control)
{
const char *str = string;
const char *ctrl = control;
char map[32];
size_t n;
// Clear out bit map.
for (n = 0; n < 32; n++) {
map[n] = 0;
}
// Set bits in control map.
while (*ctrl) {
map[*ctrl >> 3] |= (char)(1 << (*ctrl & 7));
ctrl++;
}
// 1st char NOT in control map stops search.
if (*str) {
n = 0;
while (map[*str >> 3] & (1 << (*str & 7))) {
n++;
str++;
}
return n;
}
return 0;
}
size_t strcspn(const char *string, const char *control)
{
const char *str = string;
const char *ctrl = control;
char map[32];
size_t n;
// Clear out bit map.
for (n = 0; n < 32; n++)
map[n] = 0;
// Set bits in control map.
while (*ctrl) {
map[*ctrl >> 3] |= (char)(1 << (*ctrl & 7));
ctrl++;
}
// 1st char in control map stops search.
n = 0;
map[0] |= 1;
while (!(map[*str >> 3] & (1 << (*str & 7)))) {
n++;
str++;
}
return n;
}
char *strpbrk(const char *string, const char *control)
{
const char *str = string;
const char *ctrl = control;
char map[32];
int n;
// Clear out bit map.
for (n = 0; n < 32; n++)
map[n] = 0;
// Set bits in control map.
while (*ctrl) {
map[*ctrl >> 3] |= (char)(1 << (*ctrl & 7));
ctrl++;
}
// 1st char in control map stops search.
while (*str) {
if (map[*str >> 3] & (1 << (*str & 7))) {
return (char *)str;
}
str++;
}
return NULL;
}
void *memmove(void *dst, const void *src, size_t n)
{
void *ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + n)) {
/* Non-overlapping buffers; copy from lower addresses to higher
* addresses.
*/
while (n--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
} else {
// Overlapping buffers; copy from higher addresses to lower addresses.
dst = (char *)dst + n - 1;
src = (char *)src + n - 1;
while (n--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return ret;
}
void *memchr(const void *ptr, int ch, size_t n)
{
while (n && (*(unsigned char *)ptr != (unsigned char)ch)) {
ptr = (unsigned char *)ptr + 1;
n--;
}
return (n ? (void *)ptr : NULL);
}
char *strlwr(char *s)
{
char *p = s;
while (*p) {
*p = (char)tolower(*p);
p++;
}
return s;
}
char *strupr(char *s)
{
char *p = s;
while (*p) {
*p = (char)toupper(*p);
p++;
}
return s;
}
char *strncat(char *s1, const char *s2, size_t n)
{
char *start = s1;
while (*s1++) {}
s1--;
while (n--) {
if (!(*s1++ = *s2++))
return start;
}
*s1 = '\0';
return start;
}
char *strnset(char *s, int c, size_t n)
{
while (n-- && *s) {
*s++ = (char)c;
}
return s;
}
char *strrev(char *s)
{
char *start = s;
char *left = s;
char ch;
while (*s++) {}
s -= 2;
while (left < s) {
ch = *left;
*left++ = *s;
*s-- = ch;
}
return start;
}
char *strtok_r(char *str, const char *delim, char **saveptr)
{
char *s;
const char *ctrl = delim;
char map[32];
int n;
// Clear delim map.
for (n = 0; n < 32; n++) {
map[n] = 0;
}
// Set bits in delimiter table.
do {
map[*ctrl >> 3] |= (char)(1 << (*ctrl & 7));
} while (*ctrl++);
/* Initialize s. If str is NULL, set s to the saved
* pointer (i.e., continue breaking tokens out of the str
* from the last strtok call).
*/
if (str) {
s = str;
} else {
s = *saveptr;
}
/* Find beginning of token (skip over leading delimiters). Note that
* there is no token iff this loop sets s to point to the terminal
* null (*s == '\0').
*/
while ((map[*s >> 3] & (1 << (*s & 7))) && *s) {
s++;
}
str = s;
/* Find the end of the token. If it is not the end of the str,
* put a null there.
*/
for (; *s; s++) {
if (map[*s >> 3] & (1 << (*s & 7))) {
*s++ = '\0';
break;
}
}
// Update nexttoken.
*saveptr = s;
// Determine if a token has been found.
if (str == (char *)s) {
return NULL;
} else {
return str;
}
}
// Intrinsic functions.
/*
* #pragma function(memset)
* #pragma function(memcmp)
* #pragma function(memcpy)
* #pragma function(strcpy)
* #pragma function(strlen)
* #pragma function(strcat)
* #pragma function(strcmp)
* #pragma function(strset)
*/
void *memset(void *ptr, int value, size_t num)
{
// Truncate c to 8 bits.
value = (value & 0xFF);
char *dst = (char *)ptr;
// Initialize the rest of the size.
while (num--) {
*dst++ = (char)value;
}
return ptr;
}
int memcmp(const void *ptr1, const void *ptr2, size_t n)
{
if (!n) {
return 0;
}
while (--n && *(char *)ptr1 == *(char *)ptr2) {
ptr1 = (char *)ptr1 + 1;
ptr2 = (char *)ptr2 + 1;
}
return *((unsigned char *)ptr1) - *((unsigned char *)ptr2);
}
void *memcpy(void *ptr1, const void *ptr2, size_t num)
{
char *_dst = ptr1;
const char *_src = ptr2;
while (num--) {
*_dst++ = *_src++;
}
return ptr1;
}
void *memccpy(void *ptr1, const void *ptr2, int c, size_t n)
{
while (n && (*((char *)(ptr1 = (char *)ptr1 + 1) - 1) =
*((char *)(ptr2 = (char *)ptr2 + 1) - 1)) != (char)c) {
n--;
}
return n ? ptr1 : NULL;
}
char *strcpy(char *dst, const char *src)
{
char *save = dst;
while ((*dst++ = *src++) != '\0') {}
return save;
}
size_t strlen(const char *s)
{
const char *eos;
for (eos = s; *eos != 0; ++eos) {}
long len = eos - s;
return (len < 0) ? 0 : (size_t)len;
}
size_t strnlen(const char *s, size_t count)
{
const char *sc;
for (sc = s; *sc != '\0' && count--; ++sc) {}
long len = sc - s;
return (len < 0) ? 0 : (size_t)len;
}
int strcmp(const char *s1, const char *s2)
{
int ret = 0;
const char *s1t = s1, *s2t = s2;
for (; !(ret = *s1t - *s2t) && *s2t; ++s1t, ++s2t) {}
return (ret < 0) ? -1 : (ret > 0) ? 1 :
0;
}
char *strcat(char *dst, const char *src)
{
char *cp = dst;
while (*cp) {
cp++;
}
while ((*cp++ = *src++) != '\0') {}
return dst;
}
char *strset(char *s, int c)
{
char *start = s;
while (*s) {
*s++ = (char)c;
}
return start;
}
char *strtok(char *str, const char *delim)
{
const char *spanp;
int c, sc;
char *tok;
static char *last;
if (str == NULL && (str = last) == NULL) {
return (NULL);
}
cont:
c = *str++;
for (spanp = delim; (sc = *spanp++) != 0;) {
if (c == sc) {
goto cont;
}
}
if (c == 0) {
last = NULL;
return (NULL);
}
tok = str - 1;
for (;;) {
c = *str++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0) {
str = NULL;
} else {
str[-1] = 0;
}
last = str;
return (tok);
}
} while (sc != 0);
}
}
char *trim(char *str)
{
size_t len = 0;
char *frontp = str;
char *endp = NULL;
if (str == NULL) {
return NULL;
}
if (str[0] == '\0') {
return str;
}
len = strlen(str);
endp = str + len;
/* Move the front and back pointers to address the first non-whitespace
* characters from each end.
*/
while (isspace((unsigned char)*frontp)) {
++frontp;
}
if (endp != frontp) {
while (isspace((unsigned char)*(--endp)) && endp != frontp) {}
}
if (str + len - 1 != endp) {
*(endp + 1) = '\0';
} else if (frontp != str && endp == frontp) {
*str = '\0';
}
/* Shift the string so that it starts at str so that if it's dynamically
* allocated, we can still free it on the returned pointer. Note the reuse
* of endp to mean the front of the string buffer now.
*/
endp = str;
if (frontp != str) {
while (*frontp) {
*endp++ = *frontp++;
}
*endp = '\0';
}
return str;
}
char *strdup(const char *s)
{
size_t len = strlen(s) + 1;
char *new = malloc(len);
if (new == NULL)
return NULL;
new[len] = '\0';
return (char *)memcpy(new, s, len);
}
char *strndup(const char *s, size_t n)
{
size_t len = strnlen(s, n);
char *new = malloc(len);
if (new == NULL)
return NULL;
new[len] = '\0';
return (char *)memcpy(new, s, len);
}
char *strsep(char **stringp, const char *delim)
{
char *s;
const char *spanp;
int c, sc;
char *tok;
if ((s = *stringp) == NULL) {
return (NULL);
}
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0) {
s = NULL;
} else {
s[-1] = 0;
}
*stringp = s;
return (tok);
}
} while (sc != 0);
}
}
char *itoa(char *buffer, unsigned int num, unsigned int base)
{
// int numval;
char *p, *pbase;
p = pbase = buffer;
if (base == 16) {
sprintf(buffer, "%0x", num);
} else {
if (num == 0) {
*p++ = '0';
}
while (num != 0) {
*p++ = (char)('0' + (num % base));
num = num / base;
}
*p-- = 0;
while (p > pbase) {
char tmp;
tmp = *p;
*p = *pbase;
*pbase = tmp;
p--;
pbase++;
}
}
return buffer;
}
char *replace_char(char *str, char find, char replace)
{
char *current_pos = strchr(str, find);
while (current_pos) {
*current_pos = replace;
current_pos = strchr(current_pos, find);
}
return str;
}
void strmode(mode_t mode, char *p)
{
// Usr.
*p++ = mode & S_IRUSR ? 'r' : '-';
*p++ = mode & S_IWUSR ? 'w' : '-';
*p++ = mode & S_IXUSR ? 'x' : '-';
// Group.
*p++ = mode & S_IRGRP ? 'r' : '-';
*p++ = mode & S_IWGRP ? 'w' : '-';
*p++ = mode & S_IXGRP ? 'x' : '-';
// Other.
*p++ = mode & S_IROTH ? 'r' : '-';
*p++ = mode & S_IWOTH ? 'w' : '-';
*p++ = mode & S_IXOTH ? 'x' : '-';
// Will be a '+' if ACL's implemented.
*p++ = ' ';
*p = '\0';
}
+15
View File
@@ -0,0 +1,15 @@
/// MentOS, The Mentoring Operating system project
/// @file errno.c
/// @brief Stores the error number.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/errno.h"
/// @brief Returns the error number for the current process.
/// @return Pointer to the error number.
int *__geterrno()
{
static int _errno = 0;
return &_errno;
}
+11
View File
@@ -0,0 +1,11 @@
/// MentOS, The Mentoring Operating system project
/// @file ioctl.c
/// @brief Input/Output ConTroL (IOCTL) functions implementation.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/ioctl.h"
#include "sys/errno.h"
#include "system/syscall_types.h"
_syscall3(int, ioctl, int, fd, unsigned long int, request, void *, data)
+37
View File
@@ -0,0 +1,37 @@
/// MentOS, The Mentoring Operating system project
/// @file unistd.c
/// @brief Functions used to manage files.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "string.h"
#include "limits.h"
#include "stdio.h"
#if 0
#include "vfs.h"
int rmdir(const char *path)
{
char absolute_path[PATH_MAX];
get_absolute_normalized_path(path, absolute_path);
int32_t mp_id = get_mountpoint_id(absolute_path);
if (mp_id < 0) {
printf("rmdir: failed to remove '%s':"
"Cannot find mount-point\n",
path);
return -1;
}
if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL) {
return -1;
}
return mountpoint_list[mp_id].dir_op.rmdir_f(absolute_path);
}
#endif
+12
View File
@@ -0,0 +1,12 @@
/// MentOS, The Mentoring Operating system project
/// @file utsname.c
/// @brief Functions used to provide information about the machine & OS.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/utsname.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
#include "stddef.h"
_syscall1(int, uname, utsname_t *, buf)
+38
View File
@@ -0,0 +1,38 @@
/// MentOS, The Mentoring Operating system project
/// @file termios.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "termios.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
#include "bits/ioctls.h"
int tcgetattr(int fd, termios *termios_p)
{
int retval;
__asm__ volatile("int $0x80"
: "=a"(retval)
: "0"(__NR_ioctl), "b"((long)(fd)), "c"((long)(TCGETS)),
"d"((long)(termios_p)));
if (retval < 0) {
errno = -retval;
retval = -1;
}
return retval;
}
int tcsetattr(int fd, int optional_actions, const termios *termios_p)
{
int retval;
__asm__ volatile("int $0x80"
: "=a"(retval)
: "0"(__NR_ioctl), "b"((long)(fd)), "c"((long)(TCSETS)),
"d"((long)(termios_p)));
if (retval < 0) {
errno = -retval;
retval = -1;
}
return retval;
}
+399
View File
@@ -0,0 +1,399 @@
/// MentOS, The Mentoring Operating system project
/// @file time.c
/// @brief Clock functions.
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "time.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
#include "string.h"
#include "stdio.h"
static const char *weekdays[] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
static const char *months[] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
_syscall1(time_t, time, time_t *, t)
time_t difftime(time_t time1, time_t time2)
{
return time1 - time2;
}
/// @brief Computes day of week
/// @param y Year
/// @param m Month of year (in range 1 to 12)
/// @param d Day of month (in range 1 to 31)
/// @return Day of week (in range 1 to 7)
static inline int day_of_week(unsigned int y, unsigned int m, unsigned int d)
{
int h, j, k;
// January and February are counted as months 13 and 14 of the previous year
if (m <= 2) {
m += 12;
y -= 1;
}
// J is the century
j = (int)(y / 100);
// K the year of the century
k = (int)(y % 100);
// Compute H using Zeller's congruence
h = (int)(d + (26 * (m + 1) / 10) + k + (k / 4) + (5 * j) + (j / 4));
// Return the day of the week
return ((h + 5) % 7) + 1;
}
tm_t *localtime(const time_t *time)
{
static tm_t date;
unsigned int a, b, c, d, e, f;
time_t t = *time;
// Negative Unix time values are not supported
if (t < 1) {
t = 0;
}
//Retrieve hours, minutes and seconds
date.tm_sec = (int)(t % 60);
t /= 60;
date.tm_min = (int)(t % 60);
t /= 60;
date.tm_hour = (int)(t % 24);
t /= 24;
// Convert Unix time to date
a = (unsigned int)((4 * t + 102032) / 146097 + 15);
b = (unsigned int)(t + 2442113 + a - (a / 4));
c = (20 * b - 2442) / 7305;
d = b - 365 * c - (c / 4);
e = d * 1000 / 30601;
f = d - e * 30 - e * 601 / 1000;
// January and February are counted as months 13 and 14 of the previous year
if (e <= 13) {
c -= 4716;
e -= 1;
} else {
c -= 4715;
e -= 13;
}
//Retrieve year, month and day
date.tm_year = (int)c;
date.tm_mon = (int)e;
date.tm_mday = (int)f;
// Calculate day of week.
date.tm_wday = day_of_week(date.tm_year, date.tm_mon, date.tm_mday);
return &date;
}
size_t strftime(char *str, size_t maxsize, const char *format, const tm_t *timeptr)
{
if (format == NULL || str == NULL || maxsize <= 0) {
return 0;
}
char *f = (char *)format;
char *s = str;
int value;
size_t ret = 0;
while ((*f) != '\0') {
if ((*f) != '%') {
(*s++) = (*f);
} else {
++f;
switch (*f) {
#if 0
case 'a': /* locale's abbreviated weekday name */
PUT_STRN(weekdays[timeptr->tm_wday], 3);
break;
case 'A': /* locale's full weekday name */
PUT_STR(weekdays[timeptr->tm_wday]);
break;
#endif
case 'b': // Abbreviated month name
{
strncat(s, months[timeptr->tm_mon], 3);
break;
}
case 'B': // Full month name
{
unsigned int i = (unsigned int)timeptr->tm_mon;
strcat(s, months[i]);
break;
}
case 'd': /* day of month as decimal number (01-31) */
{
value = timeptr->tm_mday;
(*s++) = (char)('0' + ((value / 10) % 10));
(*s++) = (char)('0' + (value % 10));
break;
}
case 'H': /* hour (24-hour clock) as decimal (00-23) */
{
value = timeptr->tm_hour;
(*s++) = (char)('0' + ((value / 10) % 10));
(*s++) = (char)('0' + (value % 10));
break;
}
#if 0
case 'I': /* hour (12-hour clock) as decimal (01-12) */
SPRINTF("%02d", ((timeptr->tm_hour + 11) % 12) + 1);
break;
#endif
case 'j': // Day of year as decimal number (001-366)
{
value = timeptr->tm_yday;
(*s++) = (char)('0' + ((value / 10) % 10));
(*s++) = (char)('0' + (value % 10));
break;
}
case 'm': // Month as decimal number (01-12)
{
value = timeptr->tm_mon;
(*s++) = (char)('0' + ((value / 10) % 10));
(*s++) = (char)('0' + (value % 10));
break;
}
#if 0
case 'M': /* month as decimal number (00-59) */
SPRINTF("%02d", timeptr->tm_min);
break;
case 'p': /* AM/PM designations (12-hour clock) */
PUT_STR(timeptr->tm_hour < 12 ? "AM" : "PM");
/* s.b. locale-specific */
break;
case 'S': /* second as decimal number (00-61) */
SPRINTF("%02d", timeptr->tm_sec);
break;
case 'U': /* week of year (first Sunday = 1) (00-53) */
case 'W': /* week of year (first Monday = 1) (00-53) */
{
int fudge = timeptr->tm_wday - timeptr->tm_yday % 7;
if (*fp == 'W') {
fudge--;
}
fudge = (fudge + 7) % 7; /* +7 so not negative */
SPRINTF("%02d", (timeptr->tm_yday + fudge) / 7);
break;
}
case 'w': /* weekday (0-6), Sunday is 0 */
SPRINTF("%02d", timeptr->tm_wday);
break;
case 'x': /* appropriate date representation */
RECUR("%B %d, %Y"); /* s.b. locale-specific */
break;
case 'X': /* appropriate time representation */
RECUR("%H:%M:%S"); /* s.b. locale-specific */
break;
case 'y': /* year without century as decimal (00-99) */
SPRINTF("%02d", timeptr->tm_year % 100);
break;
case 'Y': /* year with century as decimal */
SPRINTF("%d", timeptr->tm_year + 1900);
break;
case 'Z': /* time zone name or abbreviation */
/* XXX %%% */
break;
case '%':
PUT_CH('%');
break;
#endif
default:
(*s++) = '%';
(*s++) = (*f);
}
}
++f;
}
#if 0
#define PUT_CH(c) (ret < maxsize ? (*dp++ = (c), ret++) : 0)
#define PUT_STR(str) \
p = (char *)(str); \
goto dostr;
#define PUT_STRN(str, n) \
p = (char *)(str); \
len = (n); \
goto dostrn;
#define SPRINTF(fmt, arg) \
sprintf(tmpbuf, fmt, arg); \
p = tmpbuf; \
goto dostr;
#define RECUR(fmt) \
{ \
size_t r = strftime(dp, maxsize - ret, fmt, timeptr); \
if (r <= 0) \
return r; \
dp += r; \
ret += r; \
}
char* fp = (char*) format;
char* dp = s;
size_t ret = 0;
if (format == NULL || s == NULL || maxsize <= 0) {
return 0;
}
while (*fp != '\0') {
char* p;
int len;
char tmpbuf[10];
if (*fp != '%') {
PUT_CH(*fp++);
continue;
}
fp++;
switch (*fp) {
case 'a': /* locale's abbreviated weekday name */
PUT_STRN(weekdays[timeptr->tm_wday], 3);
break;
case 'A': /* locale's full weekday name */
PUT_STR(weekdays[timeptr->tm_wday]);
break;
case 'b': /* locale's abbreviated month name */
PUT_STRN(months[timeptr->tm_mon], 3);
break;
case 'B': /* locale's full month name */
PUT_STR(months[timeptr->tm_mon]);
break;
case 'c': /* appropriate date and time representation */
RECUR("%X %x"); /* s.b. locale-specific */
break;
case 'd': /* day of month as decimal number (01-31) */
SPRINTF("%02d", timeptr->tm_mday);
break;
case 'H': /* hour (24-hour clock) as decimal (00-23) */
SPRINTF("%02d", timeptr->tm_hour);
break;
case 'I': /* hour (12-hour clock) as decimal (01-12) */
SPRINTF("%02d", ((timeptr->tm_hour + 11) % 12) + 1);
break;
case 'j': /* day of year as decimal number (001-366) */
SPRINTF("%03d", timeptr->tm_yday + 1);
break;
case 'm': /* month as decimal number (01-12) */
SPRINTF("%02d", timeptr->tm_mon + 1);
break;
case 'M': /* month as decimal number (00-59) */
SPRINTF("%02d", timeptr->tm_min);
break;
case 'p': /* AM/PM designations (12-hour clock) */
PUT_STR(timeptr->tm_hour < 12 ? "AM" : "PM");
/* s.b. locale-specific */
break;
case 'S': /* second as decimal number (00-61) */
SPRINTF("%02d", timeptr->tm_sec);
break;
case 'U': /* week of year (first Sunday = 1) (00-53) */
case 'W': /* week of year (first Monday = 1) (00-53) */
{
int fudge = timeptr->tm_wday - timeptr->tm_yday % 7;
if (*fp == 'W') {
fudge--;
}
fudge = (fudge + 7) % 7; /* +7 so not negative */
SPRINTF("%02d", (timeptr->tm_yday + fudge) / 7);
break;
}
case 'w': /* weekday (0-6), Sunday is 0 */
SPRINTF("%02d", timeptr->tm_wday);
break;
case 'x': /* appropriate date representation */
RECUR("%B %d, %Y"); /* s.b. locale-specific */
break;
case 'X': /* appropriate time representation */
RECUR("%H:%M:%S"); /* s.b. locale-specific */
break;
case 'y': /* year without century as decimal (00-99) */
SPRINTF("%02d", timeptr->tm_year % 100);
break;
case 'Y': /* year with century as decimal */
SPRINTF("%d", timeptr->tm_year + 1900);
break;
case 'Z': /* time zone name or abbreviation */
/* XXX %%% */
break;
case '%':
PUT_CH('%');
break;
dostr:
while (*p != '\0')
PUT_CH(*p++);
break;
dostrn:
while (len-- > 0)
PUT_CH(*p++);
break;
}
++fp;
}
if (ret >= maxsize) {
s[maxsize - 1] = '\0';
return 0;
}
*dp = '\0';
#endif
return ret;
}
_syscall2(int, nanosleep, const timespec *, req, timespec *, rem)
unsigned int sleep(unsigned int seconds)
{
timespec req, rem;
req.tv_sec = seconds;
// Call the nanosleep.
int __ret = nanosleep(&req, &rem);
// If the call to the nanosleep is interrupted by a signal handler,
// then it returns -1 with errno set to EINTR.
if ((__ret == -1) && (errno == EINTR)) {
return rem.tv_sec;
}
return 0;
}
_syscall2(int, getitimer, int, which, itimerval *, curr_value)
_syscall3(int, setitimer, int, which, const itimerval *, new_value, itimerval *, old_value)
+13
View File
@@ -0,0 +1,13 @@
/// MentOS, The Mentoring Operating system project
/// @file chdir.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
_syscall1(int, chdir, const char *, path)
_syscall1(int, fchdir, int, fd)
+11
View File
@@ -0,0 +1,11 @@
/// MentOS, The Mentoring Operating system project
/// @file close.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
_syscall1(int, close, int, fd)
+243
View File
@@ -0,0 +1,243 @@
/// MentOS, The Mentoring Operating system project
/// @file exec.c
/// @brief
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include <debug.h>
#include "sys/unistd.h"
#include "system/syscall_types.h"
#include "sys/errno.h"
#include "sys/stat.h"
#include "stdlib.h"
#include "string.h"
#include "stdarg.h"
#include "fcntl.h"
extern char **environ;
/// @brief Default `PATH`.
#define DEFAULT_PATH "/bin:/usr/bin"
/// @brief Finds an executable inside the PATH entries.
/// @param file The file to search.
/// @param buf The buffer where we will store the absolute path.
/// @param buf_len The length of the buffer.
/// @return 0 if we have found the file inside the entries of PATH,
/// -1 otherwise.
static inline int __find_in_path(const char *file, char *buf, size_t buf_len)
{
// Determine the search path.
char *PATH_VAR = getenv("PATH");
if (PATH_VAR == NULL) {
PATH_VAR = DEFAULT_PATH;
}
// Prepare a stat object for later.
stat_t stat_buf;
// Copy the path.
char *path = strdup(PATH_VAR);
// Iterate through the path entries.
char *token = strtok(path, ":");
while (token != NULL) {
strcpy(buf, token);
strcat(buf, "/");
strcat(buf, file);
if (stat(buf, &stat_buf) == 0) {
if (stat_buf.st_mode & S_IXUSR) {
// TODO: Check why `init` has problems with this free.
// To reproduce the problem use this in init.c:
// execvp("login", _argv);
free(path);
return 0;
}
}
token = strtok(NULL, ":");
}
free(path);
// We did not find the file inside PATH.
errno = ENOENT;
return -1;
}
_syscall3(int, execve, const char *, path, char *const *, argv, char *const *, envp)
int execv(const char *path, char *const argv[])
{
return execve(path, argv, environ);
}
int execvp(const char *file, char *const argv[])
{
if (!file || !argv || !environ) {
errno = ENOENT;
return -1;
}
if (file[0] == '/') {
return execve(file, argv, environ);
}
// Prepare a buffer for the absolute path.
char absolute_path[PATH_MAX] = { 0 };
// Find the file inside the entries of the PATH variable.
if (__find_in_path(file, absolute_path, PATH_MAX) == 0) {
return execve(absolute_path, argv, environ);
}
errno = ENOENT;
return -1;
}
int execvpe(const char *file, char *const argv[], char *const envp[])
{
if (!file || !argv || !envp) {
errno = ENOENT;
return -1;
}
if (file[0] == '/') {
return execve(file, argv, envp);
}
// Prepare a buffer for the absolute path.
char absolute_path[PATH_MAX];
// Find the file inside the entries of the PATH variable.
if (__find_in_path(file, absolute_path, PATH_MAX) == 0) {
return execve(absolute_path, argv, envp);
}
errno = ENOENT;
return -1;
}
int execl(const char *path, const char *arg, ...)
{
va_list ap;
int argc;
// Phase 1: Count the arguments.
va_start(ap, arg);
for (argc = 1; va_arg(ap, const char *); ++argc) {
if (argc == INT_MAX) {
va_end(ap);
errno = E2BIG;
return -1;
}
}
va_end(ap);
// Phase 2: Store the arguments inside a vector.
char *argv[argc + 1];
va_start(ap, arg);
argv[0] = (char *)arg;
for (int i = 1; i <= argc; ++i)
argv[i] = va_arg(ap, char *);
va_end(ap);
// Now, we can call `execve` plain and simple.
return execve(path, argv, environ);
}
int execlp(const char *file, const char *arg, ...)
{
va_list ap;
int argc;
// Phase 1: Count the arguments.
va_start(ap, arg);
for (argc = 1; va_arg(ap, const char *); ++argc) {
if (argc == INT_MAX) {
va_end(ap);
errno = E2BIG;
return -1;
}
}
va_end(ap);
// Phase 2: Store the arguments inside a vector.
char *argv[argc + 1];
va_start(ap, arg);
argv[0] = (char *)arg;
for (int i = 1; i < argc; ++i)
argv[i] = va_arg(ap, char *);
va_end(ap);
// Close argv.
argv[argc] = NULL;
// Now, we can call `execve` plain and simple.
return execvpe(file, argv, environ);
}
int execle(const char *path, const char *arg, ...)
{
va_list ap;
int argc;
// Phase 1: Count the arguments.
va_start(ap, arg);
for (argc = 1; va_arg(ap, const char *); ++argc) {
if (argc == INT_MAX) {
va_end(ap);
errno = E2BIG;
return -1;
}
}
va_end(ap);
argc -= 1;
if (argc < 0) {
errno = EINVAL;
return -1;
}
// Phase 2: Store the arguments inside a vector.
char *argv[argc + 1];
va_start(ap, arg);
argv[0] = (char *)arg;
for (int i = 1; i < argc; ++i)
argv[i] = va_arg(ap, char *);
// Close argv.
argv[argc] = NULL;
// Phase 3: Store the pointer to the environ.
char **envp = va_arg(ap, char **);
va_end(ap);
// Now, we can call `execve` plain and simple.
return execve(path, argv, envp);
}
int execlpe(const char *file, const char *arg, ...)
{
va_list ap;
int argc;
// Phase 1: Count the arguments.
va_start(ap, arg);
for (argc = 1; va_arg(ap, const char *); ++argc) {
if (argc == INT_MAX) {
va_end(ap);
errno = E2BIG;
return -1;
}
}
va_end(ap);
// We don't need to count `envp` among the arguments.
if ((argc -= 1) < 0) {
errno = EINVAL;
return -1;
}
// Phase 2: Store the arguments inside a vector.
char *argv[argc + 1];
va_start(ap, arg);
argv[0] = (char *)arg;
for (int i = 1; i < argc; ++i)
argv[i] = va_arg(ap, char *);
// Close argv.
argv[argc] = NULL;
// Phase 3: Store the pointer to the environ.
char **envp = va_arg(ap, char **);
va_end(ap);
// Now, we can call `execve` plain and simple.
return execvpe(file, argv, envp);
}

Some files were not shown because too many files have changed in this diff Show More