Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.inc.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ LIB_DIR=@EMC2_HOME@/lib
#used for install stuff
#but have them here as reference
#build system only uses EMC2_RTLIB_DIR when creating rtapi.conf
EMC2_TMP_DIR=@EMC2_TMP_DIR@
EMC2_BIN_DIR=@EMC2_BIN_DIR@
EMC2_TCL_DIR=@EMC2_TCL_DIR@
EMC2_HELP_DIR=@EMC2_HELP_DIR@
Expand Down
9 changes: 9 additions & 0 deletions src/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,7 @@ AC_DEFINE_UNQUOTED([EMC2_PO_DIR], "$EMC2_PO_DIR", [Directory for po/mo translati
AC_DEFINE_UNQUOTED([EMC2_NCFILES_DIR], "$EMC2_NCFILES_DIR", [Directory for nc files])
AC_DEFINE_UNQUOTED([EMC2_IMAGE_DIR], "$EMC2_IMAGE_DIR", [Directory for images])

AC_SUBST([EMC2_TMP_DIR])
AC_SUBST([EMC2_BIN_DIR])
AC_SUBST([EMC2_TCL_DIR])
AC_SUBST([EMC2_TCL_LIB_DIR])
Expand All @@ -771,6 +772,14 @@ LINUXCNC_AUX_EXAMPLES=/usr/share/linuxcnc/aux_examples
AC_SUBST([LINUXCNC_AUX_GLADEVCP])
AC_SUBST([LINUXCNC_AUX_EXAMPLES])

# define temporary directory
AC_ARG_WITH(tmpdir,
[ --with-tmpdir=PATH Specify path for temporary files],
tmpdir="$withval",
tmpdir="/tmp")
AC_DEFINE_UNQUOTED(EMC2_TMP_DIR, "$tmpdir/linuxcnc", [Temporary files directory])
AC_SUBST(EMC2_TMP_DIR, [$tmpdir])

##############################################################################
# Subsection 3.5 - check for GTK #
# FIXME: allow it to be enabled or disabled command line #
Expand Down
8 changes: 5 additions & 3 deletions src/emc/nml_intf/emc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1900,8 +1900,10 @@ void EMC_TASK_PLAN_OPEN::update(CMS * cms)
{

EMC_TASK_CMD_MSG::update(cms);
cms->update(file, 256);

cms->update(file, LINELEN);
cms->update(remote_filesize);
cms->update(remote_buffersize);
cms->update(remote_buffer, sizeof(remote_buffer));
}

/*
Expand Down Expand Up @@ -2154,4 +2156,4 @@ void EMC_MOTION_ADAPTIVE::update(CMS * cms)
void EMC_MOTION_CMD_MSG::update(CMS * cms)
{

}
}
7 changes: 7 additions & 0 deletions src/emc/nml_intf/emc_nml.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,14 @@ class EMC_TASK_PLAN_OPEN:public EMC_TASK_CMD_MSG {
// For internal NML/CMS use only.
void update(CMS * cms);

// (local) path to file
char file[LINELEN];
// total size of file in bytes (if issued from remote process, 0 otherwise)
size_t remote_filesize;
// amount of bytes currently in buffer (if issued from remote process, 0 otherwise)
size_t remote_buffersize;
// buffer used to transfer send a chunk of file contents (if loaded from remote process)
char remote_buffer[4096];
};

class EMC_TASK_PLAN_RUN:public EMC_TASK_CMD_MSG {
Expand Down
3 changes: 2 additions & 1 deletion src/emc/task/backtrace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include "config.h"

extern int done;
extern int emcOperatorError(const char *fmt, ...);
Expand All @@ -34,7 +35,7 @@ void backtrace(int signo)

signal(signo, SIG_IGN); // prevent multiple invocations on same signal
snprintf(pid_buf, sizeof(pid_buf), "%d", getpid());
snprintf(filename, sizeof(filename),"/tmp/backtrace.%s", pid_buf);
snprintf(filename, sizeof(filename), EMC2_TMP_DIR "/backtrace.%s", pid_buf);

name_buf[readlink("/proc/self/exe", name_buf, 511)]=0;
int child_pid = fork();
Expand Down
65 changes: 64 additions & 1 deletion src/emc/task/emctaskmain.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,7 @@ static int emcTaskIssueCommand(NMLmsg * cmd)
{
int retval = 0;
int execRetval = 0;
static char remote_tmpfilename[LINELEN]; // path to temporary file received from remote process

if (0 == cmd) {
if (emc_debug & EMC_DEBUG_TASK_ISSUE) {
Expand Down Expand Up @@ -2148,10 +2149,62 @@ static int emcTaskIssueCommand(NMLmsg * cmd)
} else {
retval = 0;
}
/* delete temporary copy of remote file if it exists */
if(remote_tmpfilename[0])
unlink(remote_tmpfilename);
break;

case EMC_TASK_PLAN_OPEN_TYPE:
open_msg = (EMC_TASK_PLAN_OPEN *) cmd;
open_msg = (EMC_TASK_PLAN_OPEN *) cmd;

/* receive file in chunks from remote process via open_msg->remote_buffer */
if(open_msg->remote_filesize > 0) {
static size_t received; // amount of bytes of file received, yet
static int fd; // temporary file

/* got empty chunk? */
if(open_msg->remote_buffersize == 0) {
rcs_print_error("EMC_TASK_PLAN_OPEN received empty chunk from remote process.\n");
retval = -1;
break;
}

/* this chunk belongs to a new file? */
if(received == 0) {
/* create new tempfile */
snprintf(remote_tmpfilename, LINELEN, EMC2_TMP_DIR "/%s.XXXXXX", basename(open_msg->file));
if((fd = mkstemp(remote_tmpfilename)) < 0) {
rcs_print_error("mkstemp(%s) error: %s", remote_tmpfilename, strerror(errno));
retval = -1;
break;
}
}

/* write chunk to tempfile */
size_t bytes_written = write(fd, open_msg->remote_buffer, open_msg->remote_buffersize);
if(bytes_written < open_msg->remote_buffersize) {
rcs_print_error("fwrite(%s) error: %s", remote_tmpfilename, strerror(errno));
retval = -1;
break;
}
/* record data written */
received += bytes_written;

/* not the last chunk? */
if(received < open_msg->remote_filesize) {
/* we're done here for now */
retval = 0;
break;
}
/* all chunks received - reset byte counter */
received = 0;
/* close file */
close(fd);
/* change filename to newly written local tmp file */
rtapi_strxcpy(open_msg->file, remote_tmpfilename);
}

/* open local file */
retval = emcTaskPlanOpen(open_msg->file);
if (retval > INTERP_MIN_ERROR) {
retval = -1;
Expand Down Expand Up @@ -3275,6 +3328,16 @@ int main(int argc, char *argv[])
exit(1);
}

// create EMC2_TMP_DIR if it's not existing, yet
struct stat s = {0};
if (stat(EMC2_TMP_DIR, &s) != 0) {
if(mkdir(EMC2_TMP_DIR, 0700) != 0) {
rcs_print_error("mkdir(%s): %s", EMC2_TMP_DIR, strerror(errno));
emctask_shutdown();
exit(1);
}
}

// get our status data structure
// moved up from emc_startup so we can expose it in Python right away
emcStatus = new EMC_STAT;
Expand Down
2 changes: 1 addition & 1 deletion src/emc/task/signalhandler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static void call_gdb(int sig, int start_gdb_in_window)
FILE *f;
char tmp_gdbrc[PATH_MAX];

snprintf(tmp_gdbrc, sizeof(tmp_gdbrc), "/tmp/gdbrc.%d",getpid());
snprintf(tmp_gdbrc, sizeof(tmp_gdbrc), EMC2_TMP_DIR "/gdbrc.%d",getpid());

if ((f = fopen(tmp_gdbrc,"w")) == NULL) {
perror(tmp_gdbrc);
Expand Down
3 changes: 2 additions & 1 deletion src/emc/tooldata/tooldata_mmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include "config.h"
#include "rtapi_mutex.h"
#include "tooldata.hh"

Expand Down Expand Up @@ -73,7 +74,7 @@ typedef struct {
static char* tool_mmap_fname(void) {
if (*filename) {return filename;}
char* hdir = secure_getenv("HOME");
if (!hdir) {hdir = (char*)"/tmp";}
if (!hdir) { hdir = (char *) EMC2_TMP_DIR; }
snprintf(filename,sizeof(filename),"%s/%s",hdir,TOOL_MMAP_FILENAME);
return(filename);
}
Expand Down
50 changes: 50 additions & 0 deletions src/emc/usr_intf/axis/extensions/emcmodule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,56 @@ static PyObject *program_open(pyCommandChannel *s, PyObject *o) {
return NULL;
}
strcpy(m.file, file);
/* clear optional fields */
m.remote_buffersize = 0;
m.remote_filesize = 0;

/* send file in chunks to linuxcnc via remote_buffer for remote processes */
if(s->s->cms->ProcessType == CMS_REMOTE_TYPE && strcmp(s->s->cms->ProcessName, "emc") != 0) {
/* open file */
FILE *fd;
if(!(fd = fopen(file, "r"))) {
PyErr_Format(PyExc_OSError, "fopen(%s) error: %s", file, strerror(errno));
return PyErr_SetFromErrno(PyExc_OSError);
}
/* get filesize */
if(fseek(fd, 0L, SEEK_END) != 0) {
fclose(fd);
PyErr_Format(PyExc_OSError, "fseek(%s) error: %s", file, strerror(errno));
return PyErr_SetFromErrno(PyExc_OSError);
}
if((m.remote_filesize = ftell(fd)) < 0) {
fclose(fd);
PyErr_Format(PyExc_OSError, "ftell(%s) error: %s", file, strerror(errno));
return PyErr_SetFromErrno(PyExc_OSError);
}
if(fseek(fd, 0L, SEEK_SET) != 0) {
fclose(fd);
PyErr_Format(PyExc_OSError, "fseek(%s) error: %s", file, strerror(errno));
return PyErr_SetFromErrno(PyExc_OSError);
}

/* send complete file content in chunks of sizeof(msg.remote_buffer) */
while(!(feof(fd))) {
size_t bytes_read = fread(&m.remote_buffer, 1, sizeof(m.remote_buffer), fd);
/* read error? */
if(bytes_read <= 0 && ferror(fd)) {
PyErr_Format(PyExc_OSError, "fread(%s) error: %s", file, strerror(errno));
return PyErr_SetFromErrno(PyExc_OSError);
}
/* save amount of bytes written to buffer */
m.remote_buffersize = bytes_read;
/* send chunk */
if(emcSendCommand(s, m) < 0) {
PyErr_Format(PyExc_OSError, "emcSendCommand() error: %s");
return PyErr_SetFromErrno(PyExc_OSError);
}
}
fclose(fd);
Py_INCREF(Py_None);
return Py_None;
}

emcSendCommand(s, m);
Py_INCREF(Py_None);
return Py_None;
Expand Down
69 changes: 62 additions & 7 deletions src/emc/usr_intf/shcom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <inttypes.h>

Expand Down Expand Up @@ -934,20 +935,74 @@ static char lastProgramFile[LINELEN] = "";

int sendProgramOpen(char *program)
{
EMC_TASK_PLAN_OPEN emc_task_plan_open_msg;
int res = 0;
EMC_TASK_PLAN_OPEN msg;

// save this to run again
/* save this to run again */
rtapi_strxcpy(lastProgramFile, program);
/* store filename in message */
rtapi_strxcpy(msg.file, program);
/* clear optional fields */
msg.remote_buffersize = 0;
msg.remote_filesize = 0;
/* if we are a remote process, we send file in chunks to linuxcnc via remote_buffer */
if(emcCommandBuffer->cms->ProcessType == CMS_REMOTE_TYPE && strcmp(emcCommandBuffer->cms->ProcessName, "emc") != 0) {
/* open file */
FILE *fd;
if(!(fd = fopen(program, "r"))) {
rcs_print_error("fopen(%s) error: %s\n", program, strerror(errno));
return -1;
}
/* get filesize */
if(fseek(fd, 0L, SEEK_END) != 0) {
fclose(fd);
rcs_print_error("fseek(%s) error: %s\n", program, strerror(errno));
return -1;
}
if((msg.remote_filesize = ftell(fd)) < 0) {
fclose(fd);
rcs_print_error("ftell(%s) error: %s\n", program, strerror(errno));
return -1;
}
if(fseek(fd, 0L, SEEK_SET) != 0) {
fclose(fd);
rcs_print_error("fseek(%s) error: %s\n", program, strerror(errno));
return -1;
}

/* send complete file content in chunks of sizeof(msg.remote_buffer) */
while(!(feof(fd))) {
size_t bytes_read = fread(&msg.remote_buffer, 1, sizeof(msg.remote_buffer), fd);
/* read error? */
if(bytes_read <= 0 && ferror(fd)) {
rcs_print_error("fread(%s) error: %s\n", program, strerror(errno));
res = -1;
break;
}
/* save amount of bytes written to buffer */
msg.remote_buffersize = bytes_read;
/* send chunk */
emcCommandSend(msg);
/* error happened? */
if(emcCommandWaitDone() != 0) {
rcs_print_error("emcCommandSend() error\n");
res = -1;
break;
}
}
fclose(fd);
return res;
}

rtapi_strxcpy(emc_task_plan_open_msg.file, program);
emcCommandSend(emc_task_plan_open_msg);
/* local process, just send filename */
emcCommandSend(msg);
if (emcWaitType == EMC_WAIT_RECEIVED) {
return emcCommandWaitReceived();
return emcCommandWaitReceived();
} else if (emcWaitType == EMC_WAIT_DONE) {
return emcCommandWaitDone();
return emcCommandWaitDone();
}

return 0;
return res;
}

int sendProgramRun(int line)
Expand Down
3 changes: 2 additions & 1 deletion src/hal/classicladder/files_project.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <sys/types.h>
#endif
#include "classicladder.h"
#include "config.h"
#include "global.h"
#include "edit.h"
#include "calc.h"
Expand Down Expand Up @@ -107,7 +108,7 @@ void InitTempDir( void )
{
char * TmpEnv = getenv("TMP");
if ( TmpEnv==NULL )
TmpEnv = "/tmp";
TmpEnv = EMC2_TMP_DIR;

// get a single name directory
snprintf(TmpDirectory, sizeof(TmpDirectory), "%s/classicladder_tmp_XXXXXX", TmpEnv );
Expand Down
1 change: 1 addition & 0 deletions tcl/linuxcnc.tcl.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace eval linuxcnc {
variable HOME @EMC2_HOME@
variable TMP_DIR @EMC2_TMP_DIR@
variable BIN_DIR @EMC2_BIN_DIR@
variable TCL_DIR @EMC2_TCL_DIR@
variable TCL_LIB_DIR @EMC2_TCL_LIB_DIR@
Expand Down