bin_drv.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 223 行

C
223
字号
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ *//* Purpose:    Binary file driver interface , used for code loading */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "sys.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "erl_driver.h"#include <errno.h>#ifdef NO_UMASK#define FILE_MODE 0644#else#define FILE_MODE 0666#endifstatic int this_port;static long bin_start();static int bin_init(),bin_stop(),bin_erlang_read();static int read_fill(), write_fill();const struct erl_drv_entry bin_driver_entry = {    bin_init,    bin_start,    bin_stop,    bin_erlang_read,    NULL,    NULL,    "binary_filer"};static int bin_init(){    this_port = -1;}static long bin_start(port,buf) int port;char *buf;{    if (this_port != -1)	return(-1);    this_port = port;    return(port);}static int bin_stop(){    this_port = -1;} static int bin_erlang_read(port,buf,count)long port;char *buf;int count;{    struct stat statbuf;    int i,size,fd,rval;    char *t,*rbuf;        buf[count] = '\0';    switch (*buf) {    case 'c' :	if (chdir(buf+1) == 0)     /* sucsess */	    driver_output(this_port,"y",1);	else	    driver_output(this_port,"n",1);	return 0;    case 'f':#ifdef MSDOS	if ((fd = open(buf+1,O_RDONLY|O_BINARY)) < 0) {#else	if ((fd = open(buf+1,O_RDONLY, 0)) < 0) {#endif	    driver_output(this_port,"n",1);	    return 0;	}	if (stat(buf+1,&statbuf) < 0) {	    driver_output(this_port,"n",1);	    close(fd);	    return 0;	}	if (S_ISREG(statbuf.st_mode)) 	    size = statbuf.st_size;	else	    size = BUFSIZ;	    	if ((rbuf = (char*) driver_alloc(1 + size)) == NULL) {	    fprintf(stderr,"Out of memory\n");	    close(fd);	    driver_output(this_port,"n",1);	    return 0;	}	if (S_ISREG(statbuf.st_mode)) {	    if (read_fill(fd,1+rbuf,size) != size) {		driver_free(rbuf);		close(fd);		driver_output(this_port,"n",1);		return 0;;	    }	}	/* The idea here is that if it's a regular file read the entire 	 * entire file and if it's a device file or a tty try to read 	 * until errno != EINTR          */	else {	    while (1) {		rval = read(fd,1+rbuf,size);		if (rval < 0 && errno == EINTR)		    continue;		if (rval < 0) {		    driver_free(rbuf);		    close(fd);		    driver_output(this_port,"n",1);		    return 0;		}		size = rval;		break;	    }	}	rbuf[0] = 'y';	driver_output(this_port,rbuf,1+size);	driver_free(rbuf);	close(fd);	return 0;    case 'w':#ifdef MSDOS	if ((fd = open(buf+1, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,		       FILE_MODE)) < 0) {#else	if ((fd = open(buf+1, O_WRONLY | O_CREAT | O_TRUNC, FILE_MODE)) < 0) {#endif	    driver_output(this_port,"n",1);	    return 0;	}	t = buf+1; i = 1;	while(*t && i++ < count) t++;	t++;	/* t now points to the contents of what we shall write */	size = count - 1 - i;		/* gotta write_fill if we are writing to a slow device 	   such as /dev/audio */		if (write_fill (fd,t,size) !=  size) {	    driver_output(this_port,"n",1);	    close(fd);	    return 0;	}	driver_output(this_port,"y",1);	close(fd);	return 0;    default:	driver_failure(this_port,-1);	return 0;    }}static int write_fill(fd, buf, len)char *buf;{    int i, done = 0;        do {	if ((i = write(fd, buf+done, len-done)) < 0) {	    if (errno != EINTR)		return (i);	    i = 0;	}	done += i;    } while (done < len);    return (len);}static int read_fill(fd, buf, len)char *buf;{    int i, got = 0;    do {	if ((i = read(fd, buf+got, len-got)) <= 0) {	    if (i == 0 || errno != EINTR)		return (i);	    i = 0;	}	got += i;    } while (got < len);    return (len);}    

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?