+ {
+ aclent_t entries[3];
+ int ret;
+
+ entries[0].a_type = USER_OBJ;
+ entries[0].a_id = 0; /* irrelevant */
+ entries[0].a_perm = (mode >> 6) & 7;
+ entries[1].a_type = GROUP_OBJ;
+ entries[1].a_id = 0; /* irrelevant */
+ entries[1].a_perm = (mode >> 3) & 7;
+ entries[2].a_type = OTHER_OBJ;
+ entries[2].a_id = 0;
+ entries[2].a_perm = mode & 7;
+
+ if (desc != -1)
+ ret = facl (desc, SETACL, sizeof (entries) / sizeof (aclent_t), entries);
+ else
+ ret = acl (name, SETACL, sizeof (entries) / sizeof (aclent_t), entries);
+ if (ret < 0)
+ {
+ if (errno == ENOSYS)
+ return chmod_or_fchmod (name, desc, mode);
+ return -1;
+ }
+ }
+
+ if (!MODE_INSIDE_ACL || (mode & (S_ISUID | S_ISGID | S_ISVTX)))
+ {
+ /* We did not call chmod so far, so the special bits have not yet
+ been set. */
+ return chmod_or_fchmod (name, desc, mode);
+ }
+ return 0;
+
+# endif
+
+# elif HAVE_GETACL /* HP-UX */
+
+ struct stat statbuf;
+ struct acl_entry entries[3];
+ int ret;
+
+ if (desc != -1)
+ ret = fstat (desc, &statbuf);
+ else
+ ret = stat (name, &statbuf);
+ if (ret < 0)
+ return -1;
+
+ entries[0].uid = statbuf.st_uid;
+ entries[0].gid = ACL_NSGROUP;
+ entries[0].mode = (mode >> 6) & 7;
+ entries[1].uid = ACL_NSUSER;
+ entries[1].gid = statbuf.st_gid;
+ entries[1].mode = (mode >> 3) & 7;
+ entries[2].uid = ACL_NSUSER;
+ entries[2].gid = ACL_NSGROUP;
+ entries[2].mode = mode & 7;
+
+ if (desc != -1)
+ ret = fsetacl (desc, sizeof (entries) / sizeof (struct acl_entry), entries);
+ else
+ ret = setacl (name, sizeof (entries) / sizeof (struct acl_entry), entries);
+ if (ret < 0)
+ {
+ if (errno == ENOSYS || errno == EOPNOTSUPP)
+ return chmod_or_fchmod (name, desc, mode);
+ return -1;
+ }
+
+ if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+ {
+ /* We did not call chmod so far, so the special bits have not yet
+ been set. */
+ return chmod_or_fchmod (name, desc, mode);
+ }
+ return 0;
+
+# elif HAVE_ACLX_GET && 0 /* AIX */
+
+ /* TODO: use aclx_fput or aclx_put, respectively */
+
+# elif HAVE_STATACL /* older AIX */
+
+ union { struct acl a; char room[128]; } u;
+ int ret;
+
+ u.a.acl_len = (char *) &u.a.acl_ext[0] - (char *) &u.a; /* no entries */
+ u.a.acl_mode = mode & ~(S_IXACL | 0777);
+ u.a.u_access = (mode >> 6) & 7;
+ u.a.g_access = (mode >> 3) & 7;
+ u.a.o_access = mode & 7;
+
+ if (desc != -1)
+ ret = fchacl (desc, &u.a, u.a.acl_len);
+ else
+ ret = chacl (name, &u.a, u.a.acl_len);
+
+ if (ret < 0 && errno == ENOSYS)
+ return chmod_or_fchmod (name, desc, mode);
+
+ return ret;