ret = -EINVAL; if (pos < 0) goto unlock_out; /* we enforce 32-bit alignment for pos and count in unicode mode */ if (uni_mode && (pos | count) & 3) goto unlock_out;
poll = file->private_data; if (count && poll)
poll->event = 0;
read = 0;
ret = 0; while (count) { unsignedint this_round, skip = 0; int size;
vc = vcs_vc(inode, &viewed); if (!vc) {
ret = -ENXIO; break;
}
/* Check whether we are above size each round, *ascopy_to_userattheendofthisloop *couldsleep.
*/
size = vcs_size(vc, attr, uni_mode); if (size < 0) {
ret = size; break;
} if (pos >= size) break; if (count > size - pos)
count = size - pos;
this_round = count; if (this_round > CON_BUF_SIZE)
this_round = CON_BUF_SIZE;
/* Perform the whole read into the local con_buf. *Thenwecandroptheconsolespinlockandsafely *attempttomoveittouserspace.
*/
/* Finally, release the console semaphore while we push *allthedatatouserspacefromourtemporarybuffer. * *AKPM:Eventhoughit'sasemaphore,weshoulddropitbecause *thepagefaulthandlingcodemaywanttocallprintk().
*/
console_unlock();
ret = copy_to_user(buf, con_buf + skip, this_round);
console_lock();
/* odd pos -- the first single character */ if (pos & 1) {
count--;
c = *con_buf++;
vcs_scr_writew(vc, vc_compile_le16(c, vcs_scr_readw(vc, org)),
org);
org++;
pos++; if (++col == maxcol) {
org = screen_pos(vc, pos/2, viewed);
col = 0;
}
}
pos /= 2;
pos += maxcol - col;
/* even pos -- handle attr+character pairs */ while (count > 1) { unsignedshort w;
con_buf = (char *) __get_free_page(GFP_KERNEL); if (!con_buf) return -ENOMEM;
pos = *ppos;
/* Select the proper current console and verify *sanityofthesituationundertheconsolelock.
*/
console_lock();
attr = use_attributes(inode);
ret = -ENXIO;
vc = vcs_vc(inode, &viewed); if (!vc) goto unlock_out;
size = vcs_size(vc, attr, false); if (size < 0) {
ret = size; goto unlock_out;
}
ret = -EINVAL; if (pos < 0 || pos > size) goto unlock_out; if (count > size - pos)
count = size - pos;
written = 0; while (count) { unsignedint this_round = count;
if (this_round > CON_BUF_SIZE)
this_round = CON_BUF_SIZE;
/* Temporarily drop the console lock so that we can read *inthewritedatafromuserspacesafely.
*/
console_unlock();
ret = copy_from_user(con_buf, buf, this_round);
console_lock();
if (ret) {
this_round -= ret; if (!this_round) { /* Abort loop if no data were copied. Otherwise *failwith-EFAULT.
*/ if (written) break;
ret = -EFAULT; goto unlock_out;
}
}
/* The vc might have been freed or vcs_size might have changed *whileweslepttograbtheuserbuffer,sorecheck. *Returndatawrittenuptonowonfailure.
*/
vc = vcs_vc(inode, &viewed); if (!vc) { if (written) break;
ret = -ENXIO; goto unlock_out;
}
size = vcs_size(vc, attr, false); if (size < 0) { if (written) break;
ret = size; goto unlock_out;
} if (pos >= size) break; if (this_round > size - pos)
this_round = size - pos;
/* OK, now actually push the write to the console *underthelockusingthelocalkernelbuffer.
*/
if (!poll) { /* don't allocate anything if all we want is disable fasync */ if (!on) return0;
poll = vcs_poll_data_get(file); if (!poll) return -ENOMEM;
}
return fasync_helper(fd, file, on, &poll->fasync);
}
void vcs_make_sysfs(int index)
{
device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL, "vcs%u", index + 1);
device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 65), NULL, "vcsu%u", index + 1);
device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL, "vcsa%u", index + 1);
}
void vcs_remove_sysfs(int index)
{
device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 1));
device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 65));
device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 129));
}
int __init vcs_init(void)
{ unsignedint i;
if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
panic("unable to get major %d for vcs device", VCS_MAJOR); if (class_register(&vc_class))
panic("unable to create vc_class");
device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 64), NULL, "vcsu");
device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); for (i = 0; i < MIN_NR_CONSOLES; i++)
vcs_make_sysfs(i); return0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.