cpfile Subroutine

Purpose

Optimized copy operation of contents from the source file to the destination file.

Library

Standard C Library (libc.a)

Syntax

#include <unistd.h>

int cpfile(sfd, dfd, offset, nbytesp, flags)
int        sfd;
int        dfd;
off64_t    offset;
size64_t  *nbytesp;
uint64_t   flags;

Description

The cpfile subroutine copies nbytes data from the opened source file (ID specified in the sfd parameter) to the opened destination file (ID specified by the dfd parameter). The cpfile subroutine copies only regular files. The cpfile subroutine can copy files from one local file system, network file system (NFS) or, mounted file system to other file systems. If this function is used for any other type of file or file system, an error is returned.

The offset argument specifies where to begin the read operation from the source file and it starts writing to the same offset value in the destination file unless the destination file is opened in the append mode (by using O_APPEND flag). If the offset value is negative or indicates a position that is beyond the end of source file, an error is returned.

The nbytesp argument is an input and output argument. Basically this argument is used to pass the value also to return a value. For an input operation the address points to the number of bytes to be copied from the specified offset value. The value 0 copies the entire file (or until end of file, if the offset value is nonzero). Fewer bytes might be copied than requested because of the following reasons:

  • Insufficient space to write in the destination file.
  • Insufficient memory to allocate temporary buffers.
  • Upper limit is reached or a pending signal is detected.

The error value of -1 is returned and the errno global variable is set to indicate the failure of copy operation. On return, the nbytesp value specifies how many bytes are successfully copied before the subroutine returned from the call.

If the cpfile subroutine is interrupted by any signal, it returns from kernel space to user space to handle the signal. The error number points to the EINTR value and the nbytesp value indicates the number of bytes copied before the cpfile subroutine was interrupted. If you want the application to continue copying bytes of data from the source file after the signal is handled, call the cpfile subroutine again with a new offset value and length.

Note: If the application restarts the operation where it stopped, it might need to specify the NO_DEST_FSIZE_CHECK flag because the destination file size might not be zero after the application returns from the first call.

The flags argument is used to control the behavior of the call to cpfile subroutine. Specify the value as 0 provided, if you do not want to use the flag. Any other value indicates a valid flag. Multiple flag values can be passed together as bits.

Supported options for flag values are as follows:

SPARSE_DEST_FILE
Source file blocks that have all zero strings are set by using the fclear operation instead of the write operation on the destination file. If source file is sparse then destination file also becomes sparse after the copy operation.
NO_DEST_FSIZE_CHECK
The cpfile subroutine must not check the size of any destination file. If this flag is set the cpfile subroutine overwrites the contents of destination file.

Consider the following information about the cpfile subroutine:

  • The cpfile subroutine is used for one of the following purposes:
    • The cpfile subroutine is used to create identical copy of the source file. Destination file size must be zero, less than, or equal to source file size.
      Note: If destination file size is non-zero then NO_DEST_FSIZE_CHECK flag must be turned on. The cpfile subroutine does not explicitly truncate the destination file. Therefore the application must truncate the destination file to zero, less than, or equal to the source file size before the call. A non-zero sized destination file that is opened in append mode does not create an identical copy of the source file after the copy operation is complete.
    • The cpfile subroutine is used to replace the portion of the destination file at the offset value that is specified by the offset parameter by the portion of the source file at the same offset value. Therefore, the destination file size can be nonzero. In this case, the application must turn on the NO_DEST_FSIZE_CHECK flag.
    • The cpfile subroutine is used to concatenate the content of source file with the content of destination file. In this case, the application must open destination file in append mode (by using the O_APPEND flag) and the NO_DEST_FSIZE_CHECK flag must be turned on because the destination file size is nonzero. The cpfile subroutine starts appending data from the source file to the end of the destination file.
  • The cpfile subroutine can be used in a multi-threaded environment.
  • When the subroutine is copying data, a parallel write operation on the source file, or the destination file might result in an unexpected result.
  • If the SPARSE_DEST_FILE flag is specified, the cpfile subroutine optimizes the copy operation of the source file by skipping the block that has all zero strings in the source file by using the fclear flag instead of performing the write operation on the destination file.
  • The cpfile subroutine does not copy any attributes, extended attributes, access control lists (ACLs) from the source file to the destination file. You must manually copy these attributes, if required.
  • If system call detects any pending signal, the cpfile subroutine returns from kernel space to user space to handle the signal for an application. If application continues the copy operation after the pending signal is processed, application must call the cpfile subroutine again with a new offset value and length. New offset value indicates that from where to continue the copy operation and new length indicates the bytes to be copied from the specified offset.
    Note: The application might need to specify the NO_DEST_FSIZE_CHECK flag for consecutive calls because the destination file size might be non-zero after the previous call to the cpfile subroutine.
  • By default, the cpfile subroutine expects the destination file size to be zero. If the application wants to work with the destination file of size non-zero, the application must pass the NO_DEST_FSIZE_CHECK flag to avoid failure. If application wants to concatenate the source file with the destination file, it must open the destination file in append mode (by using theO_APPEND flag) and call the cpfile subroutine with the NO_DEST_FSIZE_CHECK flag turned on.
    Note: If the application specifies the NO_DEST_FSIZE_CHECK flag, the destination file size is not checked. Hence, if the destination file is larger than source file, data in the destination file, which is located after an offset equal to the source file size is not modified by the cpfile subroutine.

Parameters

sfd
Specifies the file descriptor for the source file.
dfd
Specifies the file descriptor for the destination file.
Offset
Specifies the position in the source file from where to read the data and the position in the destination file where to start writing the data.
nbytesp
Specifies the input value or output value. This argument specifies the number of bytes to be copied. The value 0 copies the entire file. This argument returns the number of bytes that are copied.
flags
Specifies flag values as defined by parameters of the subroutine in the description section.

Return values

Upon successful completion, the call to the cpfile subroutine returns 0. The number of bytes that is copied to the destination file is must not be greater than the value specified by the nbytes parameter. Otherwise, a value of -1 is returned and the errno global variable is set to indicate an error. In both the cases, the nbytesp variable has the value of number of bytes that was copied to the destination file.

Error codes

The cpfile subroutine is unsuccessful when one or more of the following error codes are true. File system can generate errors other than the errors specified in the following list:

EBADF
The file descriptor parameter is not valid.
EINTR
The operation was interrupted by a signal.
EINVAL
The offset, length, or flags parameter is invalid or the nbytesp parameter is null. If destination file size is nonzero and if the NO_DEST_FSIZE_CHECK flag is not set, the EINVAL error code is returned.
ENOMEM
No memory is available in the system to perform the I/O operation.
EFBIG
An offset value greater than the MAX_FILESIZE value was requested.
EAGAIN
The source or destination file was changed unexpectedly. Error code indicates that the cpfile subroutine must be called again.

Example

The following code fragment shows the optimized method to copy file by using the cpfile subroutine:


#include <unistd.h>
int main (int argc, char **argv)
{
       int sfd, dfd;
       size64_t  nbytes = 0;
       uint64_t  flags = 0;
       off64_t   offset = 0;

       /* Open source file */
       sfd = open(argv[0], O_RDONLY, 0);
       if (sfd < 0)
       {
             perror(“open”);
             exit(-1);
       }
       /* Open destination file. Create if not exist and truncate to zero size. */
       dfd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC, 0644);
       if (dfd < 0)
       {
              perror(“open”);
              exit(-1);
       }

       /* Perform any other tasks like copying attributes */
       /* Call cpfile to copy whole file. */
       rc = cpfile(sfd, dfd, offset, &nbytes, flags);
       {
              perror(“cpfile”);
              exit(-1);
       }
       close(sfd);
       close(dfd);
}