[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAFf+5zg3L6WOT=0_HY6dgP8opqgeqwFxg9jUhk2p_cVLTX=EaA@mail.gmail.com>
Date: Wed, 10 Dec 2025 14:01:36 +0530
From: Amit <amitchoudhary0523@...il.com>
To: linux-kernel@...r.kernel.org
Subject: List of yet more C programs.
-----------------------------
List of yet more C programs.
-----------------------------
* File library? - get_oldest_file_in_dir(), get_newest_file_in_dir(),
get_oldest_file_in_dir_matching_name(int case_sensitive),
get_newest_file_in_dir_matching_name(int case_sensitive).
* Share memory across machines.
* Share hard disk storage across machines.
* Allocate memory as a file (malloc_slow_memory(), etc.). Each malloc(), etc.
will be a file.
* File I/O library using mmap to remove copy/cache of file contents from three
places - kernel, glibc file library, and file contents stored by the user in
buffer(s).
* Shared mutex and shared condition variable across processes using mmap.
* Thread synchronization library that threads can't bypass if they want to
access shared data (store shared data as static in a function as key-value
pair(s) and give get/set functions for the shared data).
* Simple database (self developed architecture) and simple query language (self
developed) and connector to database.
* Backup of website.
* Backup of database(s) (PostgreSQL and MariaDB).
* Program/script to create a (desktop) launcher for an application - looks like
a .desktop file has to be created. Take the path of the application as an
input from the user.
* Program to show TCP/UDP/IP (IGMP (ping)?) traffic grouped by remote IP
addresses and sub-grouped by remote port numbers.
* Glibc wrapper library for checking the validity of arguments (NULL check,
etc.). All functions of this library should start with "gw", for example -
gw_strlen(), gw_atoi(), etc.
* Socket based manual testing tool (reference: text menu library), this should
also serve as a remote manual testing tool.
* Functions to get/set all CPU registers.
* Unit testing/Functions testing tool where the functions names and their
arguments are taken from a file (one line per function and their arguments)
and then the function is called with those arguments. The function's address
will be obtained by calling dlsym() function.
When you get a function's address using dlsym(), you can call it without any
arguments even if it requires some arguments. This is because gcc
doesn't/can't
check at compile time whether the function whose address was obtained using
dlsym() is being called without arguments even when this function requires
some arguments.
There are two ways to do it:
1. See how gcc puts the function arguments in the registers / on the
stack and then do the same and then call the function without any
arguments. How to know how gcc sets up the function arguments -
(a) Read on internet about it, read on internet about Linux/System V
ABI interface, etc.
(b) In addition to (a), some experiments can be done by writing C
programs and then generating assembly code (using 'gcc -S') for
these programs and see which arguments are going where
(in registers, on stack, etc.).
2. Another method is to parse the arguments according to their given
types (in the file) but while calling the function, typecast all of
them to 'void *'. 'unsigned long' is also a choice and in this case
signed extension will not happen, but to be totally safe, we will use
'void *'.
Now, gcc will give typecasting warnings but we can switch off all
warnings from gcc using the '-w' switch.
Example of calling a function: If the function is
func(int a, char *s, char c), then it will be called as
(*func_ptr)(get_arg(), get_arg(), get_arg()).
get_arg() function will return the next argument typecasted
to 'void *'.
'float' and 'double' arguments will not be supported because if we
use 'unsigned long' then the decimal part of 'float/double' will get
truncated. If we use 'void *' then gcc gives an error when sending
'void *' to a 'double' argument.
We will support a maximum of 10 arguments and for different
numbers of
arguments we will have different function calls.
For example:
void *call_function(func_ptr, num_arguments)
{
switch (num_arguments) {
case 1:
return ((void *)((*func_ptr)(get_arg())));
case 2:
return ((void *)((*func_ptr)(get_arg(), get_arg())));
.
.
case 10:
appropriate_code_here;
}
}
We can also explore about parsing the arguments and putting them in a
structure and then refer to the arguments as structure->arg1, etc.
So, the definition of the structure will be:
struct args
{
void *arg1;
void *arg2;
.
.
void *arg10;
};
Then we can have the following code to call the function according to
the number of arguments.
For example:
void *call_function(func_ptr, num_arguments)
{
switch (num_arguments) {
case 1:
return ((void *)((*func_ptr)(args->arg1)));
case 2:
return ((void *)((*func_ptr)(args->arg1, args->arg2))));
.
.
case 10:
appropriate_code_here;
}
}
If the user needs more number of arguments then the user can easily
modify the existing tool's code according to his/her requirements.
* RPC (Remote Procedure Call) client/server library (using sockets) and
one example or few examples.
This will require the same way of calling the functions as explained in the
Unit testing/Functions testing tool.
* Code/Functions profiling example program (use gprof or perf or both).
* Print all TCP connections along with the name of the remote server and the
remote/local port number. Make sure that the same combination of the remote
name and remote/local port number shouldn't appear more than once.
* Traceroute implementation.
* Some utility functions: get_ram_size(), dump_stack().
----
Powered by blists - more mailing lists