# Recitation 3 ### 1. Permission Management File permissions are composed of three parts: owner permissions, group permissions, and other user permissions. Each part has three types of permissions: read, write, and execute. For example, the permissions of a file represented as `-rwxr-xr--`: - `-` The first character indicates the file type. In this case, it's a regular file. If it were a directory, it would be `d` - `rwx` - The file owner has read, write, and execute permissions. - `r-x` - The file group has read and execute permissions but not write permission. - `r--` - Other users have read permission, without write and execute permissions. #### Changing Permissions with `chmod` 1. **Change Permissions Using Alphabetic Notation** - **Add Execute Permission to the Owner** ```bash chmod u+x filename ``` If the original permission was `rw-r--r--`, the new permission will be `rwxr--r--`. - **Remove Write Permission from the Group** ```bash chmod g-w filename ``` If the original permission was `rwxrwxrwx`, the new permission will be `rwxr-xrwx`. - **Add Read Permission to Others** ```bash chmod o+r filename ``` If the original permission was `rwxr-x---`, the new permission will be `rwxr-x--r`. 2. **Change Permissions Using Numeric Notation** The first digit is for owner permissions, the second digit is for group permissions, and the third is for other users. Each permission has a numeric value assigned to it: r (read): 4, w (write): 2, x (execute): 1 - **Set Read, Write, and Execute Permissions for Owner, Group, and Others** ```bash chmod 777 filename ``` The permission will be set to `rwxrwxrwx`. - **Set Owner to Read, Write, and Execute Permission; Group to Read and Execute Permission; Others to Read Permission** ```bash chmod 754 filename ``` The permission will be set to `rwxr-xr--`. #### Practical Example Assume there is a file named `example.txt` with initial permissions `rw-r--r--`: - The owner can read and write the file but cannot execute it. - The group users and other users can only read the file. We can use the `chmod` command to change these permissions: ```bash chmod u+x example.txt # Add execute permission to the owner chmod g+w example.txt # Add write permission to the group users chmod o-w example.txt # Remove write permission from other users (though they initially don't have write permission) ``` The updated permissions will be `rwxrw-r--`. - The owner can read, write, and execute the file. - The group users can read and write the file but cannot execute it. - Other users can only read the file. ### 2. File Operations in C Language #### Example 1: Using Predefined File Descriptors In UNIX and Linux systems, a file descriptor is a non-negative integer that represents the way processes access files, pipes, and network sockets. Here are some common file descriptors: - 0 - Standard Input (stdin) - 1 - Standard Output (stdout) - 2 - Standard Error (stderr) - 3 - New file (In C language) When you open a file, the system returns a new file descriptor, typically the smallest unused integer. **Working Principle**: The `open` function returns a file descriptor representing the opened file. The `read` and `write` functions access the file through the file descriptor. The `close` function closes the opened file descriptor, freeing up resources. ```c #include <unistd.h> int main() { // Write data to standard output write(1, "Hello, World!\n", 14); // Write error message to standard error write(2, "An error occurred.\n", 19); return 0; } ``` #### Example 2: Reading and Writing Files Using File Descriptors Here is a C language example demonstrating how to use file descriptors to open, read, write, and close files. ```c #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { int fd = open("example.txt", O_CREAT | O_RDWR, 0644); if (fd == -1) { perror("Cannot open"); return 1; } // Write data to the file const char *data = "Hello, World!\n"; ssize_t written = write(fd, data, 14); if (written == -1) { perror("Cannot write"); close(fd); return 1; } // Move the file position pointer to the beginning of the file lseek(fd, 0, SEEK_SET); // Read data from the file char buffer[1024]; ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1); if (bytesRead == -1) { perror("Cannot read"); close(fd); return 1; } buffer[bytesRead] = '\0'; // Add the string termination character // Print the read data printf("%s", buffer); // Close the file descriptor close(fd); return 0; } ``` In this example: - The `fcntl.h` header is for `file control options` - The `open` function is used to open a file and returns a file descriptor `fd`. - The `write` function uses this file descriptor to write data to the file. - The `lseek` function is used to move the file position pointer. - The `read` function uses the same file descriptor to read data from the file. - The `close` function is used to close the file descriptor and release the resources. - The `perror` function takes a pointer to a null-terminated string, typically containing a user-defined error message. It's followed by a colon and a space, then followed by a textual representation of the system error information. #### perror and stderr - **Returning `-1`**: In the context of system calls (such as `read`, `write`, `open`, etc.) and certain library functions, `-1` typically indicates a failure of the operation. In such cases, the `perror` function can be used or the `errno` variable can be checked to obtain details about the error. - **File Descriptor `2`**: This is the file descriptor for standard error (stderr). Every UNIX or Linux process starts with three default file descriptors: `0` for standard input, `1` for standard output, and `2` for standard error. For instance, in the following code: ```c ssize_t bytesRead = read(fd, buffer, sizeof(buffer)); if (bytesRead == -1) { // Here, -1 indicates that the read function failed perror("read"); // perror will write the error message to file descriptor 2, i.e., standard error } ``` If the `read` function fails, `bytesRead` will be `-1`, and the error can be identified and reported using `perror` or `errno`. The error message will be sent to file descriptor `2` (i.e., standard error).