mirror of
https://github.com/libretro/cpp-cheat.git
synced 2025-04-17 10:40:00 +00:00
300 lines
7.7 KiB
C
300 lines
7.7 KiB
C
/*
|
|
# Feature macros
|
|
|
|
# XOPEN_SOURCE
|
|
|
|
# GNU_SOURCE
|
|
|
|
Most glibc extensions are contained inside existing POSIX headers.
|
|
|
|
To enable them, you must define a feature macro.
|
|
|
|
There are different feature macros, each anabling a different set of functions,
|
|
|
|
You can get info on those macros with:
|
|
|
|
man feature_test_macros
|
|
|
|
Some common ones are:
|
|
|
|
- `_XOPEN_SOURCE`: enables a given POSIX version. Defined in POSIX
|
|
- `_GNU_SOURCE`: enables everyting on the GLIBC.
|
|
|
|
The feature macro definition *must* come before includes header so that the
|
|
preprocessor can see it when it inteprets the header.
|
|
|
|
# LSB
|
|
|
|
Linux standard base seems to require only the two following gnu extensions to be available:
|
|
|
|
- gnu_get_libc_version() returns a string that identifies the version of the C library running the program making the call.
|
|
- gnu_get_libc_release()
|
|
|
|
All the other functions seem to be present on all Linux distros only because glibc is a de-facto standard. TODO any others?
|
|
|
|
# glibc vs gnulib
|
|
|
|
gnulib seems is meant to be a source of code to be copied pasted, not preinstalled.
|
|
|
|
However some stuff such as `gnu_get_libc_release` seems to be only documented there,
|
|
and comes with glibc. TODO I'm confused.
|
|
|
|
<http://stackoverflow.com/questions/2240120/glibc-glib-and-gnulib>
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h> /* perror */
|
|
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
|
#include <sched.h> /* SCHED_BATCH, SCHED_IDLE, sched_getaffinity */
|
|
#include <unistd.h> /* sysconf */
|
|
|
|
#include <sys/wait.h> /* wait, sleep */
|
|
|
|
#include <gnu/libc-version.h> /* gnu_get_libc_version */
|
|
|
|
int main() {
|
|
printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());
|
|
|
|
/*
|
|
# string.h
|
|
*/
|
|
{
|
|
/*
|
|
# strfry
|
|
|
|
Create anagrams inplace.
|
|
|
|
Return the string itself.
|
|
*/
|
|
{
|
|
char s[] = "abcd";
|
|
puts("strfry(\"abcd\")");
|
|
printf(" %s\n", strfry(s));
|
|
printf(" %s\n", strfry(s));
|
|
}
|
|
}
|
|
|
|
/*
|
|
# sched.h
|
|
|
|
More scheduling policies are defined.
|
|
|
|
Those constants have the same meaning as in the kernel code versions.
|
|
*/
|
|
{
|
|
printf("SCHED_BATCH = %d\n", SCHED_BATCH);
|
|
printf("SCHED_IDLE = %d\n", SCHED_IDLE );
|
|
|
|
/* Called SCHED_NORMAL in the kernel: */
|
|
printf("SCHED_OTHER = %d\n", SCHED_OTHER);
|
|
|
|
/*
|
|
# sched_getaffinity
|
|
|
|
view in which cpu's the given process can run
|
|
|
|
Linux keeps track of this, and this can be set with appropriate premissions
|
|
|
|
# sched_setaffinity
|
|
|
|
set for getaffinity
|
|
|
|
# cpu_set_t
|
|
|
|
a bitmap with a field per cpu
|
|
*/
|
|
{
|
|
cpu_set_t mask;
|
|
if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
|
|
perror("sched_getaffinity");
|
|
exit(EXIT_FAILURE);
|
|
} else {
|
|
printf("sched_getaffinity = ");
|
|
int i;
|
|
for (i = 0; i < sizeof(cpu_set_t); i++) {
|
|
printf("%d", CPU_ISSET(0, &mask));
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
# unistd.h
|
|
*/
|
|
{
|
|
/*
|
|
# brk
|
|
|
|
# sbrk
|
|
|
|
You must have in your mind:
|
|
|
|
---> brk
|
|
|
|
|
| Heap. Grows up ^^^
|
|
|
|
|
---> brk_start
|
|
|
|
|
| brk random offset ASLR
|
|
|
|
|
---> bss end
|
|
|
|
Get and set the break data segment (TODO is it really the data semgment? what about the brk offset?)
|
|
that the kernel assigns to the process.
|
|
|
|
Set it to an absolute value, and return -1 on failure, 0 on success:
|
|
|
|
int brk(void*)
|
|
|
|
Move it by the given delta, and return the *old* value on success, `-1` on failure:
|
|
|
|
void *sbrk(intptr_t increment);
|
|
|
|
This is where the heap lives: `malloc` may use those system calls to do its job,
|
|
although it can also use `mmap`.
|
|
|
|
Once the `brk` is changed,
|
|
the application can then use the newly allocated memory as it pleases,
|
|
and the Kernel must treat that zone as being used and preserve it.
|
|
|
|
The kernel may just say: you are taking up too much memory,
|
|
or "this would overlap with another memory regions", and deny the request.
|
|
|
|
Was in POSIX 2001, but was removed.
|
|
|
|
# Get heap size
|
|
|
|
- http://stackoverflow.com/questions/8367001/how-to-check-heap-size-for-a-process-on-linux
|
|
- http://stackoverflow.com/questions/2354507/how-to-find-size-of-heap-present-in-linux
|
|
|
|
More precisely, how to get the `brk_start`?
|
|
*/
|
|
{
|
|
/* Get the top of the heap. */
|
|
{
|
|
/* TODO is the return value always `long`? What to convert to then? */
|
|
long s = (long)sbrk(0);
|
|
printf("sbrk(0) = %ld =~ %ld MiB\n", s, (((long)s)/(1<<20)));
|
|
}
|
|
|
|
/* Increase the heap by 2. */
|
|
{
|
|
long s = (long)sbrk(2);
|
|
if (s != -1) {
|
|
/* Now we safely use s2 an s2 + 1 to store what we want. */
|
|
char* p = (char*)s;
|
|
*p = 1;
|
|
*(p + 1) = 2;
|
|
assert(*p == 1);
|
|
assert(*(p + 1) == 2);
|
|
/* Restore it back. */
|
|
sbrk(-2);
|
|
} else {
|
|
perror("sbrk");
|
|
}
|
|
|
|
/*
|
|
Attemtping this without changing brk is an almost sure segfault:
|
|
unlike the stack, you can't just increment the heap directly,
|
|
Linux prevents you.
|
|
*/
|
|
{
|
|
/*
|
|
char* p = (char*)s;
|
|
*p = 1;
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
# sysconf
|
|
|
|
Sysconf extensions.
|
|
*/
|
|
{
|
|
/*
|
|
Find the number of processors.
|
|
Seems not to be possible in POSIX:
|
|
http://stackoverflow.com/questions/2693948/how-do-i-retrieve-the-number-of-processors-on-c-linux
|
|
|
|
- conf: configured on kernel.
|
|
- onln: online, that is currently running. Processors can be disabled.
|
|
|
|
*/
|
|
{
|
|
printf("_SC_NPROCESSORS_ONLN = %ld\n", sysconf(_SC_NPROCESSORS_ONLN));
|
|
printf("_SC_NPROCESSORS_CONF = %ld\n", sysconf(_SC_NPROCESSORS_CONF));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
# readline
|
|
|
|
Read one line from a file:
|
|
<http://stackoverflow.com/questions/3501338/c-read-file-line-by-line>
|
|
*/
|
|
|
|
/*
|
|
# stime
|
|
|
|
Set time retreived by time system call.
|
|
*/
|
|
|
|
/*
|
|
# acct
|
|
|
|
Write acconting information on process that start and end to given file.
|
|
|
|
Given file must exist.
|
|
|
|
Must be sudo to do it.
|
|
|
|
Description of output under:
|
|
|
|
man 5 acct
|
|
*/
|
|
{
|
|
char *fname = "acct.tmp";
|
|
if (creat(fname, S_IRWXU) == -1) {
|
|
/* May fail because the file was owned by root. */
|
|
perror("creat");
|
|
}
|
|
if (acct(fname) == -1) {
|
|
perror("acct");
|
|
/* May happen if we are not root. */
|
|
}
|
|
}
|
|
|
|
/*
|
|
# uselib
|
|
|
|
Load dynamic library.
|
|
*/
|
|
{
|
|
/* TODO */
|
|
}
|
|
|
|
/*
|
|
# swapon
|
|
|
|
Manage in shich devices swap memory can exist.
|
|
|
|
# swapoff
|
|
*/
|
|
{
|
|
/* TODO */
|
|
}
|
|
|
|
printf("ALL ASSERTS PASSED\n");
|
|
return EXIT_SUCCESS;
|
|
}
|