1 /* This file contains a few general purpose utility routines.
3 * The entry points into this file are
4 * copy_path: copy a path name from a path request from userland
5 * fetch_name: go get a path name from user space
6 * panic: something awful has occurred; MINIX cannot continue
7 * in_group: determines if group 'grp' is in rfp->fp_sgroups[]
11 #include <minix/callnr.h>
12 #include <minix/endpoint.h>
21 /*===========================================================================*
23 *===========================================================================*/
24 int copy_path(char *dest
, size_t size
)
26 /* Go get the path for a path request. Put the result in in 'dest', which
27 * should be at least PATH_MAX in size.
32 assert(size
>= PATH_MAX
);
34 name
= job_m_in
.m_lc_vfs_path
.name
;
35 len
= job_m_in
.m_lc_vfs_path
.len
;
37 if (len
> size
) { /* 'len' includes terminating-nul */
38 err_code
= ENAMETOOLONG
;
42 /* Is the string contained in the message? If not, perform a normal copy. */
43 if (len
> M_PATH_STRING_MAX
)
44 return fetch_name(name
, len
, dest
);
46 /* Just copy the path from the message */
47 strncpy(dest
, job_m_in
.m_lc_vfs_path
.buf
, len
);
49 if (dest
[len
- 1] != '\0') {
50 err_code
= ENAMETOOLONG
;
57 /*===========================================================================*
59 *===========================================================================*/
60 int fetch_name(vir_bytes path
, size_t len
, char *dest
)
62 /* Go get path and put it in 'dest'. */
65 if (len
> PATH_MAX
) { /* 'len' includes terminating-nul */
66 err_code
= ENAMETOOLONG
;
70 /* Check name length for validity. */
71 if (len
> SSIZE_MAX
) {
76 /* String is not contained in the message. Get it from user space. */
77 r
= sys_datacopy_wrapper(who_e
, path
, VFS_PROC_NR
, (vir_bytes
) dest
, len
);
83 if (dest
[len
- 1] != '\0') {
84 err_code
= ENAMETOOLONG
;
91 /*===========================================================================*
93 *===========================================================================*/
94 int isokendpt_f(const char *file
, int line
, endpoint_t endpoint
, int *proc
,
99 *proc
= _ENDPOINT_P(endpoint
);
100 if (endpoint
== NONE
) {
101 printf("VFS %s:%d: endpoint is NONE\n", file
, line
);
103 } else if (*proc
< 0 || *proc
>= NR_PROCS
) {
104 printf("VFS %s:%d: proc (%d) from endpoint (%d) out of range\n",
105 file
, line
, *proc
, endpoint
);
107 } else if ((ke
= fproc
[*proc
].fp_endpoint
) != endpoint
) {
109 assert(fproc
[*proc
].fp_pid
== PID_FREE
);
111 printf("VFS %s:%d: proc (%d) from endpoint (%d) doesn't match "
112 "known endpoint (%d)\n", file
, line
, *proc
, endpoint
,
113 fproc
[*proc
].fp_endpoint
);
114 assert(fproc
[*proc
].fp_pid
!= PID_FREE
);
120 panic("isokendpt_f failed");
122 return(failed
? EDEADEPT
: OK
);
125 /*===========================================================================*
127 *===========================================================================*/
128 int in_group(struct fproc
*rfp
, gid_t grp
)
132 for (i
= 0; i
< rfp
->fp_ngroups
; i
++)
133 if (rfp
->fp_sgroups
[i
] == grp
)
139 /*===========================================================================*
140 * sys_datacopy_wrapper *
141 *===========================================================================*/
142 int sys_datacopy_wrapper(endpoint_t src
, vir_bytes srcv
,
143 endpoint_t dst
, vir_bytes dstv
, size_t len
)
145 /* Safe function to copy data from or to a user buffer.
146 * VFS has to be a bit more careful as a regular copy
147 * might trigger VFS action needed by VM while it's
148 * blocked on the kernel call. This wrapper tries the
149 * copy, invokes VM itself asynchronously if necessary,
150 * then tries the copy again.
152 * This function assumes it's between VFS and a user process,
153 * and therefore one of the endpoints is SELF (VFS).
156 endpoint_t them
= NONE
;
157 vir_bytes themv
= -1;
160 r
= sys_datacopy_try(src
, srcv
, dst
, dstv
, len
);
162 if(src
== VFS_PROC_NR
) src
= SELF
;
163 if(dst
== VFS_PROC_NR
) dst
= SELF
;
165 assert(src
== SELF
|| dst
== SELF
);
167 if(src
== SELF
) { them
= dst
; themv
= dstv
; writable
= 1; }
168 if(dst
== SELF
) { them
= src
; themv
= srcv
; writable
= 0; }
170 assert(writable
>= 0);
171 assert(them
!= SELF
);
174 /* The copy has failed with EFAULT, this means the kernel has
175 * given up but it might not be a legitimate error. Ask VM.
177 if((r
=vm_vfs_procctl_handlemem(them
, themv
, len
, writable
)) != OK
) {
181 r
= sys_datacopy_try(src
, srcv
, dst
, dstv
, len
);