class: center, middle ### Secure Computer Architecture and Systems *** # The C Standard Library ??? - Hi everyone, welcome to this last video on the C programming language - Here we talk about the standard library --- # The C Standard Library (Libc) - **Library of pre-written functions for many low-level tasks**: printing to the console with `printf`, allocating memory with `malloc`, etc. - Essential utilities standardised across compilers and operating systems for portability ??? - The C standard library, also shortened as libc, provides a set of pre-written functions to accomplish a plethora of low level tasks in C - We have seen a few of these functions already: `printf` to print to the console, `malloc` to allocate memory, and a few others - These functions are portable and you can use them with any compiler, operating system, and target architecture -- - **Key Features:** - Input/output (`stdio.h`) - Memory management (`stdlib.h`) - String and memory manipulation (`string.h`) - Mathematical functions (`math.h`) - File handling (`fcntl.h`, `unistd.h`) - Time and date (`time.h`) ??? - Function from the libc will fall within a series of broad categories, including I/O, memory management, string and memory manipulation, maths functions, file handling, time and date, and more - To use the functions from the libc the programmer will need to include the relevant header files, you can see a few on the slide -- - Here we focus on some I/O and memory/string manipulation functions because they have security implications ??? - In these slides we will cover a few I/O and memory or string manipulation functions - This is because they have important security implication that we will investigate later in the unit --- class: middle, inverse, center # String and Memory Manipulation ??? - Let's check out some string and memory manipulation functions first --- # String Copy ```c char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n); ``` ??? - `strcpy` lets the programmer perform a string copy - It takes as parameter the destination memory, and the source string - The destination should be a buffer with enough space to accomodate a copy of the source - A variant is `strncpy`, which takes another parameter, `n` - `strncpy` will do the copy up to a maximum of `n` characters -- ```c #include
/* ... */ char *string1 = "hello"; char *string2 = string1; // this is not a string copy! char string3[10]; // allocated space of 10 bytes, it's called a buffer /* not super safe, what happens if string1 > string3? */ strcpy(string3, string1); /* better */ strncpy(string3, string1, 10); printf("string1 @%p: %s\n", string1, string1); // string1 @1234: hello printf("string2 @%p: %s\n", string2, string2); // string2 @1234: hello printf("string3 @%p: %s\n", string3, string3); // string3 @5678: hello ``` .codelink[
`05-c-standard-library/strcpy.c`
]
??? - You can see an example of usage of both functions here - We have a string named string1, containing `hello` - Look at how string2 is constructed: please note that this is not a string copy: the affectaion simply place the value of string1, which is a pointer, into string 2 - So in the end we end up with another pointer pointing to the original string, as illustrated at the bottom of the slide - If you want to make a proper string copy you need to use strcpy - This is what happens to str3 it points to a buffer of 10 characters which is enough to accomodate a copy of the original string - Then we call strcpy, that will in effect copy the source into the destination, including the termination character - Note that strcpy can be dangerous when the source string is larger than the destination buffer: the function will blindly copy the entire source string and will overflow the destination buffer - To help avoid this you can use `strncpy`, and pass as its last parameter the size of the destination buffer --- # String Concatenation ```c char *strcat(char *dest, const char *src); char *strncat(char *dest, const char *src, size_t n); ``` ??? - To concatenate a string to another you can use `strcat` - It takes two strings as parameter, a destination and a source - After the call the destination string will contain the concatenation of the original destination string, followed by the source string - Once again make sure the destination buffer has enough space to accomodate the sum of characters of the original destination, the source, plus one termination character - If you want to concatenate up to a certain number of characters, you can use `strncat` -- ```c #include
/* ... */ char world[6] = "world"; char s1[32]; char s2[32]; strcpy(s1, "hello "); strcpy(s2, "hello "); strcat(s1, world); // not very safe strncat(s2, world, 32 - strlen(s2)); // better printf("s1: %s\n", s1); // hello world printf("s2: %s\n", s2); // hello world ``` .codelink[
`05-c-standard-library/strcat.c`
] ??? - You have an example of usage of each of these functions here - We have 2 buffers of 32 bytes each, s1 and s2 - We start by placing the string "hello " in each buffers with `strcpy` - The we concatenate s1 and the "world", string, resulting in s1 being "hello world" - We also have a safer example with strncat concatenating s2 and the "world" string - See how we calculate the maximum number of characters to concatenate: it's the size of the destination buffer, 32 bytes, minus the amoutn of characters already present in there, obtained with the strlen function that returns the length of a string --- # Copying Memory ```c void *memcpy(void *dest, void *src, size_t n); ``` ??? - To copy memory one can use the memcpy function - It's better to use that function than to copy manually, because it is highly optimised for speed - `memcpy` copies `n` bytes from the source `src` into the destination `dest` - Note that the source and destination are `void *` generic pointers so they can point to anything -- ```c # include
typedef struct { int m1; int m2; int m3; float f1; } mystruct; int main() { int array_size = 10; mystruct array1[array_size]; mystruct array2[array_size]; for(int i=0; i
`05-c-standard-library/memcpy.c`
] ??? - You have an example of usage here - We have 2 arrays of 10 elements, each element being a relatively large data structure - We populate the first array manually, then let's say that we want to populate the second array with the same content - Because we know that 1 dimensional arrays are laid out contiguously in memory we cna achieve this quickly with a `memcpy` - So we call `memcpy` with the destination beign array2 and the source being array1 - Remember that in C arrays are pointers so we cna pass them as parameters to `memcpy` - We also calculate the number of bytes to copy: it's the number of element in the arrays, multiplied by the size of each element obtained with `sizeof` --- class: inverse, middle, center # Console Input ??? Now let's briefly see how to get input from the user through the console --- # Console Input .leftcol[ ```c char *fgets(char *s, int size, FILE *stream); ``` ] .rightcol[ ```c int scanf(const char *format, ...); ``` ] ??? - To get a string of character from the user you can use fgets - It takes the destination buffer `s` as parameters, as well as the maximum number of characters to write `size` - The third parameter is a stream descriptor that we'll use to indicate that the characters should come from the console, also called the standard input - To get numbers from the user you can use scanf - It takes a string describing the input format as first parameter, followed by the address of the variables to fill with the input -- ```c int int1, int2; double double1; float float1; char s[128]; printf("Please input a string:\n"); fgets(s, 128, stdin); printf("Please input an integer:\n"); scanf("%d", &int1); printf("Please input a float:\n"); scanf("%lf", &double1); /* make sure to us %lf for double and %f for float */ printf("Please enter an integer and a float separated by a space\n"); scanf("%d %f", &int2, &float1); printf("You have entered: %d, %d, %lf, %f, and %s\n", int1, int2, double1, float1, s); ``` .codelink[
`05-c-standard-library/console-input.c`
] ??? - Let's how to use these functions - THe first call to `fgets` here gets a string from the user and places it into a buffer of 128 characters - The we have a few calls to scanf to get respectively and integer, a double, and, on a single line, and integer and a float separated by a space - The program then prints the value of each number and string input to the program --- class: middle, center, inverse # More Libc Functions, Manual Pages ??? - Finally let's talk about how to get reference information about more functions from the standard C library --- # More Libc Functions, Manual Pages - There are many more functions from the standard library that will be useful in the context of this unit - https://en.cppreference.com/w/c.html ??? - Obviously I do not have the time here to make a comprehensive overview of all functions from the C standard library - In the rest of the unit there will be other functions that will be useful to you, either because we are seeing them in the lecture materials, or because you need to use them to complete the lab exercises - To search and explore what kind of functions are available there ar emany solution, but one good starting point is cppreference.com that has a nice part on the C language -- - **Manual** describing how to use each function from the standard library (amongst other popular C libraries) integrated in the command line: ```c man
``` - Will give you: - Function's prototype - Headers to include to be able to use the function - Description of the function's parameters and behaviour - Return values in case of success/error ??? - One last thing: if you want to know how to use a particular function of the libc, you cna use the manual - In the terminal type `man` followed by the name of the function - The man page will be displayed, describing the function's prototype, its behaviour, the headers you need to include to use the function, and the values it can return upon success or exit - To exit the man page simply type q on yoru keyboard --- # Summary - C standard library: a collection of pre-written functions available to accomplish various low-level tasks - We covered a few examples regarding: - String manipulation (`strcpy`, `strcat`) - Memory copy (`memcpy`) - Console input (`fgets`, `scanf`) ??? - In summary, we talked about the C standard library which contains many functions to help you realise various low level tasks - We saw some string and memory manipulation as well as console input functions - And we discussed how to find more functions from the libc, and learn how to use them