__chattr() — Change the attributes of a file or directory

Standards

Standards / Extensions C or C++ Dependencies

z/OS® UNIX

both z/OS V1R2

Format

#define _OPEN_SYS_FILE_EXT 1
#include <sys/stat.h>

int __chattr(char* pathname, attrib_t *attributes, int attributes_len);

General description

The __chattr() function modifies the attributes that are associated with a file. It can be used to change the mode, owner, access time, modification time, change time, reference time, audit flags, general attribute flags, file tag, and file format and size. The file to be impacted is defined by the pathname argument.

The attributes argument is the address of an attrib_t structure which is used to identify the attributes to be modified and the new values desired. The attrib_t type is an f_attributes structure as defined in <sys/stat.h> for use with the __chattr() function. For proper behavior the user should ensure that this structure has been initialized to zeros before it is populated. Available elements of the f_attributes structure are defined in Table 1:
Table 1. Struct f_attributes Element Descriptions
Element Data Type General Description
Bit Flags Indicating Which Attributes to Change
att_modechg:1 int 1=Change to mode indicated
att_ownerchg:1 int 1=Change to Owner indicated
att_setgen:1 int 1=Set General Attributes
att_trunc:1 int 1=Truncate Size
att_atimechg:1 int 1=Change the Atime
att_atimetod:1 int 1=Change Atime to Cur.Time
att_mtimechg:1 int 1=Change the Mtime
att_mtimetod:1 int 1=Change Mtime to Cur.Time
att_maaudit:1 int 1=Modify auditor audit info
att_muaudit:1 int 1=Modify user audit info
att_ctimechg:1 int 1=Change the Ctime
att_ctimetod:1 int 1=Change Ctime to Cur.Time
att_reftimechg:1 int 1=Change the RefTime
att_reftimetod:1 int 1=Change RefTime to Cur.Time
att_filefmtchg:1 int 1=Change File Format
att_filetagchg:1 int 1=Change File Tag
att_seclabelchg:1 int 1=Change Seclabel
Modified Values for Indicated Attributes to Change
att_mode mode_t File Mode
att_uid int User ID of the owner of the file
att_gid int Group ID of the Group of the file
att_sharelibmask:1 int 1=Shared Library Mask
att_noshareasmask:1 int 1=No Shareas Flag Mask
att_apfauthmask:1 int 1=APF Authorized Flag Mask
att_progctlmask:1 int 1=Prog. Controlled Flag Mask
att_sharelib:1 int 1=Shared Library Flag
att_noshareas:1 int 1=No Shareas Flag
att_apfauth:1 int 1=APF Authorized Flag
att_progctl:1 int 1=Program Controlled Flag
att_size off_t File size
att_atime time_t Time of last access
att_mtime time_t Time of last data modification
att_auditoraudit int Area for auditor audit info
att_useraudit int Area for user audit info
att_ctime time_t Time of last file status change
att_reftime time_t Reference Time
att_filefmt char File Format
att_filetag struct file_tag File Tag
att_seclabel char Security Label
Note: If you set att_nodelfilesmask, att_sharelibmask, att_nodelfiles, att_sharelib, att_noshareasmask, att_apfauthmask, att_progctlmask, att_noshareas, att_apfauth or att_progctl, then att_setgen must also be set. The att_setgen flag is a required indicator when setting "general" attributes.

Returned value

If successful, __chattr() returns 0.

If unsuccessful, __chattr() returns -1 and sets errno to one of the following values:

Error Code
Description
EACCES
The calling process did not have appropriate permissions. Possible reasons include:
  • The calling process was attempting to set access time or modification time to current time, and the effective UID of the calling process does not match the owner of the file; the process does not have write permission for the file; or the process does not have appropriate privileges.
  • The calling process was attempting to truncate the file, and it does not have write permission for the file.
ECICS
An attempt was made to change file tag attributes under non-OTE CICS® and file tagging is not supported in that environment.
EFBIG
The calling process was attempting to change the size of a file, but the specified length is greater than the maximum file size limit for the process.
EINVAL
The attributes structure containing the requested changes is not valid.
ELOOP
A loop exists in symbolic links that were encountered during resolution of the pathname argument. This error is issued if more than 24 symbolic links are detected in the resolution of pathname.
ENAMETOOLONG
pathname is longer than 1023 characters, or a component of the pathname is longer than 255 characters. (File name truncation is not supported.)
ENOENT
No file named pathname was found.
ENOTDIR
Some component of pathname is not a directory.
EPERM
The operation is not permitted for one of the following reasons:
  • The calling process was attempting to change the mode or the file format but the effective UID of the calling process does not match the owner of the file, and the calling process does not have appropriate privileges.
  • The calling process was attempting to change the owner but it does not have appropriate privileges.
  • The calling process was attempting to change the general attribute bits but it does not have write permission for the file.
  • The calling process was attempting to set a time value (not current time) but the effective UID does not match the owner of the file, and it does not have appropriate privileges.
  • The calling process was attempting to set the change time or reference time to current time but it does not have write permission for the file.
  • The calling process was attempting to change auditing flags but the effective UID of the calling process does not match the owner of the file and the calling process does not have appropriate privileges.
  • The calling process was attempting to change the Security Auditor's auditing flags but the user does not have auditor authority.
EROFS
pathname specifies a file that is on a read-only file system.

Example

#define _POSIX_SOURCE 1
#define _OPEN_SYS_FILE_EXT 1
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {

   int fd;
   attrib_t myAtt;
   struct stat attr;
   char filename[] = "chattr.testfile";

   /* Create an empty file */
   if ( (fd = creat(filename, S_IRWXU | S_IRGRP | S_IROTH)) < 0) {
      perror("Failed to create testfile");
      exit(1);
   }
   close(fd);

   /* Clear myAtt structure */
   memset(&myAtt, 0, sizeof(myAtt));

   /* Update myAtt to request file tag change and set file tag values */
   myAtt.att_filetagchg = 1;
   myAtt.att_filetag.ft_ccsid = 12345;
   myAtt.att_filetag.ft_txtflag = 1;

   /* Change Attributes */
   if ( __chattr(filename, &myAtt, sizeof(myAtt)) != 0 ) {
      perror("Failed to change attributes for testfile");
      exit(2);
   }

   /* Verify Change */
   if ( stat(filename,&attr) !=0 ) {
      perror("Failed to acquire statistics for testfile");
      exit(3);
   }

   if ((attr.st_tag.ft_ccsid == 12345)
       && (attr.st_tag.ft_txtflag == 1)) {
      printf("File attributes changed successfully\n");
   }

}

Related information