Skip to content

Commit 3400822

Browse files
authored
[unix] Flush now gives errors and flushes tx and rx (#900)
- Bonus less structs as many functions return nothing or error
1 parent b340407 commit 3400822

File tree

7 files changed

+98
-74
lines changed

7 files changed

+98
-74
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ For getting started with node-serialport, we recommend you begin with the follow
5656
* [`.pause()`](#module_serialport--SerialPort+pause)
5757
* [`.resume()`](#module_serialport--SerialPort+resume)
5858
* [`.close(callback)`](#module_serialport--SerialPort+close)
59-
* [`.flush([callback])`](#module_serialport--SerialPort+flush)
6059
* [`.set([options], [callback])`](#module_serialport--SerialPort+set)
60+
* [`.flush([callback])`](#module_serialport--SerialPort+flush)
6161
* [`.drain([callback])`](#module_serialport--SerialPort+drain)
6262
* [`Event: "data"`](#module_serialport--SerialPort+event_data)
6363
* [`Event: "error"`](#module_serialport--SerialPort+event_error)
@@ -399,20 +399,6 @@ Closes an open connection
399399
| callback | <code>errorCallback</code> | Called once a connection is closed. |
400400

401401

402-
-
403-
404-
<a name="module_serialport--SerialPort+flush"></a>
405-
406-
#### `serialPort.flush([callback])`
407-
Flushes data received but not read. See [`tcflush()`](http://linux.die.net/man/3/tcflush) for Mac/Linux and [`FlushFileBuffers`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439) for Windows.
408-
409-
**Kind**: instance method of <code>[SerialPort](#exp_module_serialport--SerialPort)</code>
410-
411-
| Param | Type | Description |
412-
| --- | --- | --- |
413-
| [callback] | <code>[errorCallback](#module_serialport--SerialPort..errorCallback)</code> | Called once the flush operation finishes. |
414-
415-
416402
-
417403

418404
<a name="module_serialport--SerialPort+set"></a>
@@ -433,6 +419,20 @@ Sets flags on an open port. Uses [`SetCommMask`](https://msdn.microsoft.com/en-u
433419
| [callback] | <code>[errorCallback](#module_serialport--SerialPort..errorCallback)</code> | | Called once the port's flags have been set. |
434420

435421

422+
-
423+
424+
<a name="module_serialport--SerialPort+flush"></a>
425+
426+
#### `serialPort.flush([callback])`
427+
Flush discards data received but not read and written but not transmitted. For more technical details see [`tcflush(fd, TCIFLUSH)`](http://linux.die.net/man/3/tcflush) for Mac/Linux and [`FlushFileBuffers`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439) for Windows.
428+
429+
**Kind**: instance method of <code>[SerialPort](#exp_module_serialport--SerialPort)</code>
430+
431+
| Param | Type | Description |
432+
| --- | --- | --- |
433+
| [callback] | <code>[errorCallback](#module_serialport--SerialPort..errorCallback)</code> | Called once the flush operation finishes. |
434+
435+
436436
-
437437

438438
<a name="module_serialport--SerialPort+drain"></a>

lib/serialport.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -478,25 +478,6 @@ SerialPort.prototype.close = function(callback) {
478478
}.bind(this));
479479
};
480480

481-
/**
482-
* Flushes data received but not read. See [`tcflush()`](http://linux.die.net/man/3/tcflush) for Mac/Linux and [`FlushFileBuffers`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439) for Windows.
483-
* @param {module:serialport~errorCallback=} callback Called once the flush operation finishes.
484-
*/
485-
SerialPort.prototype.flush = function(callback) {
486-
if (!this.isOpen) {
487-
debug('flush attempted, but port is not open');
488-
return this._error(new Error('Port is not open'), callback);
489-
}
490-
491-
SerialPortBinding.flush(this.fd, function(err, result) {
492-
if (err) {
493-
debug('SerialPortBinding.flush had an error', err);
494-
return this._error(err, callback);
495-
}
496-
if (callback) { callback.call(this, null, result) }
497-
}.bind(this));
498-
};
499-
500481
/**
501482
* Sets flags on an open port. Uses [`SetCommMask`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363257(v=vs.85).aspx) for windows and [`ioctl`](http://linux.die.net/man/4/tty_ioctl) for mac and linux.
502483
* @param {object=} options All options are operating system default when the port is opened. Every flag is set on each call to the provided or default values. If options isn't provided default options will be used.
@@ -538,6 +519,25 @@ SerialPort.prototype.set = function(options, callback) {
538519
}.bind(this));
539520
};
540521

522+
/**
523+
* Flush discards data received but not read and written but not transmitted. For more technical details see [`tcflush(fd, TCIFLUSH)`](http://linux.die.net/man/3/tcflush) for Mac/Linux and [`FlushFileBuffers`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439) for Windows.
524+
* @param {module:serialport~errorCallback=} callback Called once the flush operation finishes.
525+
*/
526+
SerialPort.prototype.flush = function(callback) {
527+
if (!this.isOpen) {
528+
debug('flush attempted, but port is not open');
529+
return this._error(new Error('Port is not open'), callback);
530+
}
531+
532+
SerialPortBinding.flush(this.fd, function(err, result) {
533+
if (err) {
534+
debug('SerialPortBinding.flush had an error', err);
535+
return this._error(err, callback);
536+
}
537+
if (callback) { callback.call(this, null, result) }
538+
}.bind(this));
539+
};
540+
541541
/**
542542
* Waits until all output data has been transmitted to the serial port. See [`tcdrain()`](http://linux.die.net/man/3/tcdrain) or [FlushFileBuffers()](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=vs.85).aspx) for more information.
543543
* @param {module:serialport~errorCallback=} callback Called once the drain operation returns.

src/serialport.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ NAN_METHOD(Close) {
371371
}
372372
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
373373

374-
CloseBaton* baton = new CloseBaton();
375-
memset(baton, 0, sizeof(CloseBaton));
374+
VoidBaton* baton = new VoidBaton();
375+
memset(baton, 0, sizeof(VoidBaton));
376376
baton->fd = info[0]->ToInt32()->Int32Value();
377377
baton->callback = new Nan::Callback(callback);
378378

@@ -385,7 +385,7 @@ NAN_METHOD(Close) {
385385

386386
void EIO_AfterClose(uv_work_t* req) {
387387
Nan::HandleScope scope;
388-
CloseBaton* data = static_cast<CloseBaton*>(req->data);
388+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
389389

390390
v8::Local<v8::Value> argv[1];
391391
if (data->errorString[0]) {
@@ -496,8 +496,8 @@ NAN_METHOD(Flush) {
496496
}
497497
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
498498

499-
FlushBaton* baton = new FlushBaton();
500-
memset(baton, 0, sizeof(FlushBaton));
499+
VoidBaton* baton = new VoidBaton();
500+
memset(baton, 0, sizeof(VoidBaton));
501501
baton->fd = fd;
502502
baton->callback = new Nan::Callback(callback);
503503

@@ -511,18 +511,17 @@ NAN_METHOD(Flush) {
511511
void EIO_AfterFlush(uv_work_t* req) {
512512
Nan::HandleScope scope;
513513

514-
FlushBaton* data = static_cast<FlushBaton*>(req->data);
514+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
515515

516-
v8::Local<v8::Value> argv[2];
516+
v8::Local<v8::Value> argv[1];
517517

518518
if (data->errorString[0]) {
519519
argv[0] = v8::Exception::Error(Nan::New<v8::String>(data->errorString).ToLocalChecked());
520-
argv[1] = Nan::Undefined();
521520
} else {
522-
argv[0] = Nan::Undefined();
523-
argv[1] = Nan::New<v8::Int32>(data->result);
521+
argv[0] = Nan::Null();
524522
}
525-
data->callback->Call(2, argv);
523+
524+
data->callback->Call(1, argv);
526525

527526
delete data->callback;
528527
delete data;
@@ -602,8 +601,8 @@ NAN_METHOD(Drain) {
602601
}
603602
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
604603

605-
DrainBaton* baton = new DrainBaton();
606-
memset(baton, 0, sizeof(DrainBaton));
604+
VoidBaton* baton = new VoidBaton();
605+
memset(baton, 0, sizeof(VoidBaton));
607606
baton->fd = fd;
608607
baton->callback = new Nan::Callback(callback);
609608

@@ -617,7 +616,7 @@ NAN_METHOD(Drain) {
617616
void EIO_AfterDrain(uv_work_t* req) {
618617
Nan::HandleScope scope;
619618

620-
DrainBaton* data = static_cast<DrainBaton*>(req->data);
619+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
621620

622621
v8::Local<v8::Value> argv[1];
623622

src/serialport.h

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,6 @@ struct QueuedWrite {
142142
}
143143
};
144144

145-
struct CloseBaton {
146-
int fd;
147-
Nan::Callback* callback;
148-
char errorString[ERROR_STRING_SIZE];
149-
};
150-
151145
struct ListResultItem {
152146
std::string comName;
153147
std::string manufacturer;
@@ -164,13 +158,6 @@ struct ListBaton {
164158
char errorString[ERROR_STRING_SIZE];
165159
};
166160

167-
struct FlushBaton {
168-
int fd;
169-
Nan::Callback* callback;
170-
int result;
171-
char errorString[ERROR_STRING_SIZE];
172-
};
173-
174161
struct SetBaton {
175162
int fd;
176163
Nan::Callback* callback;
@@ -183,10 +170,9 @@ struct SetBaton {
183170
bool brk;
184171
};
185172

186-
struct DrainBaton {
173+
struct VoidBaton {
187174
int fd;
188175
Nan::Callback* callback;
189-
int result;
190176
char errorString[ERROR_STRING_SIZE];
191177
};
192178

src/serialport_unix.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,8 @@ void EIO_Write(uv_work_t* req) {
375375
}
376376

377377
void EIO_Close(uv_work_t* req) {
378-
CloseBaton* data = static_cast<CloseBaton*>(req->data);
378+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
379+
379380
if (-1 == close(data->fd)) {
380381
snprintf(data->errorString, sizeof(data->errorString), "Error: %s, unable to close fd %d", strerror(errno), data->fd);
381382
}
@@ -671,12 +672,6 @@ void EIO_List(uv_work_t* req) {
671672
#endif
672673
}
673674

674-
void EIO_Flush(uv_work_t* req) {
675-
FlushBaton* data = static_cast<FlushBaton*>(req->data);
676-
677-
data->result = tcflush(data->fd, TCIFLUSH);
678-
}
679-
680675
void EIO_Set(uv_work_t* req) {
681676
SetBaton* data = static_cast<SetBaton*>(req->data);
682677

@@ -719,8 +714,17 @@ void EIO_Set(uv_work_t* req) {
719714
}
720715
}
721716

717+
void EIO_Flush(uv_work_t* req) {
718+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
719+
720+
if (-1 == tcflush(data->fd, TCIOFLUSH)) {
721+
snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot flush", strerror(errno));
722+
return;
723+
}
724+
}
725+
722726
void EIO_Drain(uv_work_t* req) {
723-
DrainBaton* data = static_cast<DrainBaton*>(req->data);
727+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
724728

725729
if (-1 == tcdrain(data->fd)) {
726730
snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot drain", strerror(errno));

src/serialport_win.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ void EIO_Write(uv_work_t* req) {
432432
}
433433

434434
void EIO_Close(uv_work_t* req) {
435-
CloseBaton* data = static_cast<CloseBaton*>(req->data);
435+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
436436

437437
g_closingHandles.push_back(data->fd);
438438

@@ -537,7 +537,7 @@ void EIO_List(uv_work_t* req) {
537537
}
538538

539539
void EIO_Flush(uv_work_t* req) {
540-
FlushBaton* data = static_cast<FlushBaton*>(req->data);
540+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
541541

542542
if (!FlushFileBuffers((HANDLE)data->fd)) {
543543
ErrorCodeToString("flushing connection (FlushFileBuffers)", GetLastError(), data->errorString);
@@ -546,7 +546,7 @@ void EIO_Flush(uv_work_t* req) {
546546
}
547547

548548
void EIO_Drain(uv_work_t* req) {
549-
DrainBaton* data = static_cast<DrainBaton*>(req->data);
549+
VoidBaton* data = static_cast<VoidBaton*>(req->data);
550550

551551
if (!FlushFileBuffers((HANDLE)data->fd)) {
552552
ErrorCodeToString("draining connection (FlushFileBuffers)", GetLastError(), data->errorString);

test/bindings.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,41 @@ describe('SerialPortBinding', function() {
306306
});
307307
});
308308

309+
describe('#flush', function() {
310+
it('errors when given a bad fd', function(done) {
311+
SerialPortBinding.flush(44, function(err) {
312+
assert.instanceOf(err, Error);
313+
done();
314+
});
315+
});
316+
317+
if (!testPort) {
318+
it('Cannot be tested further. Set the TEST_PORT env var with an available serialport for more testing.');
319+
return;
320+
}
321+
322+
beforeEach(function(done) {
323+
SerialPortBinding.open(testPort, defaultPortOpenOptions, function(err, fd) {
324+
assert.isNull(err);
325+
assert.isNumber(fd);
326+
this.fd = fd;
327+
done();
328+
}.bind(this));
329+
});
330+
331+
afterEach(function(done) {
332+
SerialPortBinding.close(this.fd, done);
333+
this.fd = null;
334+
});
335+
336+
it('flushes the port', function(done) {
337+
SerialPortBinding.flush(this.fd, function(err) {
338+
assert.isNull(err);
339+
done();
340+
});
341+
});
342+
});
343+
309344
describe('#set', function() {
310345
it('errors when given a bad fd', function(done) {
311346
SerialPortBinding.drain(44, function(err) {

0 commit comments

Comments
 (0)