/****** uti/afsutil/sge_read_token() ****************************************** * NAME * sge_read_token() -- read token from file * * SYNOPSIS * char* sge_read_token(const char *file) * * FUNCTION * Read token from file, malloc buffer, add '\0' byte and * return pointer to buffer. * * INPUTS * const char *file - filename * * NOTES * MT-NOTE: sge_read_token() is MT safe * * RESULT * char* - pointer to a malloced buffer or * NULL if error occured ******************************************************************************/ char *sge_read_token(const char *file) { SGE_STRUCT_STAT sb; int fd; char *tokenbuf; size_t size; DENTER(TOP_LAYER, "sge_read_token"); if (SGE_STAT(file, &sb)) { DTRACE; return NULL; } size = sb.st_size + 1; if (((SGE_OFF_T)size != sb.st_size + 1) || (tokenbuf = (char *) malloc(size)) == NULL) { DTRACE; return NULL; } if ((fd = SGE_OPEN2(file, O_RDONLY)) == -1) { DTRACE; return NULL; } if (read(fd, tokenbuf, sb.st_size) != sb.st_size) { DTRACE; close(fd); return NULL; } tokenbuf[sb.st_size] = '\0'; close(fd); DEXIT; return tokenbuf; }
/****** uti/io/sge_copy_append() ********************************************** * NAME * sge_copy_append() -- Copy/append one file to another * * SYNOPSIS * int sge_copy_append(char *src, const char *dst, * sge_mode_t mode) * * FUNCTION * Copy/append content from 'src' to 'dst' * * INPUTS * char *src - source filename * const char *dst - destination filename * sge_mode_t mode - mode * * RESULT * int - error state * 0 - OK * -1 - Error * * SEE ALSO * uti/io/sge_mode_t * * NOTES * MT-NOTE: sge_copy_append() is MT safe ******************************************************************************/ int sge_copy_append(char *src, const char *dst, sge_mode_t mode) { #define CPBUF 1024 char buf[CPBUF]; int fdsrc, fddst, modus, rs, ws; bool error; DENTER(TOP_LAYER, "sge_copy_append"); if (src == NULL || dst == NULL || strlen(src) == 0 || strlen(dst) == 0 || !(mode == SGE_MODE_APPEND || mode == SGE_MODE_COPY)) { DEXIT; return -1; } if (!strcmp(src, dst)) { DEXIT; return -1; } /* Return if source file doesn't exist */ if ((fdsrc = SGE_OPEN2(src, O_RDONLY)) == -1) { DEXIT; return -1; } if (mode == SGE_MODE_APPEND) modus = O_WRONLY | O_APPEND | O_CREAT; else modus = O_WRONLY | O_CREAT; if ((fddst = SGE_OPEN3(dst, modus, 0666)) == -1) { DEXIT; return -1; } error = false; while (!error) { rs = read(fdsrc, buf, 512); if (rs == -1 && errno == EINTR) continue; else if (rs == -1) error = true; if (!error && rs > 0) { while (!error) { ws = write(fddst, buf, rs); if (ws == -1 && errno == EINTR) continue; else if (ws == -1) { error = true; break; } else break; } } if (error) break; if (rs == 0) break; } close(fdsrc); close(fddst); DEXIT; return (error ? -1: 0); }
/****** err_trace/shepherd_trace_init_intern() ******************************* * NAME * shepherd_trace_init_intern() -- Initialize shepherd's tracing. * * SYNOPSIS * static FILE* shepherd_trace_init(char *trace_file_path, * char *trace_file_name) * * FUNCTION * Opens the shepherd's trace file and sets the FD_CLOEXEC-flag so it will * be closed automatically in an exec()-call. * Must be called with euid=admin user to work properly! * * INPUTS * char *trace_file_path - either the whole path of the trace file (including * the file itself) * or NULL to retrieve the file pointer of an already * opened trace file. * char *trace_file_name - the name of the trace file itself. Ignored when * *trace_file_path is NULL. * * RESULT * FILE* - If successfully opened, the file pointer of shepherd's trace file. * - Otherwise NULL. *******************************************************************************/ static FILE* shepherd_trace_init_intern(st_shepherd_file_t shepherd_file) { static char path[SGE_PATH_MAX]; static bool called = false; SGE_STRUCT_STAT statbuf; dstring ds; char buffer[SGE_PATH_MAX+128]; char tmppath[SGE_PATH_MAX]; int fd = -1; FILE *fp = NULL; int do_chown = 0; /* * after changing into the jobs cwd we need an * absolute path to the error/trace file */ if (called == false) { getcwd(path, sizeof(path)); called=true; } snprintf(tmppath, SGE_PATH_MAX,"%s/%s",path, g_shepherd_file_name[shepherd_file]); sge_strlcpy(g_shepherd_file_path[shepherd_file], tmppath, SGE_PATH_MAX); /* If the file does not exist, create it. Otherwise just open it. */ if (SGE_STAT(tmppath, &statbuf)) { fd = SGE_OPEN3(tmppath, O_RDWR | O_CREAT | O_APPEND, 0644); if (fd<0) { sge_dstring_init(&ds, buffer, sizeof(buffer)); sge_dstring_sprintf(&ds, "creat(%s) failed: %s", tmppath, strerror(errno)); shepherd_panic(buffer); } if (getuid() == SGE_SUPERUSER_UID) { /* We must give the file to the job owner later */ do_chown = 1; } else { /* We are not root, so we have to own all files anyway. */ do_chown = 0; } } else { /* The file already exists. We get here when * a) a exec() failed or * b) after the execution of prolog/job, when the job/epilog * tries to init the error/exit status files. * * In a root system we can just open the file, because we are either * root or the job user who owns the file. * In a admin user system we must set our euid to root to open it, then * it is the same as the root system. * In a test user system we are the owner of the file and can open it. * * When we are root (masked or not), we gave this file to the * prolog user/job user right after its creation. But we can have * 3 different users for prolog, job and epilog, so we must give * the file here to the next user. * This must be done via shepherd_trace_chown() in the shepherd * before we switch to this user there. * It can't be done here because we don't know if we are in * case a) (exec failed) or case b) (after execution of prolog/job). */ int old_euid = SGE_SUPERUSER_UID; /* * Work around for CR 6293411: * See shepherd_trace_exit() for details. */ if (getuid() == SGE_SUPERUSER_UID) { old_euid = geteuid(); seteuid(SGE_SUPERUSER_UID); } fd = SGE_OPEN2(tmppath, O_RDWR | O_APPEND); if (fd<0) { sge_dstring_init(&ds, buffer, sizeof(buffer)); sge_dstring_sprintf(&ds, "open(%s) failed: %s", tmppath, strerror(errno)); shepherd_panic(buffer); } do_chown = 0; /* * Switch back to admin user? */ if (old_euid != SGE_SUPERUSER_UID) { seteuid(old_euid); } } /* Something went wrong. */ if (fd<0) { return NULL; } /* To avoid to block stdin, stdout or stderr, dup the fd until it is >= 3 */ if (fd<3) { dup_fd(&fd); } /* Set FD_CLOEXEC flag to automatically close the file in an exec() */ if (!set_cloexec(fd)) { shepherd_panic("set_cloexec() failed"); return NULL; } /* * Now open a FILE* from the file descriptor, so we can use fprintf(). */ fp = fdopen(fd, "a"); if (!fp) { sge_dstring_init(&ds, buffer, sizeof(buffer)); sge_dstring_sprintf(&ds, "can't open %s file \"%s\": %s\n", g_shepherd_file_name[shepherd_file], tmppath, strerror(errno)); shepherd_panic(buffer); return NULL; } if (do_chown && strlen(g_job_owner) > 0) { shepherd_trace_chown_intern(g_job_owner, fp, shepherd_file); } return fp; }