source: psi/trunk/cutestuff/util/bconsole.cpp

Last change on this file was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 2.6 KB
Line 
1/*
2 * bconsole.cpp - ByteStream wrapper for stdin/stdout
3 * Copyright (C) 2003 Justin Karneges
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include"bconsole.h"
22
23#include<qsocketnotifier.h>
24#include<unistd.h>
25#include<fcntl.h>
26
27//----------------------------------------------------------------------------
28// BConsole
29//----------------------------------------------------------------------------
30class BConsole::Private
31{
32public:
33 Private() {}
34
35 QSocketNotifier *r, *w;
36 bool closing;
37 bool closed;
38};
39
40BConsole::BConsole(QObject *parent)
41:ByteStream(parent)
42{
43 d = new Private;
44 d->closing = false;
45 d->closed = false;
46
47 // set stdin/stdout to non-block
48 fcntl(0, F_SETFL, O_NONBLOCK);
49 fcntl(1, F_SETFL, O_NONBLOCK);
50
51 d->r = new QSocketNotifier(0, QSocketNotifier::Read);
52 connect(d->r, SIGNAL(activated(int)), SLOT(sn_read()));
53 d->w = 0;
54}
55
56BConsole::~BConsole()
57{
58 delete d->w;
59 delete d->r;
60 delete d;
61}
62
63bool BConsole::isOpen() const
64{
65 return (!d->closing && !d->closed);
66}
67
68void BConsole::close()
69{
70 if(d->closing || d->closed)
71 return;
72
73 if(bytesToWrite() > 0)
74 d->closing = true;
75 else {
76 ::fclose(stdout);
77 d->closed = true;
78 }
79}
80
81void BConsole::sn_read()
82{
83 QByteArray a(1024);
84 int r = ::read(0, a.data(), a.size());
85 if(r < 0) {
86 error(ErrRead);
87 }
88 else if(r == 0) {
89 connectionClosed();
90 }
91 else {
92 a.resize(r);
93 appendRead(a);
94 readyRead();
95 }
96}
97
98void BConsole::sn_write()
99{
100 d->w->deleteLater();
101 d->w = 0;
102
103 if(bytesToWrite() > 0)
104 tryWrite();
105 if(bytesToWrite() == 0 && d->closing) {
106 d->closing = false;
107 d->closed = true;
108 delayedCloseFinished();
109 }
110}
111
112int BConsole::tryWrite()
113{
114 // try a section of the write buffer
115 QByteArray a = takeWrite(1024, false);
116
117 // write it
118 int r = ::write(1, a.data(), a.size());
119 if(r < 0) {
120 error(ErrWrite);
121 return -1;
122 }
123
124 d->w = new QSocketNotifier(1, QSocketNotifier::Write);
125 connect(d->w, SIGNAL(activated(int)), SLOT(sn_write()));
126
127 takeWrite(r);
128 bytesWritten(r);
129 return r;
130}
Note: See TracBrowser for help on using the repository browser.