Merge branch 'release/v0.4.0'
This commit is contained in:
+12
-11
@@ -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
|
||||
...
|
||||
|
||||
@@ -99,3 +99,6 @@ src/initscp/initfscp
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
|
||||
# OS filesystem files.
|
||||
files/bin/**
|
||||
+136
-89
@@ -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
@@ -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:
|
||||
|
||||
|
||||
@@ -1,95 +1,93 @@
|
||||
MentOS
|
||||
======
|
||||
# MentOS
|
||||
|
||||
[](https://forthebadge.com)
|
||||
[](https://forthebadge.com)
|
||||
[](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 defined 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,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 +0,0 @@
|
||||
# This file is generated by cmake for dependency checking of the CMakeCache.txt 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)
|
||||
@@ -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.
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+2061
File diff suppressed because it is too large
Load Diff
@@ -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 © 2014–2021 the MentOs team, and numerous contributors.<br>
|
||||
It is available for use and modification under the 
|
||||
<a href="$relpath^md_LICENSE.html">MIT License</a>.<br>
|
||||
</li>
|
||||
</ul>
|
||||
<hr class="footer"/>
|
||||
<address class="footer">
|
||||
$generatedby 
|
||||
<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>
|
||||
@@ -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--> <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 |
@@ -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
@@ -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
@@ -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 | - | - | - | - |
|
||||
| | | | | | | | |
|
||||
@@ -0,0 +1,2 @@
|
||||
root:x:0:user,root,marco
|
||||
user:x:1000:banana,marco
|
||||
@@ -0,0 +1 @@
|
||||
avalon
|
||||
@@ -0,0 +1,2 @@
|
||||
root:root:0:0:Root User:/:/bin/shell
|
||||
user:user:1000:1000:Normal User:/home/user:/bin/shell
|
||||
@@ -1,3 +0,0 @@
|
||||
root:password
|
||||
user:computer
|
||||
asd:asd
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
come va ?
|
||||
AAA
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 "")
|
||||
@@ -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__))
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
};
|
||||
@@ -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);
|
||||
@@ -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__)
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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); \
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
@@ -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
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 == ' ');
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
Reference in New Issue
Block a user