| OLD | NEW |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library fletch_agent.agent; | 5 library dartino_agent.agent; |
| 6 | 6 |
| 7 import 'dart:convert' show UTF8; | 7 import 'dart:convert' show UTF8; |
| 8 import 'dart:fletch'; | 8 import 'dart:dartino'; |
| 9 import 'dart:fletch.ffi'; | 9 import 'dart:dartino.ffi'; |
| 10 import 'dart:fletch.os' as os; | 10 import 'dart:dartino.os' as os; |
| 11 import 'dart:typed_data'; | 11 import 'dart:typed_data'; |
| 12 | 12 |
| 13 import 'package:ffi/ffi.dart'; | 13 import 'package:ffi/ffi.dart'; |
| 14 import 'package:file/file.dart'; | 14 import 'package:file/file.dart'; |
| 15 import 'package:fletch/fletch.dart' as fletch; | 15 import 'package:dartino/dartino.dart' as dartino; |
| 16 import 'package:os/os.dart' show sys; | 16 import 'package:os/os.dart' show sys; |
| 17 import 'package:socket/socket.dart'; | 17 import 'package:socket/socket.dart'; |
| 18 | 18 |
| 19 import '../lib/messages.dart'; | 19 import '../lib/messages.dart'; |
| 20 | 20 |
| 21 class Logger { | 21 class Logger { |
| 22 final String _prefix; | 22 final String _prefix; |
| 23 final String _path; | 23 final String _path; |
| 24 final bool _logToStdout; | 24 final bool _logToStdout; |
| 25 | 25 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 return cStringToString(ptr); | 66 return cStringToString(ptr); |
| 67 } | 67 } |
| 68 | 68 |
| 69 // Agent specific info. | 69 // Agent specific info. |
| 70 final String ip; | 70 final String ip; |
| 71 final int port; | 71 final int port; |
| 72 final String pidFile; | 72 final String pidFile; |
| 73 final Logger logger; | 73 final Logger logger; |
| 74 final bool applyUpgrade; | 74 final bool applyUpgrade; |
| 75 | 75 |
| 76 // Fletch-vm path and args. | 76 // Dartino-vm path and args. |
| 77 final String vmBinPath; | 77 final String vmBinPath; |
| 78 final String vmLogDir; | 78 final String vmLogDir; |
| 79 final String tmpDir; | 79 final String tmpDir; |
| 80 | 80 |
| 81 factory AgentContext() { | 81 factory AgentContext() { |
| 82 String ip = _getEnv('AGENT_IP'); | 82 String ip = _getEnv('AGENT_IP'); |
| 83 if (ip == null) { | 83 if (ip == null) { |
| 84 ip = '0.0.0.0'; | 84 ip = '0.0.0.0'; |
| 85 } | 85 } |
| 86 int port; | 86 int port; |
| 87 try { | 87 try { |
| 88 String portStr = _getEnv('AGENT_PORT'); | 88 String portStr = _getEnv('AGENT_PORT'); |
| 89 port = int.parse(portStr); | 89 port = int.parse(portStr); |
| 90 } catch (_) { | 90 } catch (_) { |
| 91 port = AGENT_DEFAULT_PORT; // default | 91 port = AGENT_DEFAULT_PORT; // default |
| 92 } | 92 } |
| 93 String logFile = _getEnv('AGENT_LOG_FILE'); | 93 String logFile = _getEnv('AGENT_LOG_FILE'); |
| 94 if (logFile == null) { | 94 if (logFile == null) { |
| 95 print('Agent requires a valid log file. Please specify file path in ' | 95 print('Agent requires a valid log file. Please specify file path in ' |
| 96 'the AGENT_LOG_FILE environment variable.'); | 96 'the AGENT_LOG_FILE environment variable.'); |
| 97 Process.exit(); | 97 Process.exit(); |
| 98 } | 98 } |
| 99 var logger = new Logger('Agent', logFile); | 99 var logger = new Logger('Agent', logFile); |
| 100 String pidFile = _getEnv('AGENT_PID_FILE'); | 100 String pidFile = _getEnv('AGENT_PID_FILE'); |
| 101 if (pidFile == null) { | 101 if (pidFile == null) { |
| 102 logger.error('Agent requires a valid pid file. Please specify file path ' | 102 logger.error('Agent requires a valid pid file. Please specify file path ' |
| 103 'in the AGENT_PID_FILE environment variable.'); | 103 'in the AGENT_PID_FILE environment variable.'); |
| 104 Process.exit(); | 104 Process.exit(); |
| 105 } | 105 } |
| 106 String vmBinPath = _getEnv('FLETCH_VM'); | 106 String vmBinPath = _getEnv('DARTINO_VM'); |
| 107 String vmLogDir = _getEnv('VM_LOG_DIR'); | 107 String vmLogDir = _getEnv('VM_LOG_DIR'); |
| 108 String tmpDir = _getEnv('TMPDIR'); | 108 String tmpDir = _getEnv('TMPDIR'); |
| 109 if (tmpDir == null) tmpDir = '/tmp'; | 109 if (tmpDir == null) tmpDir = '/tmp'; |
| 110 | 110 |
| 111 // If the below ENV variable is set the agent will just store the agent | 111 // If the below ENV variable is set the agent will just store the agent |
| 112 // debian package but not apply it. | 112 // debian package but not apply it. |
| 113 bool applyUpgrade = _getEnv('AGENT_UPGRADE_DRY_RUN') == null; | 113 bool applyUpgrade = _getEnv('AGENT_UPGRADE_DRY_RUN') == null; |
| 114 | 114 |
| 115 logger.info('Agent log file: $logFile'); | 115 logger.info('Agent log file: $logFile'); |
| 116 logger.info('Agent pid file: $pidFile'); | 116 logger.info('Agent pid file: $pidFile'); |
| 117 logger.info('Vm path: $vmBinPath'); | 117 logger.info('Vm path: $vmBinPath'); |
| 118 logger.info('Log path: $vmLogDir'); | 118 logger.info('Log path: $vmLogDir'); |
| 119 | 119 |
| 120 // Make sure we have a fletch-vm binary we can use for launching a vm. | 120 // Make sure we have a dartino-vm binary we can use for launching a vm. |
| 121 if (!File.existsAsFile(vmBinPath)) { | 121 if (!File.existsAsFile(vmBinPath)) { |
| 122 logger.error('Cannot find fletch vm at path: $vmBinPath'); | 122 logger.error('Cannot find dartino vm at path: $vmBinPath'); |
| 123 Process.exit(); | 123 Process.exit(); |
| 124 } | 124 } |
| 125 // Make sure we have a valid log directory. | 125 // Make sure we have a valid log directory. |
| 126 if (!File.existsAsFile(vmLogDir)) { | 126 if (!File.existsAsFile(vmLogDir)) { |
| 127 logger.error('Cannot find log directory: $vmLogDir'); | 127 logger.error('Cannot find log directory: $vmLogDir'); |
| 128 Process.exit(); | 128 Process.exit(); |
| 129 } | 129 } |
| 130 return new AgentContext._( | 130 return new AgentContext._( |
| 131 ip, port, pidFile, logger, vmBinPath, vmLogDir, tmpDir, applyUpgrade); | 131 ip, port, pidFile, logger, vmBinPath, vmLogDir, tmpDir, applyUpgrade); |
| 132 } | 132 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 break; | 205 break; |
| 206 case RequestHeader.STOP_VM: | 206 case RequestHeader.STOP_VM: |
| 207 _stopVm(); | 207 _stopVm(); |
| 208 break; | 208 break; |
| 209 case RequestHeader.LIST_VMS: | 209 case RequestHeader.LIST_VMS: |
| 210 _listVms(); | 210 _listVms(); |
| 211 break; | 211 break; |
| 212 case RequestHeader.UPGRADE_AGENT: | 212 case RequestHeader.UPGRADE_AGENT: |
| 213 _upgradeAgent(); | 213 _upgradeAgent(); |
| 214 break; | 214 break; |
| 215 case RequestHeader.FLETCH_VERSION: | 215 case RequestHeader.DARTINO_VERSION: |
| 216 _fletchVersion(); | 216 _dartinoVersion(); |
| 217 break; | 217 break; |
| 218 case RequestHeader.SIGNAL_VM: | 218 case RequestHeader.SIGNAL_VM: |
| 219 _signalVm(); | 219 _signalVm(); |
| 220 break; | 220 break; |
| 221 default: | 221 default: |
| 222 _context.logger.warn('Unknown command: ${_requestHeader.command}.'); | 222 _context.logger.warn('Unknown command: ${_requestHeader.command}.'); |
| 223 _sendReply( | 223 _sendReply( |
| 224 new ReplyHeader(_requestHeader.id, ReplyHeader.UNKNOWN_COMMAND)); | 224 new ReplyHeader(_requestHeader.id, ReplyHeader.UNKNOWN_COMMAND)); |
| 225 break; | 225 break; |
| 226 } | 226 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 238 File portFile = new File.temporary("${_context.tmpDir}/vm-port-"); | 238 File portFile = new File.temporary("${_context.tmpDir}/vm-port-"); |
| 239 try { | 239 try { |
| 240 List<String> args = ['--log-dir=${_context.vmLogDir}', | 240 List<String> args = ['--log-dir=${_context.vmLogDir}', |
| 241 '--port-file=${portFile.path}', '--host=0.0.0.0']; | 241 '--port-file=${portFile.path}', '--host=0.0.0.0']; |
| 242 vmPid = os.NativeProcess.startDetached(_context.vmBinPath, args); | 242 vmPid = os.NativeProcess.startDetached(_context.vmBinPath, args); |
| 243 // Find out what port the vm is listening on. | 243 // Find out what port the vm is listening on. |
| 244 _context.logger.info('Reading port from ${portFile.path} for vm $vmPid'); | 244 _context.logger.info('Reading port from ${portFile.path} for vm $vmPid'); |
| 245 int port = _retrieveVmPort(portFile.path); | 245 int port = _retrieveVmPort(portFile.path); |
| 246 reply = new StartVmReply( | 246 reply = new StartVmReply( |
| 247 _requestHeader.id, ReplyHeader.SUCCESS, vmId: vmPid, vmPort: port); | 247 _requestHeader.id, ReplyHeader.SUCCESS, vmId: vmPid, vmPort: port); |
| 248 _context.logger.info('Started fletch vm with pid $vmPid on port $port'); | 248 _context.logger.info('Started dartino vm with pid $vmPid on port $port'); |
| 249 } catch (e) { | 249 } catch (e) { |
| 250 reply = new StartVmReply(_requestHeader.id, ReplyHeader.START_VM_FAILED); | 250 reply = new StartVmReply(_requestHeader.id, ReplyHeader.START_VM_FAILED); |
| 251 // TODO(wibling): could extend the result with caught error string. | 251 // TODO(wibling): could extend the result with caught error string. |
| 252 _context.logger.warn('Failed to start vm with error: $e'); | 252 _context.logger.warn('Failed to start vm with error: $e'); |
| 253 if (vmPid > 0) { | 253 if (vmPid > 0) { |
| 254 // Kill the vm. | 254 // Kill the vm. |
| 255 _kill.icall$2(vmPid, SIGTERM); | 255 _kill.icall$2(vmPid, SIGTERM); |
| 256 } | 256 } |
| 257 } finally { | 257 } finally { |
| 258 File.delete(portFile.path); | 258 File.delete(portFile.path); |
| 259 } | 259 } |
| 260 _sendReply(reply); | 260 _sendReply(reply); |
| 261 } | 261 } |
| 262 | 262 |
| 263 int _retrieveVmPort(String portPath) { | 263 int _retrieveVmPort(String portPath) { |
| 264 // The fletch-vm will write the port it is listening on into the file | 264 // The dartino-vm will write the port it is listening on into the file |
| 265 // specified by 'portPath' above. The agent waits for the file to be | 265 // specified by 'portPath' above. The agent waits for the file to be |
| 266 // created (retries the File.open until it succeeds) and then reads the | 266 // created (retries the File.open until it succeeds) and then reads the |
| 267 // port from the file. | 267 // port from the file. |
| 268 // To make sure we are reading a consistent value from the file, ie. the | 268 // To make sure we are reading a consistent value from the file, ie. the |
| 269 // vm could have written a partial value at the time we read it, we continue | 269 // vm could have written a partial value at the time we read it, we continue |
| 270 // reading the value from the file until we have read the same value from | 270 // reading the value from the file until we have read the same value from |
| 271 // file in two consecutive reads. | 271 // file in two consecutive reads. |
| 272 // An alternative to the consecutive reading would be to use cooperative | 272 // An alternative to the consecutive reading would be to use cooperative |
| 273 // locking, but consecutive reading is not relying on the fletch-vm to | 273 // locking, but consecutive reading is not relying on the dartino-vm to |
| 274 // behave. | 274 // behave. |
| 275 // TODO(wibling): Look into passing a socket port to the fletch-vm and | 275 // TODO(wibling): Look into passing a socket port to the dartino-vm and |
| 276 // have it write the port to the socket. This allows the agent to just | 276 // have it write the port to the socket. This allows the agent to just |
| 277 // wait on the socket and wake up when it is ready. | 277 // wait on the socket and wake up when it is ready. |
| 278 int previousPort = -1; | 278 int previousPort = -1; |
| 279 for (int retries = 500; retries >= 0; --retries) { | 279 for (int retries = 500; retries >= 0; --retries) { |
| 280 int port = _tryReadPort(portPath, retries == 0); | 280 int port = _tryReadPort(portPath, retries == 0); |
| 281 // Check if we read the same port value twice in a row. | 281 // Check if we read the same port value twice in a row. |
| 282 if (previousPort != -1 && previousPort == port) return port; | 282 if (previousPort != -1 && previousPort == port) return port; |
| 283 previousPort = port; | 283 previousPort = port; |
| 284 os.sleep(10); | 284 os.sleep(10); |
| 285 } | 285 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 314 if (_requestHeader.payloadLength != 4) { | 314 if (_requestHeader.payloadLength != 4) { |
| 315 _sendReply( | 315 _sendReply( |
| 316 new StopVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD)); | 316 new StopVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD)); |
| 317 return; | 317 return; |
| 318 } | 318 } |
| 319 var reply; | 319 var reply; |
| 320 // Read in the vm id. | 320 // Read in the vm id. |
| 321 var pidBytes = _socket.read(4); | 321 var pidBytes = _socket.read(4); |
| 322 if (pidBytes == null) { | 322 if (pidBytes == null) { |
| 323 reply = new StopVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD); | 323 reply = new StopVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD); |
| 324 _context.logger.warn('Missing pid of the fletch vm to stop.'); | 324 _context.logger.warn('Missing pid of the dartino vm to stop.'); |
| 325 } else { | 325 } else { |
| 326 int pid = readUint32(pidBytes, 0); | 326 int pid = readUint32(pidBytes, 0); |
| 327 int err = _kill.icall$2(pid, SIGTERM); | 327 int err = _kill.icall$2(pid, SIGTERM); |
| 328 if (err != 0) { | 328 if (err != 0) { |
| 329 reply = new StopVmReply(_requestHeader.id, ReplyHeader.UNKNOWN_VM_ID); | 329 reply = new StopVmReply(_requestHeader.id, ReplyHeader.UNKNOWN_VM_ID); |
| 330 _context.logger.warn( | 330 _context.logger.warn( |
| 331 'Failed to stop pid $pid with error: ${Foreign.errno}'); | 331 'Failed to stop pid $pid with error: ${Foreign.errno}'); |
| 332 } else { | 332 } else { |
| 333 reply = new StopVmReply(_requestHeader.id, ReplyHeader.SUCCESS); | 333 reply = new StopVmReply(_requestHeader.id, ReplyHeader.SUCCESS); |
| 334 _context.logger.info('Stopped pid: $pid'); | 334 _context.logger.info('Stopped pid: $pid'); |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 _sendReply(reply); | 337 _sendReply(reply); |
| 338 } | 338 } |
| 339 | 339 |
| 340 void _signalVm() { | 340 void _signalVm() { |
| 341 if (_requestHeader.payloadLength != 8) { | 341 if (_requestHeader.payloadLength != 8) { |
| 342 _sendReply( | 342 _sendReply( |
| 343 new SignalVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD)); | 343 new SignalVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD)); |
| 344 return; | 344 return; |
| 345 } | 345 } |
| 346 var reply; | 346 var reply; |
| 347 // Read in the vm id and the signal to send. | 347 // Read in the vm id and the signal to send. |
| 348 var pidBytes = _socket.read(8); | 348 var pidBytes = _socket.read(8); |
| 349 if (pidBytes == null) { | 349 if (pidBytes == null) { |
| 350 reply = new SignalVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD); | 350 reply = new SignalVmReply(_requestHeader.id, ReplyHeader.INVALID_PAYLOAD); |
| 351 _context.logger.warn('Missing pid of the fletch vm to signal.'); | 351 _context.logger.warn('Missing pid of the dartino vm to signal.'); |
| 352 } else { | 352 } else { |
| 353 int pid = readUint32(pidBytes, 0); | 353 int pid = readUint32(pidBytes, 0); |
| 354 int signal = readUint32(pidBytes, 4); | 354 int signal = readUint32(pidBytes, 4); |
| 355 // Hack to make ctrl-c work for stopping spawned vms work on Raspbian | 355 // Hack to make ctrl-c work for stopping spawned vms work on Raspbian |
| 356 // wheezy. For some reason SIGINT doesn't work so we map it to SIGTERM as | 356 // wheezy. For some reason SIGINT doesn't work so we map it to SIGTERM as |
| 357 // a workaround. | 357 // a workaround. |
| 358 if (signal == SIGINT && sys.info().release.startsWith('3.18')) { | 358 if (signal == SIGINT && sys.info().release.startsWith('3.18')) { |
| 359 _context.logger.info('Remapping SIGINT to SIGTERM on Raspbian wheezy'); | 359 _context.logger.info('Remapping SIGINT to SIGTERM on Raspbian wheezy'); |
| 360 signal = SIGTERM; | 360 signal = SIGTERM; |
| 361 } | 361 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 375 void _listVms() { | 375 void _listVms() { |
| 376 // TODO(wibling): implement this method. For now just hardcode some values. | 376 // TODO(wibling): implement this method. For now just hardcode some values. |
| 377 _sendReply( | 377 _sendReply( |
| 378 new ListVmsReply(_requestHeader.id, ReplyHeader.UNKNOWN_COMMAND)); | 378 new ListVmsReply(_requestHeader.id, ReplyHeader.UNKNOWN_COMMAND)); |
| 379 } | 379 } |
| 380 | 380 |
| 381 void _upgradeAgent() { | 381 void _upgradeAgent() { |
| 382 int result; | 382 int result; |
| 383 ByteBuffer binary = _socket.read(_requestHeader.payloadLength); | 383 ByteBuffer binary = _socket.read(_requestHeader.payloadLength); |
| 384 if (binary == null) { | 384 if (binary == null) { |
| 385 _context.logger.warn('Could not read fletch-agent package binary' | 385 _context.logger.warn('Could not read dartino-agent package binary' |
| 386 ' of length ${_requestHeader.payloadLength} bytes'); | 386 ' of length ${_requestHeader.payloadLength} bytes'); |
| 387 result = ReplyHeader.INVALID_PAYLOAD; | 387 result = ReplyHeader.INVALID_PAYLOAD; |
| 388 } else { | 388 } else { |
| 389 _context.logger.info('Read fletch-agent package binary' | 389 _context.logger.info('Read dartino-agent package binary' |
| 390 ' of length ${binary.lengthInBytes} bytes.'); | 390 ' of length ${binary.lengthInBytes} bytes.'); |
| 391 File file = new File.open(PACKAGE_FILE_NAME, mode: File.WRITE); | 391 File file = new File.open(PACKAGE_FILE_NAME, mode: File.WRITE); |
| 392 try { | 392 try { |
| 393 file.write(binary); | 393 file.write(binary); |
| 394 } catch (e) { | 394 } catch (e) { |
| 395 _context.logger.warn('UpgradeAgent failed: $e'); | 395 _context.logger.warn('UpgradeAgent failed: $e'); |
| 396 _sendReply(new UpgradeAgentReply(_requestHeader.id, | 396 _sendReply(new UpgradeAgentReply(_requestHeader.id, |
| 397 ReplyHeader.UPGRADE_FAILED)); | 397 ReplyHeader.UPGRADE_FAILED)); |
| 398 } finally { | 398 } finally { |
| 399 file.close(); | 399 file.close(); |
| 400 } | 400 } |
| 401 _context.logger.info('Package file written successfully.'); | 401 _context.logger.info('Package file written successfully.'); |
| 402 if (_context.applyUpgrade) { | 402 if (_context.applyUpgrade) { |
| 403 int pid = os.NativeProcess.startDetached('/usr/bin/dpkg', | 403 int pid = os.NativeProcess.startDetached('/usr/bin/dpkg', |
| 404 [// Force dpkg to overwrite configuration files installed by | 404 [// Force dpkg to overwrite configuration files installed by |
| 405 // the agent. | 405 // the agent. |
| 406 '--force-confnew', | 406 '--force-confnew', |
| 407 '--install', | 407 '--install', |
| 408 PACKAGE_FILE_NAME]); | 408 PACKAGE_FILE_NAME]); |
| 409 _context.logger.info('started package update (PID $pid)'); | 409 _context.logger.info('started package update (PID $pid)'); |
| 410 } | 410 } |
| 411 result = ReplyHeader.SUCCESS; | 411 result = ReplyHeader.SUCCESS; |
| 412 } | 412 } |
| 413 _context.logger.info('sending reply'); | 413 _context.logger.info('sending reply'); |
| 414 _sendReply(new UpgradeAgentReply(_requestHeader.id, result)); | 414 _sendReply(new UpgradeAgentReply(_requestHeader.id, result)); |
| 415 } | 415 } |
| 416 | 416 |
| 417 void _fletchVersion() { | 417 void _dartinoVersion() { |
| 418 String version = fletch.version(); | 418 String version = dartino.version(); |
| 419 _context.logger.info('Returning fletch version $version'); | 419 _context.logger.info('Returning dartino version $version'); |
| 420 _sendReply(new FletchVersionReply( | 420 _sendReply(new DartinoVersionReply( |
| 421 _requestHeader.id, ReplyHeader.SUCCESS, version: version)); | 421 _requestHeader.id, ReplyHeader.SUCCESS, version: version)); |
| 422 } | 422 } |
| 423 } | 423 } |
| 424 | 424 |
| 425 void main(List<String> arguments) { | 425 void main(List<String> arguments) { |
| 426 // The agent context will initialize itself from the runtime environment. | 426 // The agent context will initialize itself from the runtime environment. |
| 427 var context = new AgentContext(); | 427 var context = new AgentContext(); |
| 428 | 428 |
| 429 // Write the program's pid to the pid file if set. | 429 // Write the program's pid to the pid file if set. |
| 430 _writePid(context.pidFile); | 430 _writePid(context.pidFile); |
| 431 | 431 |
| 432 // Run fletch agent on given ip address and port. | 432 // Run dartino agent on given ip address and port. |
| 433 var agent = new Agent(context); | 433 var agent = new Agent(context); |
| 434 agent.start(); | 434 agent.start(); |
| 435 } | 435 } |
| 436 | 436 |
| 437 void _writePid(String pidFilePath) { | 437 void _writePid(String pidFilePath) { |
| 438 final ForeignFunction _getpid = ForeignLibrary.main.lookup('getpid'); | 438 final ForeignFunction _getpid = ForeignLibrary.main.lookup('getpid'); |
| 439 | 439 |
| 440 int pid = _getpid.icall$0(); | 440 int pid = _getpid.icall$0(); |
| 441 List<int> encodedPid = UTF8.encode('$pid'); | 441 List<int> encodedPid = UTF8.encode('$pid'); |
| 442 ByteBuffer buffer = new Uint8List.fromList(encodedPid).buffer; | 442 ByteBuffer buffer = new Uint8List.fromList(encodedPid).buffer; |
| 443 var pidFile = new File.open(pidFilePath, mode: File.WRITE); | 443 var pidFile = new File.open(pidFilePath, mode: File.WRITE); |
| 444 try { | 444 try { |
| 445 pidFile.write(buffer); | 445 pidFile.write(buffer); |
| 446 } finally { | 446 } finally { |
| 447 pidFile.close(); | 447 pidFile.close(); |
| 448 } | 448 } |
| 449 } | 449 } |
| 450 | 450 |
| 451 void printUsage() { | 451 void printUsage() { |
| 452 print('Usage:'); | 452 print('Usage:'); |
| 453 print('The Fletch agent supports the following flags'); | 453 print('The Dartino agent supports the following flags'); |
| 454 print(''); | 454 print(''); |
| 455 print(' --port: specify the port on which to listen, default: ' | 455 print(' --port: specify the port on which to listen, default: ' |
| 456 '$AGENT_DEFAULT_PORT'); | 456 '$AGENT_DEFAULT_PORT'); |
| 457 print(' --ip: specify the ip address on which to listen, default: 0.0.0.0'); | 457 print(' --ip: specify the ip address on which to listen, default: 0.0.0.0'); |
| 458 print(' --vm: specify the path to the vm binary, default: ' | 458 print(' --vm: specify the path to the vm binary, default: ' |
| 459 '/opt/fletch/bin/fletch-vm.'); | 459 '/opt/dartino/bin/dartino-vm.'); |
| 460 print(''); | 460 print(''); |
| 461 Process.exit(); | 461 Process.exit(); |
| 462 } | 462 } |
| OLD | NEW |