- c = to->ldisc.receive_room(to);
- if (c > count)
- c = count;
- to->ldisc.receive_buf(to, buf, NULL, c);
+ if (from_user) {
+ down(&tty->flip.pty_sem);
+ temp_buffer = &tty->flip.char_buf[0];
+ while (count > 0) {
+ /* check space so we don't copy needlessly */
+ n = to->ldisc.receive_room(to);
+ if (n > count)
+ n = count;
+ if (!n) break;
+
+ n = min(n, PTY_BUF_SIZE);
+ n -= copy_from_user(temp_buffer, buf, n);
+ if (!n) {
+ if (!c)
+ c = -EFAULT;
+ break;
+ }
+
+ /* check again in case the buffer filled up */
+ room = to->ldisc.receive_room(to);
+ if (n > room)
+ n = room;
+ if (!n) break;
+ buf += n;
+ c += n;
+ count -= n;
+ to->ldisc.receive_buf(to, temp_buffer, NULL, n);
+ }
+ up(&tty->flip.pty_sem);
+ } else {
+ c = to->ldisc.receive_room(to);
+ if (c > count)
+ c = count;
+ to->ldisc.receive_buf(to, buf, NULL, c);
+ }