Change all cursor positioning functions to use sub-structures rather than the whole state structure, and if turning off cursor positioning, do so via a new flag "cursor->disable" rather than changing the operator-supplied options in "control" (#165).
This commit is contained in:
@@ -352,6 +352,7 @@ struct pvstate_s {
|
||||
#ifdef HAVE_IPC
|
||||
bool noipc; /* set if we can't use IPC */
|
||||
#endif /* HAVE_IPC */
|
||||
bool disable; /* set if cursor positioning can't be used */
|
||||
} cursor;
|
||||
|
||||
/*******************
|
||||
@@ -563,10 +564,9 @@ pvdisplay_bytecount_t pv_formatter_sgr(pvformatter_args_t);
|
||||
bool pv_format (pvprogramstatus_t, readonly_pvcontrol_t,
|
||||
readonly_pvtransferstate_t, readonly_pvtransfercalc_t,
|
||||
/*@null@ */ const char *, pvdisplay_t, bool, bool);
|
||||
void pv_display (pvstate_t, pvprogramstatus_t, readonly_pvcontrol_t,
|
||||
pvtransientflags_t, readonly_pvtransferstate_t,
|
||||
pvtransfercalc_t, pvcursorstate_t, pvdisplay_t, /*@null@ */
|
||||
pvdisplay_t, bool);
|
||||
void pv_display (pvprogramstatus_t, readonly_pvcontrol_t, pvtransientflags_t,
|
||||
readonly_pvtransferstate_t, pvtransfercalc_t,
|
||||
pvcursorstate_t, pvdisplay_t, /*@null@ */ pvdisplay_t, bool);
|
||||
|
||||
ssize_t pv_transfer(pvstate_t, int, bool *, bool *, off_t, long *);
|
||||
int pv_next_file(pvstate_t, unsigned int, int);
|
||||
@@ -575,11 +575,11 @@ int pv_next_file(pvstate_t, unsigned int, int);
|
||||
void pv_write_retry(int, const char *, size_t);
|
||||
void pv_tty_write(readonly_pvtransientflags_t, const char *, size_t);
|
||||
|
||||
void pv_crs_fini(pvstate_t);
|
||||
void pv_crs_init(pvstate_t);
|
||||
void pv_crs_update(pvstate_t, const char *);
|
||||
void pv_crs_fini(pvcursorstate_t, readonly_pvcontrol_t, pvtransientflags_t);
|
||||
void pv_crs_init(pvcursorstate_t, readonly_pvcontrol_t, pvtransientflags_t);
|
||||
void pv_crs_update(pvcursorstate_t, readonly_pvcontrol_t, pvtransientflags_t, const char *);
|
||||
#ifdef HAVE_IPC
|
||||
void pv_crs_needreinit(pvstate_t);
|
||||
void pv_crs_needreinit(pvcursorstate_t);
|
||||
#endif
|
||||
|
||||
void pv_sig_allowpause(void);
|
||||
|
||||
+143
-136
@@ -47,24 +47,24 @@
|
||||
* Create a per-euid, per-tty, lockfile in ${TMPDIR:-${TMP:-/tmp}} for the
|
||||
* tty on the given file descriptor.
|
||||
*/
|
||||
static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
static void pv_crs_open_lockfile(pvcursorstate_t cursor, readonly_pvcontrol_t control, int fd)
|
||||
{
|
||||
char *ttydev;
|
||||
char *tmpdir;
|
||||
int openflags;
|
||||
|
||||
state->cursor.lock_fd = -1;
|
||||
cursor->lock_fd = -1;
|
||||
|
||||
ttydev = ttyname(fd);
|
||||
if (!ttydev) {
|
||||
if (!state->control.force) {
|
||||
if (!control->force) {
|
||||
pv_error("%s: %s", _("failed to get terminal name"), strerror(errno));
|
||||
}
|
||||
/*
|
||||
* If we don't know our terminal name, we can neither do IPC
|
||||
* nor make a lock file, so turn off cursor positioning.
|
||||
*/
|
||||
state->control.cursor = 0;
|
||||
cursor->disable = true;
|
||||
debug("%s", "ttyname failed - cursor positioning disabled");
|
||||
return;
|
||||
}
|
||||
@@ -80,8 +80,8 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
* $TMP are rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
|
||||
memset(state->cursor.lock_file, 0, PV_SIZEOF_CRS_LOCK_FILE);
|
||||
(void) pv_snprintf(state->cursor.lock_file,
|
||||
memset(cursor->lock_file, 0, PV_SIZEOF_CRS_LOCK_FILE);
|
||||
(void) pv_snprintf(cursor->lock_file,
|
||||
PV_SIZEOF_CRS_LOCK_FILE, "%s/pv-%s-%i.lock", tmpdir, basename(ttydev), (int) geteuid());
|
||||
|
||||
/*
|
||||
@@ -93,7 +93,7 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
openflags = O_RDWR | O_CREAT;
|
||||
#endif
|
||||
|
||||
state->cursor.lock_fd = open(state->cursor.lock_file, openflags, 0600); /* flawfinder: ignore */
|
||||
cursor->lock_fd = open(cursor->lock_file, openflags, 0600); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale: we aren't truncating the lock file, we
|
||||
@@ -102,9 +102,9 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
* open() is as safe as we can make it.
|
||||
*/
|
||||
|
||||
if (state->cursor.lock_fd < 0) {
|
||||
pv_error("%s: %s: %s", state->cursor.lock_file, _("failed to open lock file"), strerror(errno));
|
||||
state->control.cursor = 0;
|
||||
if (cursor->lock_fd < 0) {
|
||||
pv_error("%s: %s: %s", cursor->lock_file, _("failed to open lock file"), strerror(errno));
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -114,14 +114,14 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
* Lock the terminal on the given file descriptor, falling back to using a
|
||||
* lockfile if the terminal itself cannot be locked.
|
||||
*/
|
||||
static void pv_crs_lock(pvstate_t state, int fd)
|
||||
static void pv_crs_lock(pvcursorstate_t cursor, readonly_pvcontrol_t control, int fd)
|
||||
{
|
||||
struct flock lock;
|
||||
int lock_fd;
|
||||
|
||||
lock_fd = fd;
|
||||
if (state->cursor.lock_fd >= 0)
|
||||
lock_fd = state->cursor.lock_fd;
|
||||
if (cursor->lock_fd >= 0)
|
||||
lock_fd = cursor->lock_fd;
|
||||
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = (short) F_WRLCK;
|
||||
@@ -130,10 +130,10 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
lock.l_len = 1;
|
||||
while (fcntl(lock_fd, F_SETLKW, &lock) < 0) {
|
||||
if (errno != EINTR) {
|
||||
if (state->cursor.lock_fd == -2) {
|
||||
pv_crs_open_lockfile(state, fd);
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
lock_fd = state->cursor.lock_fd;
|
||||
if (cursor->lock_fd == -2) {
|
||||
pv_crs_open_lockfile(cursor, control, fd);
|
||||
if (cursor->lock_fd >= 0) {
|
||||
lock_fd = cursor->lock_fd;
|
||||
}
|
||||
} else {
|
||||
pv_error("%s: %s", _("lock attempt failed"), strerror(errno));
|
||||
@@ -142,8 +142,8 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
}
|
||||
}
|
||||
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
debug("%s: %s", state->cursor.lock_file, "terminal lockfile acquired");
|
||||
if (cursor->lock_fd >= 0) {
|
||||
debug("%s: %s", cursor->lock_file, "terminal lockfile acquired");
|
||||
} else {
|
||||
debug("%s", "terminal lock acquired");
|
||||
}
|
||||
@@ -154,14 +154,14 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
* Unlock the terminal on the given file descriptor. If pv_crs_lock used
|
||||
* lockfile locking, unlock the lockfile.
|
||||
*/
|
||||
static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
static void pv_crs_unlock(pvcursorstate_t cursor, int fd)
|
||||
{
|
||||
struct flock lock;
|
||||
int lock_fd;
|
||||
|
||||
lock_fd = fd;
|
||||
if (state->cursor.lock_fd >= 0)
|
||||
lock_fd = state->cursor.lock_fd;
|
||||
if (cursor->lock_fd >= 0)
|
||||
lock_fd = cursor->lock_fd;
|
||||
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = (short) F_UNLCK;
|
||||
@@ -170,8 +170,8 @@ static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
lock.l_len = 1;
|
||||
(void) fcntl(lock_fd, F_SETLK, &lock);
|
||||
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
debug("%s: %s", state->cursor.lock_file, "terminal lockfile released");
|
||||
if (cursor->lock_fd >= 0) {
|
||||
debug("%s: %s", cursor->lock_file, "terminal lockfile released");
|
||||
} else {
|
||||
debug("%s", "terminal lock released");
|
||||
}
|
||||
@@ -185,20 +185,20 @@ static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
* cursor mode (including us), and store it in pv_crs_pvcount. If this is
|
||||
* larger than pv_crs_pvmax, update pv_crs_pvmax.
|
||||
*/
|
||||
static void pv_crs_ipccount(pvstate_t state)
|
||||
static void pv_crs_ipccount(pvcursorstate_t cursor)
|
||||
{
|
||||
struct shmid_ds buf;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.shm_nattch = 0;
|
||||
|
||||
(void) shmctl(state->cursor.shmid, IPC_STAT, &buf);
|
||||
state->cursor.pvcount = (int) (buf.shm_nattch);
|
||||
(void) shmctl(cursor->shmid, IPC_STAT, &buf);
|
||||
cursor->pvcount = (int) (buf.shm_nattch);
|
||||
|
||||
if (state->cursor.pvcount > state->cursor.pvmax)
|
||||
state->cursor.pvmax = state->cursor.pvcount;
|
||||
if (cursor->pvcount > cursor->pvmax)
|
||||
cursor->pvmax = cursor->pvcount;
|
||||
|
||||
debug("%s: %d", "pvcount", state->cursor.pvcount);
|
||||
debug("%s: %d", "pvcount", cursor->pvcount);
|
||||
}
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
@@ -294,7 +294,7 @@ static int pv_crs_get_ypos(int terminalfd)
|
||||
* count" of one, and so no initialisation occurs. So, we lock the terminal
|
||||
* with pv_crs_lock() while we are attaching and checking.
|
||||
*/
|
||||
static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
static int pv_crs_ipcinit(pvcursorstate_t cursor, readonly_pvcontrol_t control, char *ttyfile, int terminalfd)
|
||||
{
|
||||
key_t key;
|
||||
|
||||
@@ -309,25 +309,25 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
pv_crs_lock(state, terminalfd);
|
||||
if (!state->control.cursor) {
|
||||
pv_crs_lock(cursor, control, terminalfd);
|
||||
if ((!control->cursor) || (cursor->disable)) {
|
||||
debug("%s", "early return - cursor has been disabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
state->cursor.shmid = shmget(key, sizeof(struct pvipccursorstate_s), 0600 | IPC_CREAT);
|
||||
if (state->cursor.shmid < 0) {
|
||||
cursor->shmid = shmget(key, sizeof(struct pvipccursorstate_s), 0600 | IPC_CREAT);
|
||||
if (cursor->shmid < 0) {
|
||||
debug("%s: %s", "shmget failed", strerror(errno));
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
pv_crs_unlock(cursor, terminalfd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*@-nullpass@ */
|
||||
/* splint doesn't know shmaddr can be NULL */
|
||||
state->cursor.shared = shmat(state->cursor.shmid, NULL, 0);
|
||||
cursor->shared = shmat(cursor->shmid, NULL, 0);
|
||||
/*@+nullpass@ */
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
pv_crs_ipccount(cursor);
|
||||
|
||||
/*
|
||||
* If nobody else is attached to the shared memory segment, we're
|
||||
@@ -335,29 +335,29 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
* current Y cursor co-ordinate and with an initial false value for
|
||||
* the TOSTOP-added flag.
|
||||
*/
|
||||
if (state->cursor.pvcount < 2) {
|
||||
state->cursor.y_start = pv_crs_get_ypos(terminalfd);
|
||||
state->cursor.shared->y_topmost = state->cursor.y_start;
|
||||
state->cursor.shared->tty_tostop_added = false;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
if (cursor->pvcount < 2) {
|
||||
cursor->y_start = pv_crs_get_ypos(terminalfd);
|
||||
cursor->shared->y_topmost = cursor->y_start;
|
||||
cursor->shared->tty_tostop_added = false;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
debug("%s", "we are the first to attach");
|
||||
}
|
||||
|
||||
state->cursor.y_offset = state->cursor.pvcount - 1;
|
||||
if (state->cursor.y_offset < 0)
|
||||
state->cursor.y_offset = 0;
|
||||
cursor->y_offset = cursor->pvcount - 1;
|
||||
if (cursor->y_offset < 0)
|
||||
cursor->y_offset = 0;
|
||||
|
||||
/*
|
||||
* If anyone else had attached to the shared memory segment, we need
|
||||
* to read the top Y co-ordinate from it.
|
||||
*/
|
||||
if (state->cursor.pvcount > 1) {
|
||||
state->cursor.y_start = state->cursor.shared->y_topmost;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
debug("%s: %d", "not the first to attach - got top y", state->cursor.y_start);
|
||||
if (cursor->pvcount > 1) {
|
||||
cursor->y_start = cursor->shared->y_topmost;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
debug("%s: %d", "not the first to attach - got top y", cursor->y_start);
|
||||
}
|
||||
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
pv_crs_unlock(cursor, terminalfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -367,15 +367,15 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
/*
|
||||
* Initialise the terminal for cursor positioning.
|
||||
*/
|
||||
void pv_crs_init(pvstate_t state)
|
||||
void pv_crs_init(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags)
|
||||
{
|
||||
char *ttyfile;
|
||||
int terminalfd;
|
||||
|
||||
state->cursor.lock_fd = -2;
|
||||
state->cursor.lock_file[0] = '\0';
|
||||
cursor->lock_fd = -2;
|
||||
cursor->lock_file[0] = '\0';
|
||||
|
||||
if (!state->control.cursor)
|
||||
if ((!control->cursor) || (cursor->disable))
|
||||
return;
|
||||
|
||||
debug("%s", "init");
|
||||
@@ -383,7 +383,7 @@ void pv_crs_init(pvstate_t state)
|
||||
ttyfile = ttyname(STDERR_FILENO);
|
||||
if (NULL == ttyfile) {
|
||||
debug("%s: %s", "disabling cursor positioning because ttyname failed", strerror(errno));
|
||||
state->control.cursor = false;
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,22 +398,22 @@ void pv_crs_init(pvstate_t state)
|
||||
|
||||
if (terminalfd < 0) {
|
||||
pv_error("%s: %s: %s", _("failed to open terminal"), ttyfile, strerror(errno));
|
||||
state->control.cursor = false;
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_IPC
|
||||
if (pv_crs_ipcinit(state, ttyfile, terminalfd) != 0) {
|
||||
if (pv_crs_ipcinit(cursor, control, ttyfile, terminalfd) != 0) {
|
||||
debug("%s", "ipcinit failed, setting noipc flag");
|
||||
state->cursor.noipc = true;
|
||||
cursor->noipc = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have already set the terminal TOSTOP attribute, set the
|
||||
* flag in shared memory to let the other instances know.
|
||||
*/
|
||||
if ((!state->cursor.noipc) && (1 == state->flags.clear_tty_tostop_on_exit) && (NULL != state->cursor.shared)) {
|
||||
if ((!cursor->noipc) && (1 == flags->clear_tty_tostop_on_exit) && (NULL != cursor->shared)) {
|
||||
debug("%s", "propagating local clear_tty_tostop_on_exit true value to shared tty_tostop_added flag");
|
||||
state->cursor.shared->tty_tostop_added = true;
|
||||
cursor->shared->tty_tostop_added = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -421,26 +421,26 @@ void pv_crs_init(pvstate_t state)
|
||||
* co-ordinate. If we are using IPC, then the pv_crs_ipcinit()
|
||||
* function takes care of this in a more multi-process-friendly way.
|
||||
*/
|
||||
if (state->cursor.noipc) {
|
||||
if (cursor->noipc) {
|
||||
#else /* ! HAVE_IPC */
|
||||
if (1) {
|
||||
#endif /* HAVE_IPC */
|
||||
/*
|
||||
* Get current cursor position + 1.
|
||||
*/
|
||||
pv_crs_lock(state, terminalfd);
|
||||
state->cursor.y_start = pv_crs_get_ypos(terminalfd);
|
||||
pv_crs_lock(cursor, control, terminalfd);
|
||||
cursor->y_start = pv_crs_get_ypos(terminalfd);
|
||||
/*
|
||||
* Move down a line while the terminal is locked, so that
|
||||
* other processes in the pipeline will get a different
|
||||
* initial ypos.
|
||||
*/
|
||||
if (state->cursor.y_start > 0)
|
||||
pv_tty_write(&(state->flags), "\n", 1);
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
if (cursor->y_start > 0)
|
||||
pv_tty_write(flags, "\n", 1);
|
||||
pv_crs_unlock(cursor, terminalfd);
|
||||
|
||||
if (state->cursor.y_start < 1)
|
||||
state->control.cursor = 0;
|
||||
if (cursor->y_start < 1)
|
||||
cursor->disable = true;
|
||||
}
|
||||
|
||||
(void) close(terminalfd);
|
||||
@@ -451,11 +451,11 @@ void pv_crs_init(pvstate_t state)
|
||||
/*
|
||||
* Set the "we need to reinitialise cursor positioning" flag.
|
||||
*/
|
||||
void pv_crs_needreinit(pvstate_t state)
|
||||
void pv_crs_needreinit(pvcursorstate_t cursor)
|
||||
{
|
||||
state->cursor.needreinit += 2;
|
||||
if (state->cursor.needreinit > 3)
|
||||
state->cursor.needreinit = 3;
|
||||
cursor->needreinit += 2;
|
||||
if (cursor->needreinit > 3)
|
||||
cursor->needreinit = 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -465,36 +465,36 @@ void pv_crs_needreinit(pvstate_t state)
|
||||
* Reinitialise the cursor positioning code (called if we are backgrounded
|
||||
* then foregrounded again).
|
||||
*/
|
||||
static void pv_crs_reinit(pvstate_t state)
|
||||
static void pv_crs_reinit(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags)
|
||||
{
|
||||
debug("%s", "reinit");
|
||||
|
||||
if (1 == state->flags.suspend_stderr) {
|
||||
if (1 == flags->suspend_stderr) {
|
||||
debug("%s", "reinit abandoned - stderr is suspended");
|
||||
return;
|
||||
}
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
state->cursor.needreinit--;
|
||||
if (state->cursor.y_offset < 1)
|
||||
state->cursor.needreinit = 0;
|
||||
cursor->needreinit--;
|
||||
if (cursor->y_offset < 1)
|
||||
cursor->needreinit = 0;
|
||||
|
||||
if (state->cursor.needreinit > 0) {
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
if (cursor->needreinit > 0) {
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
return;
|
||||
}
|
||||
|
||||
debug("%s", "reinit full");
|
||||
|
||||
state->cursor.y_start = pv_crs_get_ypos(STDERR_FILENO);
|
||||
cursor->y_start = pv_crs_get_ypos(STDERR_FILENO);
|
||||
|
||||
if ((state->cursor.y_offset < 1) && (NULL != state->cursor.shared)) {
|
||||
state->cursor.shared->y_topmost = state->cursor.y_start;
|
||||
if ((cursor->y_offset < 1) && (NULL != cursor->shared)) {
|
||||
cursor->shared->y_topmost = cursor->y_start;
|
||||
}
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -503,12 +503,17 @@ static void pv_crs_reinit(pvstate_t state)
|
||||
* Output a single-line update (\0-terminated), using the ECMA-48 CSI "CUP"
|
||||
* sequence to move the cursor to the correct position to do so.
|
||||
*/
|
||||
void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
void pv_crs_update(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags,
|
||||
const char *output_line)
|
||||
{
|
||||
char cup_cmd[32]; /* flawfinder: ignore */
|
||||
size_t cup_cmd_length, output_line_length;
|
||||
int y;
|
||||
|
||||
/* Early return if cursor positioning was disabled. */
|
||||
if (cursor->disable)
|
||||
return;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: the "cup_cmd" buffer is always zeroed
|
||||
* before each use, and is only written to by pv_snprintf() bounded
|
||||
@@ -520,24 +525,24 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
/* flawfinder - output_line is explictly expected to be \0-terminated. */
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if (!state->cursor.noipc) {
|
||||
if (state->cursor.needreinit > 0)
|
||||
pv_crs_reinit(state);
|
||||
if (!cursor->noipc) {
|
||||
if (cursor->needreinit > 0)
|
||||
pv_crs_reinit(cursor, control, flags);
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
if (NULL != state->cursor.shared) {
|
||||
if (state->cursor.y_lastread != state->cursor.shared->y_topmost) {
|
||||
state->cursor.y_start = state->cursor.shared->y_topmost;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
pv_crs_ipccount(cursor);
|
||||
if (NULL != cursor->shared) {
|
||||
if (cursor->y_lastread != cursor->shared->y_topmost) {
|
||||
cursor->y_start = cursor->shared->y_topmost;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->cursor.needreinit > 0)
|
||||
if (cursor->needreinit > 0)
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
y = state->cursor.y_start;
|
||||
y = cursor->y_start;
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
/*
|
||||
@@ -546,41 +551,41 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
* scroll the screen (only if we're the first `pv'), and then move
|
||||
* our initial Y co-ordinate up.
|
||||
*/
|
||||
if (((state->cursor.y_start + state->cursor.pvmax) > (int) (state->control.height))
|
||||
&& (!state->cursor.noipc)
|
||||
if (((cursor->y_start + cursor->pvmax) > (int) (control->height))
|
||||
&& (!cursor->noipc)
|
||||
) {
|
||||
int offs;
|
||||
|
||||
offs = ((state->cursor.y_start + state->cursor.pvmax) - state->control.height);
|
||||
offs = ((cursor->y_start + cursor->pvmax) - control->height);
|
||||
|
||||
state->cursor.y_start -= offs;
|
||||
if (state->cursor.y_start < 1)
|
||||
state->cursor.y_start = 1;
|
||||
cursor->y_start -= offs;
|
||||
if (cursor->y_start < 1)
|
||||
cursor->y_start = 1;
|
||||
|
||||
debug("%s: %d", "scroll offset", offs);
|
||||
|
||||
/*
|
||||
* Scroll the screen if we're the first `pv'.
|
||||
*/
|
||||
if (0 == state->cursor.y_offset) {
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
if (0 == cursor->y_offset) {
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H", state->control.height);
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H", control->height);
|
||||
cup_cmd_length = strlen(cup_cmd); /* flawfinder: ignore */
|
||||
pv_tty_write(&(state->flags), cup_cmd, cup_cmd_length);
|
||||
pv_tty_write(flags, cup_cmd, cup_cmd_length);
|
||||
for (; offs > 0; offs--) {
|
||||
pv_tty_write(&(state->flags), "\n", 1);
|
||||
pv_tty_write(flags, "\n", 1);
|
||||
}
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
|
||||
debug("%s", "we are the first - scrolled screen");
|
||||
}
|
||||
}
|
||||
|
||||
if (!state->cursor.noipc)
|
||||
y = state->cursor.y_start + state->cursor.y_offset;
|
||||
if (!cursor->noipc)
|
||||
y = cursor->y_start + cursor->y_offset;
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
/*
|
||||
@@ -601,19 +606,19 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
* pv_snprintf() fails to run the string will be of zero length.
|
||||
*/
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
pv_tty_write(&(state->flags), cup_cmd, cup_cmd_length);
|
||||
pv_tty_write(&(state->flags), output_line, output_line_length);
|
||||
pv_tty_write(flags, cup_cmd, cup_cmd_length);
|
||||
pv_tty_write(flags, output_line, output_line_length);
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reposition the cursor to a final position.
|
||||
*/
|
||||
void pv_crs_fini(pvstate_t state)
|
||||
void pv_crs_fini(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags)
|
||||
{
|
||||
char cup_cmd[32]; /* flawfinder: ignore */
|
||||
unsigned int y;
|
||||
@@ -622,15 +627,15 @@ void pv_crs_fini(pvstate_t state)
|
||||
|
||||
debug("%s", "fini");
|
||||
|
||||
y = (unsigned int) (state->cursor.y_start);
|
||||
y = (unsigned int) (cursor->y_start);
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if ((state->cursor.pvmax > 0) && (!state->cursor.noipc))
|
||||
y += state->cursor.pvmax - 1;
|
||||
if ((cursor->pvmax > 0) && (!cursor->noipc))
|
||||
y += cursor->pvmax - 1;
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
if (y > state->control.height)
|
||||
y = state->control.height;
|
||||
if (y > control->height)
|
||||
y = control->height;
|
||||
|
||||
/*
|
||||
* Absolute bounds check.
|
||||
@@ -641,9 +646,11 @@ void pv_crs_fini(pvstate_t state)
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H\n", y);
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
pv_tty_write(&(state->flags), cup_cmd, strlen(cup_cmd)); /* flawfinder: ignore */
|
||||
if (!cursor->disable) {
|
||||
pv_tty_write(flags, cup_cmd, strlen(cup_cmd)); /* flawfinder: ignore */
|
||||
}
|
||||
/* flawfinder - pv_snprintf() always \0-terminates (see above). */
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
@@ -652,40 +659,40 @@ void pv_crs_fini(pvstate_t state)
|
||||
* attribute, set our local flag so pv_sig_fini() will know about
|
||||
* it.
|
||||
*/
|
||||
if ((!state->cursor.noipc) && (NULL != state->cursor.shared) && state->cursor.shared->tty_tostop_added) {
|
||||
if (0 == state->flags.clear_tty_tostop_on_exit) {
|
||||
if ((!cursor->noipc) && (NULL != cursor->shared) && cursor->shared->tty_tostop_added) {
|
||||
if (0 == flags->clear_tty_tostop_on_exit) {
|
||||
debug("%s",
|
||||
"propagating shared tty_tostop_added true value to local clear_tty_tostop_on_exit flag");
|
||||
state->flags.clear_tty_tostop_on_exit = 1;
|
||||
flags->clear_tty_tostop_on_exit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
if (NULL != state->cursor.shared) {
|
||||
(void) shmdt(state->cursor.shared);
|
||||
pv_crs_ipccount(cursor);
|
||||
if (NULL != cursor->shared) {
|
||||
(void) shmdt(cursor->shared);
|
||||
}
|
||||
state->cursor.shared = NULL;
|
||||
cursor->shared = NULL;
|
||||
|
||||
/*
|
||||
* If we are the last instance detaching from the shared memory,
|
||||
* delete it so it's not left lying around.
|
||||
*/
|
||||
if (state->cursor.pvcount < 2) {
|
||||
if (cursor->pvcount < 2) {
|
||||
struct shmid_ds shm_buf;
|
||||
memset(&shm_buf, 0, sizeof(shm_buf));
|
||||
(void) shmctl(state->cursor.shmid, IPC_RMID, &shm_buf);
|
||||
(void) shmctl(cursor->shmid, IPC_RMID, &shm_buf);
|
||||
}
|
||||
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
(void) close(state->cursor.lock_fd);
|
||||
if (cursor->lock_fd >= 0) {
|
||||
(void) close(cursor->lock_fd);
|
||||
/*
|
||||
* We can get away with removing this on exit because all
|
||||
* the other PVs will be finishing at the same sort of time.
|
||||
*/
|
||||
(void) remove(state->cursor.lock_file);
|
||||
(void) remove(cursor->lock_file);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -1249,14 +1249,12 @@ bool pv_format(pvprogramstatus_t status, readonly_pvcontrol_t control, readonly_
|
||||
* If "final" is true, this is the final update, so the rate is given as an
|
||||
* an average over the whole transfer; otherwise the current rate is shown.
|
||||
*/
|
||||
void pv_display(pvstate_t state, pvprogramstatus_t status, readonly_pvcontrol_t control, pvtransientflags_t flags,
|
||||
void pv_display(pvprogramstatus_t status, readonly_pvcontrol_t control, pvtransientflags_t flags,
|
||||
readonly_pvtransferstate_t transfer, pvtransfercalc_t calc, pvcursorstate_t cursor, pvdisplay_t display,
|
||||
/*@null@ */ pvdisplay_t extra_display, bool final)
|
||||
{
|
||||
bool reinitialise = false;
|
||||
|
||||
if (NULL == state)
|
||||
return;
|
||||
if (NULL == status)
|
||||
return;
|
||||
if (NULL == control)
|
||||
@@ -1310,7 +1308,7 @@ void pv_display(pvstate_t state, pvprogramstatus_t status, readonly_pvcontrol_t
|
||||
pv_tty_write(flags, "\n", 1);
|
||||
} else if (control->cursor) {
|
||||
if (control->force || pv_in_foreground()) {
|
||||
pv_crs_update(state, display->display_buffer);
|
||||
pv_crs_update(cursor, control, flags, display->display_buffer);
|
||||
display->output_produced = true;
|
||||
pv__output_produced = true;
|
||||
}
|
||||
|
||||
+7
-7
@@ -118,7 +118,7 @@ int pv_main_loop(pvstate_t state)
|
||||
* don't need to.
|
||||
*/
|
||||
|
||||
pv_crs_init(state);
|
||||
pv_crs_init(&(state->cursor), &(state->control), &(state->flags));
|
||||
|
||||
eof_in = false;
|
||||
eof_out = false;
|
||||
@@ -166,7 +166,7 @@ int pv_main_loop(pvstate_t state)
|
||||
*/
|
||||
if (input_fd < 0) {
|
||||
if (state->control.cursor)
|
||||
pv_crs_fini(state);
|
||||
pv_crs_fini(&(state->cursor), &(state->control), &(state->flags));
|
||||
return state->status.exit_status;
|
||||
}
|
||||
#if HAVE_POSIX_FADVISE
|
||||
@@ -270,7 +270,7 @@ int pv_main_loop(pvstate_t state)
|
||||
if (written < 0) {
|
||||
debug("%s: %s", "write error from pv_transfer", strerror(errno));
|
||||
if (state->control.cursor)
|
||||
pv_crs_fini(state);
|
||||
pv_crs_fini(&(state->cursor), &(state->control), &(state->flags));
|
||||
return state->status.exit_status;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ int pv_main_loop(pvstate_t state)
|
||||
&(state->display), final_update);
|
||||
} else {
|
||||
/* Produce the display. */
|
||||
pv_display(state, &(state->status), &(state->control), &(state->flags), &(state->transfer),
|
||||
pv_display(&(state->status), &(state->control), &(state->flags), &(state->transfer),
|
||||
&(state->calc), &(state->cursor), &(state->display), &(state->extra_display),
|
||||
final_update);
|
||||
}
|
||||
@@ -520,7 +520,7 @@ int pv_main_loop(pvstate_t state)
|
||||
eof_out ? "true" : "false");
|
||||
|
||||
if (state->control.cursor) {
|
||||
pv_crs_fini(state);
|
||||
pv_crs_fini(&(state->cursor), &(state->control), &(state->flags));
|
||||
} else {
|
||||
if ((!state->control.numeric) && (!state->control.no_display)
|
||||
&& (state->display.output_produced))
|
||||
@@ -724,7 +724,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
state->control.height = new_height;
|
||||
}
|
||||
|
||||
pv_display(state, &(state->status), &(state->control), &(state->flags), &(state->transfer),
|
||||
pv_display(&(state->status), &(state->control), &(state->flags), &(state->transfer),
|
||||
&(state->calc), &(state->cursor), &(state->display), &(state->extra_display), ended);
|
||||
}
|
||||
|
||||
@@ -990,7 +990,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
if (NULL != info_array[idx].state) {
|
||||
info_array[idx].state->transfer.transferred = position_now;
|
||||
info_array[idx].state->transfer.total_written = position_now;
|
||||
pv_display(info_array[idx].state, &(info_array[idx].state->status),
|
||||
pv_display(&(info_array[idx].state->status),
|
||||
&(info_array[idx].state->control), &(info_array[idx].state->flags),
|
||||
&(info_array[idx].state->transfer), &(info_array[idx].state->calc),
|
||||
&(info_array[idx].state->cursor), &(info_array[idx].state->display),
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
void pv_crs_needreinit(pvstate_t);
|
||||
void pv_crs_needreinit(pvcursorstate_t);
|
||||
#endif
|
||||
|
||||
/*@null@*/ static pvstate_t pv_sig_state = NULL;
|
||||
@@ -194,7 +194,7 @@ static void pv_sig_cont( /*@unused@ */ __attribute__((unused))
|
||||
if (0 == pv_sig_state->flags.suspend_stderr) {
|
||||
pv_sig_ensure_tty_tostop();
|
||||
#ifdef HAVE_IPC
|
||||
pv_crs_needreinit(pv_sig_state);
|
||||
pv_crs_needreinit(&(pv_sig_state->cursor));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -548,6 +548,6 @@ void pv_sig_checkbg(void)
|
||||
|
||||
pv_sig_ensure_tty_tostop();
|
||||
#ifdef HAVE_IPC
|
||||
pv_crs_needreinit(pv_sig_state);
|
||||
pv_crs_needreinit(&(pv_sig_state->cursor));
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user