17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
58fd04b83SRoger A. Faulkner  * Common Development and Distribution License (the "License").
68fd04b83SRoger A. Faulkner  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
218fd04b83SRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
23*794f0adbSRoger A. Faulkner  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <stdlib.h>
277c478bd9Sstevel@tonic-gate #include <unistd.h>
287c478bd9Sstevel@tonic-gate #include <string.h>
297c478bd9Sstevel@tonic-gate #include <errno.h>
307c478bd9Sstevel@tonic-gate #include "libproc.h"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate  * rename() system call -- executed by subject process.
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate int
pr_rename(struct ps_prochandle * Pr,const char * old,const char * new)367c478bd9Sstevel@tonic-gate pr_rename(struct ps_prochandle *Pr, const char *old, const char *new)
377c478bd9Sstevel@tonic-gate {
387c478bd9Sstevel@tonic-gate 	sysret_t rval;
398fd04b83SRoger A. Faulkner 	argdes_t argd[4];
407c478bd9Sstevel@tonic-gate 	argdes_t *adp;
417c478bd9Sstevel@tonic-gate 	int error;
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 	if (Pr == NULL)
447c478bd9Sstevel@tonic-gate 		return (rename(old, new));
457c478bd9Sstevel@tonic-gate 
468fd04b83SRoger A. Faulkner 	adp = &argd[0];		/* old fd argument */
478fd04b83SRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
488fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
498fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
508fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
518fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
528fd04b83SRoger A. Faulkner 
538fd04b83SRoger A. Faulkner 	adp++;			/* move to old argument */
547c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
557c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)old;
567c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
577c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
587c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(old) + 1;
597c478bd9Sstevel@tonic-gate 
608fd04b83SRoger A. Faulkner 	adp++;			/* move to new fd argument */
618fd04b83SRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
628fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
638fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
648fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
658fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
668fd04b83SRoger A. Faulkner 
678fd04b83SRoger A. Faulkner 	adp++;			/* move to new argument */
687c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
697c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)new;
707c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
717c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
727c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(new) + 1;
737c478bd9Sstevel@tonic-gate 
748fd04b83SRoger A. Faulkner 	error = Psyscall(Pr, &rval, SYS_renameat, 4, &argd[0]);
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 	if (error) {
777c478bd9Sstevel@tonic-gate 		errno = (error > 0) ? error : ENOSYS;
787c478bd9Sstevel@tonic-gate 		return (-1);
797c478bd9Sstevel@tonic-gate 	}
807c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate /*
847c478bd9Sstevel@tonic-gate  * link() system call -- executed by subject process.
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate int
pr_link(struct ps_prochandle * Pr,const char * existing,const char * new)877c478bd9Sstevel@tonic-gate pr_link(struct ps_prochandle *Pr, const char *existing, const char *new)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate 	sysret_t rval;
90*794f0adbSRoger A. Faulkner 	argdes_t argd[5];
917c478bd9Sstevel@tonic-gate 	argdes_t *adp;
927c478bd9Sstevel@tonic-gate 	int error;
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	if (Pr == NULL)
957c478bd9Sstevel@tonic-gate 		return (link(existing, new));
967c478bd9Sstevel@tonic-gate 
97*794f0adbSRoger A. Faulkner 	adp = &argd[0];		/* first directory fd argument */
98*794f0adbSRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
99*794f0adbSRoger A. Faulkner 	adp->arg_object = NULL;
100*794f0adbSRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
101*794f0adbSRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
102*794f0adbSRoger A. Faulkner 	adp->arg_size = 0;
103*794f0adbSRoger A. Faulkner 
104*794f0adbSRoger A. Faulkner 	adp++;			/* existing argument */
1057c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
1067c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)existing;
1077c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
1087c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1097c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(existing) + 1;
1107c478bd9Sstevel@tonic-gate 
111*794f0adbSRoger A. Faulkner 	adp++;			/* second directory fd argument */
112*794f0adbSRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
113*794f0adbSRoger A. Faulkner 	adp->arg_object = NULL;
114*794f0adbSRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
115*794f0adbSRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
116*794f0adbSRoger A. Faulkner 	adp->arg_size = 0;
117*794f0adbSRoger A. Faulkner 
1187c478bd9Sstevel@tonic-gate 	adp++;			/* new argument */
1197c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
1207c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)new;
1217c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
1227c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1237c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(new) + 1;
1247c478bd9Sstevel@tonic-gate 
125*794f0adbSRoger A. Faulkner 	adp++;			/* flag argument */
126*794f0adbSRoger A. Faulkner 	adp->arg_value = 0;
127*794f0adbSRoger A. Faulkner 	adp->arg_object = NULL;
128*794f0adbSRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
129*794f0adbSRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
130*794f0adbSRoger A. Faulkner 	adp->arg_size = 0;
131*794f0adbSRoger A. Faulkner 
132*794f0adbSRoger A. Faulkner 	error = Psyscall(Pr, &rval, SYS_linkat, 5, &argd[0]);
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	if (error) {
1357c478bd9Sstevel@tonic-gate 		errno = (error > 0) ? error : ENOSYS;
1367c478bd9Sstevel@tonic-gate 		return (-1);
1377c478bd9Sstevel@tonic-gate 	}
1387c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate  * unlink() system call -- executed by subject process.
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate int
pr_unlink(struct ps_prochandle * Pr,const char * path)1457c478bd9Sstevel@tonic-gate pr_unlink(struct ps_prochandle *Pr, const char *path)
1467c478bd9Sstevel@tonic-gate {
1477c478bd9Sstevel@tonic-gate 	sysret_t rval;
1488fd04b83SRoger A. Faulkner 	argdes_t argd[3];
1497c478bd9Sstevel@tonic-gate 	argdes_t *adp;
1507c478bd9Sstevel@tonic-gate 	int error;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	if (Pr == NULL)
1537c478bd9Sstevel@tonic-gate 		return (unlink(path));
1547c478bd9Sstevel@tonic-gate 
1558fd04b83SRoger A. Faulkner 	adp = &argd[0];		/* directory fd argument */
1568fd04b83SRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
1578fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
1588fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
1598fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
1608fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
1618fd04b83SRoger A. Faulkner 	adp++;			/* move to path argument */
1628fd04b83SRoger A. Faulkner 
1637c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
1647c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)path;
1657c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
1667c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1677c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(path) + 1;
1688fd04b83SRoger A. Faulkner 	adp++;			/* move to flags argument */
1698fd04b83SRoger A. Faulkner 
1708fd04b83SRoger A. Faulkner 	adp->arg_value = 0;
1718fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
1728fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
1738fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
1748fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
1757c478bd9Sstevel@tonic-gate 
1768fd04b83SRoger A. Faulkner 	error = Psyscall(Pr, &rval, SYS_unlinkat, 3, &argd[0]);
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	if (error) {
1797c478bd9Sstevel@tonic-gate 		errno = (error > 0) ? error : ENOSYS;
1807c478bd9Sstevel@tonic-gate 		return (-1);
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
1837c478bd9Sstevel@tonic-gate }
184