C Programming

Chdr() Function in C Language

Setting up a working directory starting from the Linux root directory opens up the possibility of accessing and working on the entire file structure in the various system and user folders.

In this Linux Hint article, you will learn how to set up a working directory using the chdir() function.

We will explain the theoretical workings of this function, its syntax, the types of input and output arguments, and the type of data that each of these arguments takes. Then, we will look at a description on how the chdir() works and the headers required to use this function.

To use this function in practice, we will apply everything that we learned in a practical example where you learn the step-by-step process on how to use this function to set a working directory.

Syntax of the Chdir() Function in C Language

int chdir ( const char* path )

Description of the Chdir() Function in C Language

The chdir() function sets the working directory to the specified folder in the absolute path which is passed in the input argument string. This function accepts a pure string or a pointer of char type to a string which contains the path of the selected directory. To get the current directory to the up level, we need to send the string “..” as an input argument to chdir(). To query the path, use the getcwd() function.

The output argument of this function is of int type. If the working directory selection is successful, chdir() returns 0 as result. Otherwise, if an error occurs, the result is -1.

When we work with this function, we do it directly on the file structure of the operating system. This structure may vary in different versions of OS and it may point to directories that do not exist or have a different name. Therefore, the use of this function can trigger the different types of errors.

The chdir() function returns -1 if an error occurs during execution. However, this information is not sufficient to identify the error and provide a real-time solution or a message to the user, informing about the exception. However, all possible errors that this function can throw are predefined in the “errno.h” header. We will see later a special section to identify the predefined errors.

The chdir() function is defined in the “unistd.h” header. To use it, we need to include it in our “.c” file as follows:

#include <unistd.h>

How to Set the Working Directory Using the Chdir() Function in C Language

In this example, we explain how to set the working directory from our C code. The first step is to include the necessary header, the “unistd.h”. We also include the input and output header which is the “stdio.h” since we use the printf() function to display the results. There are two ways to set the directory with this function. The first directory is a plain string that we send as an input argument to chdir().

We use the getcwd() function to retrieve the created directory. The returned string is stored in the dir character array which we printf() to the shell to determine if it is changed correctly.

In the following snippet, we set the “Documents” folder as the working directory using this mode:

#include <stdio.h>
#include <unistd.h>

void main ()
  {
   char dir [50];
   chdir( "/home/linuxhint/Documents/");
   printf ("\n\n The selected directory is: %s\n", getcwd (dir, 50));

  }

Next, we see an image with the compilation and execution of this code:

The second way is to create a buffer with the elements of char type with the selected directory path and call the chdir() function by passing that string pointer as input argument.

#include <stdio.h>
#include <unistd.h>

void main ()
  {
   char dir [50];
   char path [50] = "/home/linuxhint/Documents/";
   chdir( path);
   printf ("\n\n The selected directory is: %s\n", getcwd (dir, 50));

  }

Next, we see an image with the compilation and execution of this code:

Possible Problems and Solutions When Using the Chdir() Function in the C Language

One of the most common problems when using the chdir() function is that this function uses the absolute path of the directory that we want to select in its input argument.

When we work with files and paths in programming, we usually do so with functions like fopen() or similar. The paths that are specified as input arguments in these functions do not have to contain the root directory since they take the “home” of the logged-in user as their starting point.

Unlike these functions, chdir() is a system function. This means that it uses the absolute paths. If the Linux home directory (/) is not specified as the start of the path, this function does not take effect. Here is the correct procedure to select the “Documents” directory in an absolute path:

home/Documents      Incorrect
/home/Documents     Correct

The following code performs the selection of the “Documents” directory with two calls to chdir(). The first code is without the root directory (/) and the second code is with the root directory (/). After each call, it queries the current directory with getcwd() and displays it in the command console.

#include <stdio.h>
#include <unistd.h>

void main ()
  {

   char name_Ptr[100];
   //No root directory
   chdir( "home/linuxhint/Documents/");
   printf ( "No root directory: %s", getcwd (name_Ptr, 100) );

   //With root directory
   chdir ( "/home/linuxhint/Documents/");
   printf ( "With root directory: %s\n", getcwd (name_Ptr,100) );
  }

It is very important to take this into account when sharing with different functions, chains, or fragments that contain the file paths or directories since, as we can see, some functions take effect when the root directory is not included such as fopen( ) while others like chdir() do not.

In the following image, we see the previous code which is compiled and executed and shows the effect of this function with and without the root directory in its input path.

How to Recover and Identify the Exceptions that May Be Generated Using Chdir() with the Help of the Errno Variables and the Default Errors in the Errno.H Header

This section briefly explains how to identify the possible generated errors using the chdir() function through the predefined error messages in the errno.h header.

The “errno.h” header defines the error codes and is used to identify them when a program is executed. A variable of integer type named “errno” is defined in it which stores a predefined value that represents a specific error every time an exception occurs during execution. In the following, you can see an original fragment of the “errno-base.h” header which is included in the “errno.h” and in which the most common errors are defined:

#define EPERM         1 /* Operation not permitted */
#define NOENT         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 /* Argument 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 */

In cases where the chdir() function returns -1, we can identify the error using the “errno” variable. In this way, we give a specific treatment to resolve the error or a message to the user.

The variables and error codes are defined in the “errno.h” header. To use them, we must include them in our “.c” file as follows:

#include <errno.h>

Example:

In this example, we will try to set the working directory to a non-existent folder. So, chdir()returns -1. Since we know that the function generates an error, we consult the “errno” variable in an if condition to identify the error. In this case, it is the NOENT error which indicates that the file or directory is not found and is represented by the number 2.

We use the printf() function to send a message to the user, informing them that an error has occurred, the error number, and its meaning. The following is the code for this example:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

void main ()
  {
   int error;
   error = chdir( "/home/linuxhint/Docnts/");

   if (error == -1){
     printf ("\n\nAn error occurred. Error: %i\n", errno );
     if (errno == ENOENT)
           printf ("No such file or directory\n\n");
    }
  }

You can try the different fruits indicating the existing and non-existent folders to see the results. The following image shows the compilation and execution of this code:

Conclusion

In this comprehensive Linux Hint article, we explained how to use the chdir() function to specify a working directory. We looked at a theoretical section about this function and applied what we learned in an example with image code snippets. We also showed you some of the most common errors when using the chdir() and how to specify the working path correctly. In addition, we included a special section that teaches you how to detect the various errors with the “errno” variable.

We hope that this article is useful for you. For more articles about the C language and Linux tips, use the search engine on our website.

About the author

Julio Cesar

Julio Cesar is a 42 years old programmer with 8 years of experience in embedded systems development, 6 years developing firmware for user interfaces in C and C++. Additionally he has 2 years of experience developing scripts for network devices and 3 years as developer of high frequency PCB (Printed Circuit Board).