1 /* fhandler_virtual.cc: base fhandler class for virtual filesystems
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10 #include <cygwin/acl.h>
11 #include <sys/statvfs.h>
18 #include "child_info.h"
22 fhandler_virtual::fhandler_virtual ():
23 fhandler_base (), filebuf (NULL
), fileid (-1)
27 fhandler_virtual::~fhandler_virtual ()
37 fhandler_virtual::fixup_after_exec ()
42 fhandler_virtual::opendir (int fd
)
48 if (!virt_ftype_isdir (exists ()))
50 else if ((len
= strlen (get_name ())) > PATH_MAX
- 3)
51 set_errno (ENAMETOOLONG
);
52 else if ((dir
= (DIR *) malloc (sizeof (DIR))) == NULL
)
54 else if ((dir
->__d_dirname
= (char *) malloc (len
+ 3)) == NULL
)
59 else if ((dir
->__d_dirent
=
60 (struct dirent
*) malloc (sizeof (struct dirent
))) == NULL
)
62 free (dir
->__d_dirname
);
68 strcpy (dir
->__d_dirname
, get_name ());
69 dir
->__d_dirent
->__d_version
= __DIRENT_VERSION
;
70 dir
->__d_cookie
= __DIRENT_COOKIE
;
71 dir
->__handle
= INVALID_HANDLE_VALUE
;
72 dir
->__d_position
= 0;
84 if (cfd
>= 0 && open (O_RDONLY
, 0))
95 syscall_printf ("%p = opendir (%s)", res
, get_name ());
100 fhandler_virtual::telldir (DIR * dir
)
102 return dir
->__d_position
;
106 fhandler_virtual::seekdir (DIR * dir
, long loc
)
108 dir
->__flags
|= dirent_saw_dot
| dirent_saw_dot_dot
;
109 dir
->__d_position
= loc
;
113 fhandler_virtual::rewinddir (DIR * dir
)
115 dir
->__d_position
= 0;
116 dir
->__flags
|= dirent_saw_dot
| dirent_saw_dot_dot
;
120 fhandler_virtual::closedir (DIR * dir
)
126 fhandler_virtual::lseek (off_t offset
, int whence
)
129 * On Linux, when you lseek within a /proc file,
130 * the contents of the file are updated.
132 if (!fill_filebuf ())
143 position
= filesize
+ offset
;
153 fhandler_virtual::dup (fhandler_base
* child
, int flags
)
155 int ret
= fhandler_base::dup (child
, flags
);
159 fhandler_virtual
*fhproc_child
= (fhandler_virtual
*) child
;
160 fhproc_child
->filebuf
= (char *) cmalloc_abort (HEAP_BUF
, filesize
);
161 memcpy (fhproc_child
->filebuf
, filebuf
, filesize
);
167 fhandler_virtual::close ()
181 fhandler_virtual::read (void *ptr
, size_t& len
)
196 if ((ssize_t
) len
> filesize
- position
)
197 len
= (size_t) (filesize
- position
);
198 if ((ssize_t
) len
< 0)
201 memcpy (ptr
, filebuf
+ position
, len
);
206 fhandler_virtual::write (const void *ptr
, size_t len
)
212 /* low-level open for all proc files */
214 fhandler_virtual::open (int flags
, mode_t mode
)
219 set_flags ((flags
& ~O_TEXT
) | O_BINARY
);
225 fhandler_virtual::exists ()
231 fhandler_virtual::fill_filebuf ()
237 fhandler_virtual::fchmod (mode_t mode
)
239 /* Same as on Linux. */
245 fhandler_virtual::fchown (uid_t uid
, gid_t gid
)
247 /* Same as on Linux. */
253 fhandler_virtual::facl (int cmd
, int nentries
, aclent_t
*aclbufp
)
255 int res
= fhandler_base::facl (cmd
, nentries
, aclbufp
);
256 if (res
>= 0 && cmd
== GETACL
)
258 aclbufp
[0].a_perm
= (S_IRUSR
| (pc
.isdir () ? S_IXUSR
: 0)) >> 6;
259 aclbufp
[1].a_perm
= (S_IRGRP
| (pc
.isdir () ? S_IXGRP
: 0)) >> 3;
260 aclbufp
[2].a_perm
= S_IROTH
| (pc
.isdir () ? S_IXOTH
: 0);
266 fhandler_virtual::fstatvfs (struct statvfs
*sfs
)
268 /* Virtual file system. Just return an empty buffer with a few values
269 set to something useful. Just as on Linux. */
270 memset (sfs
, 0, sizeof (*sfs
));
271 sfs
->f_bsize
= sfs
->f_frsize
= 4096;
272 sfs
->f_flag
= ST_RDONLY
;
273 sfs
->f_namemax
= NAME_MAX
;