1 /* fhandler_raw.cc. See fhandler.h for a description of the fhandler classes.
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
12 #include <cygwin/rdevio.h>
14 #include <sys/param.h>
19 /**********************************************************************/
20 /* fhandler_dev_raw */
22 fhandler_dev_raw::fhandler_dev_raw ()
26 need_fork_fixup (true);
29 fhandler_dev_raw::~fhandler_dev_raw ()
32 delete [] devbufalloc
;
36 fhandler_dev_raw::fstat (struct stat
*buf
)
38 debug_printf ("here");
40 fhandler_base::fstat (buf
);
43 if (get_major () == DEV_TAPE_MAJOR
)
44 buf
->st_mode
= S_IFCHR
| STD_RBITS
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
46 buf
->st_mode
= S_IFBLK
| STD_RBITS
| STD_WBITS
| S_IWGRP
| S_IWOTH
;
48 if (get_major () == DEV_SD_HIGHPART_END
&& get_minor () == 9999)
49 buf
->st_ino
= get_ino ();
50 buf
->st_uid
= geteuid ();
51 buf
->st_gid
= getegid ();
53 buf
->st_blksize
= PREFERRED_IO_BLKSIZE
;
54 time_as_timestruc_t (&buf
->st_ctim
);
55 buf
->st_atim
= buf
->st_mtim
= buf
->st_birthtim
= buf
->st_ctim
;
61 fhandler_dev_raw::open (int flags
, mode_t
)
63 /* Check for illegal flags. */
64 if (get_major () != DEV_TAPE_MAJOR
&& (flags
& O_APPEND
))
70 /* Always open a raw device existing and binary. */
71 flags
&= ~(O_CREAT
| O_TRUNC
);
74 /* Write-only doesn't work well with raw devices */
75 if ((flags
& O_ACCMODE
) == O_WRONLY
)
76 flags
= ((flags
& ~O_WRONLY
) | O_RDWR
);
78 int res
= fhandler_base::open (flags
, 0);
84 fhandler_dev_raw::dup (fhandler_base
*child
, int flags
)
86 int ret
= fhandler_base::dup (child
, flags
);
90 fhandler_dev_raw
*fhc
= (fhandler_dev_raw
*) child
;
94 /* Create sector-aligned buffer */
95 fhc
->devbufalloc
= new char [devbufsiz
+ devbufalign
];
96 fhc
->devbuf
= (char *) roundup2 ((uintptr_t) fhc
->devbufalloc
,
97 (uintptr_t) devbufalign
);
101 fhc
->lastblk_to_read (false);
107 fhandler_dev_raw::fixup_after_fork (HANDLE parent
)
109 fhandler_base::fixup_after_fork (parent
);
112 lastblk_to_read (false);
116 fhandler_dev_raw::fixup_after_exec ()
118 if (!close_on_exec ())
122 /* Create sector-aligned buffer */
123 devbufalloc
= new char [devbufsiz
+ devbufalign
];
124 devbuf
= (char *) roundup2 ((uintptr_t) devbufalloc
,
125 (uintptr_t) devbufalign
);
129 lastblk_to_read (false);
134 fhandler_dev_raw::ioctl (unsigned int cmd
, void *buf
)
140 struct rdop
*op
= (struct rdop
*) buf
;
143 ret
= ERROR_INVALID_PARAMETER
;
148 if (get_major () == DEV_TAPE_MAJOR
)
152 mop
.mt_op
= MTSETBLK
;
153 mop
.mt_count
= op
->rd_parm
;
154 ret
= ioctl (MTIOCTOP
, &mop
);
156 else if ((op
->rd_parm
<= 1 && get_major () != DEV_TAPE_MAJOR
)
157 || (op
->rd_parm
> 1 && (op
->rd_parm
% devbufalign
))
158 || (get_flags () & O_DIRECT
))
159 /* The conditions for a valid parameter are:
160 - The new size is either 0 or 1, both indicating unbuffered
161 I/O, and the device is a tape device.
162 - Or, the new buffersize must be a multiple of the
163 required buffer alignment.
164 - In the O_DIRECT case, the whole request is invalid. */
165 ret
= ERROR_INVALID_PARAMETER
;
166 else if (!devbuf
|| op
->rd_parm
!= devbufsiz
)
169 off_t curpos
= lseek (0, SEEK_CUR
);
171 if (op
->rd_parm
> 1L)
172 buf
= new char [op
->rd_parm
+ devbufalign
];
175 delete [] devbufalloc
;
178 devbuf
= (char *) roundup2 ((uintptr_t) buf
,
179 (uintptr_t) devbufalign
);
180 devbufsiz
= op
->rd_parm
?: 1L;
181 devbufstart
= devbufend
= 0;
182 lseek (curpos
, SEEK_SET
);
189 else if (cmd
== RDIOCGET
)
191 struct rdget
*get
= (struct rdget
*) buf
;
194 ret
= ERROR_INVALID_PARAMETER
;
196 get
->bufsiz
= devbufsiz
;
199 return fhandler_base::ioctl (cmd
, buf
);