Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright (c) 1997-2000 by Sun Microsystems, Inc.
     24  * All rights reserved.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <sys/isa_defs.h>
     30 #include <stdlib.h>
     31 #include <unistd.h>
     32 #include <errno.h>
     33 #include <fcntl.h>
     34 #include "libproc.h"
     35 
     36 /*
     37  * fcntl() system call -- executed by subject process.
     38  */
     39 int
     40 pr_fcntl(struct ps_prochandle *Pr, int fd, int cmd, void *argp)
     41 {
     42 	sysret_t rval;			/* return value from fcntl() */
     43 	argdes_t argd[3];		/* arg descriptors for fcntl() */
     44 	argdes_t *adp;
     45 	int error;
     46 
     47 	if (Pr == NULL)		/* no subject process */
     48 		return (fcntl(fd, cmd, argp));
     49 
     50 	adp = &argd[0];		/* file descriptor argument */
     51 	adp->arg_value = fd;
     52 	adp->arg_object = NULL;
     53 	adp->arg_type = AT_BYVAL;
     54 	adp->arg_inout = AI_INPUT;
     55 	adp->arg_size = 0;
     56 
     57 	adp++;			/* cmd argument */
     58 #ifdef _LP64
     59 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
     60 		/*
     61 		 * Guilty knowledge of the large file compilation environment
     62 		 */
     63 		switch (cmd) {
     64 		case F_GETLK:
     65 			cmd = 33;
     66 			break;
     67 		case F_SETLK:
     68 			cmd = 34;
     69 			break;
     70 		case F_SETLKW:
     71 			cmd = 35;
     72 			break;
     73 		case F_FREESP:
     74 			cmd = 27;
     75 			break;
     76 		}
     77 	}
     78 #endif	/* _LP64 */
     79 	adp->arg_value = cmd;
     80 	adp->arg_object = NULL;
     81 	adp->arg_type = AT_BYVAL;
     82 	adp->arg_inout = AI_INPUT;
     83 	adp->arg_size = 0;
     84 
     85 	adp++;			/* argp argument */
     86 	if (argp == NULL) {
     87 		adp->arg_value = 0;
     88 		adp->arg_object = NULL;
     89 		adp->arg_type = AT_BYVAL;
     90 		adp->arg_inout = AI_INPUT;
     91 		adp->arg_size = 0;
     92 	} else {
     93 		adp->arg_value = 0;
     94 		adp->arg_object = argp;
     95 		adp->arg_type = AT_BYREF;
     96 		adp->arg_inout = AI_INOUT;
     97 		switch (cmd) {
     98 		case F_GETLK:
     99 		case F_SETLK:
    100 		case F_SETLKW:
    101 		case F_ALLOCSP:
    102 		case F_FREESP:
    103 			adp->arg_size = sizeof (struct flock);
    104 			break;
    105 #ifdef _LP64
    106 		case 33:
    107 		case 34:
    108 		case 35:
    109 		case 27:
    110 			adp->arg_size = sizeof (struct flock64_32);
    111 #else	/* _LP64 */
    112 		case F_GETLK64:
    113 		case F_SETLK64:
    114 		case F_SETLKW64:
    115 		case F_FREESP64:
    116 			adp->arg_size = sizeof (struct flock64);
    117 #endif	/* _LP64 */
    118 			break;
    119 		case F_SHARE:
    120 		case F_UNSHARE:
    121 			adp->arg_size = sizeof (struct fshare);
    122 			break;
    123 		default:
    124 			adp->arg_value = (long)argp;
    125 			adp->arg_object = NULL;
    126 			adp->arg_type = AT_BYVAL;
    127 			adp->arg_inout = AI_INPUT;
    128 			adp->arg_size = 0;
    129 			break;
    130 		}
    131 	}
    132 
    133 	error = Psyscall(Pr, &rval, SYS_fcntl, 3, &argd[0]);
    134 
    135 	if (error) {
    136 		errno = (error > 0)? error : ENOSYS;
    137 		return (-1);
    138 	}
    139 	return (rval.sys_rval1);
    140 }
    141