1
- /* $OpenBSD: region.c,v 1.44 2023/03/28 14:47:28 op Exp $ */
1
+ /* $OpenBSD: region.c,v 1.45 2024/07/09 14:46:17 op Exp $ */
2
2
3
3
/* This file is in the public domain. */
4
4
26
26
27
27
#define TIMEOUT 10000
28
28
29
- static char leftover [BUFSIZ ];
30
-
31
29
static int getregion (struct region * );
32
- static int iomux (int , char * const , int , struct buffer * );
33
- static int preadin (int , struct buffer * );
30
+ static int iomux (int , char * const , int );
31
+ static int preadin (int );
34
32
static void pwriteout (int , char * * , int * );
35
33
static int setsize (struct region * , RSIZE );
36
- static int shellcmdoutput (char * const , char * const , int );
34
+ static int shellcmdoutput (char * const , char * const , int ,
35
+ struct buffer * );
37
36
38
37
/*
39
38
* Kill the region. Ask "getregion" to figure out the bounds of the region.
@@ -413,13 +412,10 @@ int
413
412
piperegion (int f , int n )
414
413
{
415
414
struct region region ;
415
+ struct buffer * bp = NULL ;
416
416
int len ;
417
417
char * cmd , cmdbuf [NFILEN ], * text ;
418
418
419
- /* C-u M-| is not supported yet */
420
- if (n > 1 )
421
- return (ABORT );
422
-
423
419
if (curwp -> w_markp == NULL ) {
424
420
dobeep ();
425
421
ewprintf ("The mark is not set now, so there is no region" );
@@ -443,7 +439,14 @@ piperegion(int f, int n)
443
439
444
440
region_get_data (& region , text , len );
445
441
446
- return shellcmdoutput (cmd , text , len );
442
+ if (n > 1 ) {
443
+ bp = curbp ;
444
+ undo_boundary_enable (FFRAND , 0 );
445
+ killregion (FFRAND , 1 );
446
+ kdelete ();
447
+ }
448
+
449
+ return (shellcmdoutput (cmd , text , len , bp ));
447
450
}
448
451
449
452
/*
@@ -453,33 +456,51 @@ piperegion(int f, int n)
453
456
int
454
457
shellcommand (int f , int n )
455
458
{
459
+ struct buffer * bp = NULL ;
456
460
char * cmd , cmdbuf [NFILEN ];
457
461
458
462
if (n > 1 )
459
- return ( ABORT ) ;
463
+ bp = curbp ;
460
464
461
465
if ((cmd = eread ("Shell command: " , cmdbuf , sizeof (cmdbuf ),
462
466
EFNEW | EFCR )) == NULL || (cmd [0 ] == '\0' ))
463
467
return (ABORT );
464
468
465
- return shellcmdoutput (cmd , NULL , 0 );
469
+ return ( shellcmdoutput (cmd , NULL , 0 , bp ) );
466
470
}
467
471
468
472
int
469
- shellcmdoutput (char * const cmd , char * const text , int len )
473
+ shellcmdoutput (char * const cmd , char * const text , int len ,
474
+ struct buffer * bp )
470
475
{
471
- struct buffer * bp ;
476
+ struct mgwin * wp ;
477
+ struct line * tlp ;
472
478
char * argv [] = {NULL , "-c" , cmd , NULL };
473
479
char * shellp ;
474
- int ret ;
480
+ int tbo , ret , special = 0 ;
481
+
482
+ if (bp == NULL ) {
483
+ special = 1 ;
484
+ bp = bfind ("*Shell Command Output*" , TRUE);
485
+ bp -> b_flag &= ~BFREADONLY ; /* disable read-only */
486
+ wp = popbuf (bp , WNONE );
487
+ if (wp == NULL || bclear (bp ) != TRUE) {
488
+ free (text );
489
+ return (FALSE);
490
+ }
491
+ curbp = bp ;
492
+ curwp = wp ;
493
+ }
475
494
476
- bp = bfind ("*Shell Command Output*" , TRUE);
477
- bp -> b_flag |= BFREADONLY ;
478
- if (bclear (bp ) != TRUE) {
479
- free (text );
495
+ if (bp -> b_flag & BFREADONLY ) {
496
+ dobeep ();
497
+ ewprintf ("Buffer is read-only" );
480
498
return (FALSE);
481
499
}
482
500
501
+ tlp = curwp -> w_dotp ; /* save current position */
502
+ tbo = curwp -> w_doto ;
503
+
483
504
if ((shellp = getenv ("SHELL" )) == NULL )
484
505
shellp = _PATH_BSHELL ;
485
506
@@ -489,14 +510,21 @@ shellcmdoutput(char* const cmd, char* const text, int len)
489
510
argv [0 ] = shellp ;
490
511
491
512
ret = pipeio (shellp , argv , text , len , bp );
492
-
493
513
if (ret == TRUE) {
494
514
eerase ();
495
- if (lforw (bp -> b_headp ) == bp -> b_headp )
515
+ if (special && lforw (bp -> b_headp ) == bp -> b_headp )
496
516
addline (bp , "(Shell command succeeded with no output)" );
497
517
}
498
518
499
519
free (text );
520
+
521
+ if (special ) {
522
+ bp -> b_flag |= BFREADONLY ; /* restore read-only */
523
+ gotobob (0 , 0 );
524
+ } else {
525
+ curwp -> w_dotp = tlp ; /* return to old position */
526
+ curwp -> w_doto = tbo ;
527
+ }
500
528
return (ret );
501
529
}
502
530
@@ -539,7 +567,11 @@ pipeio(const char* const path, char* const argv[], char* const text, int len,
539
567
default :
540
568
/* Parent process */
541
569
close (s [1 ]);
542
- ret = iomux (s [0 ], text , len , outbp );
570
+
571
+ undo_boundary_enable (FFRAND , 0 );
572
+ ret = iomux (s [0 ], text , len );
573
+ undo_boundary_enable (FFRAND , 1 );
574
+
543
575
waitpid (pid , NULL , 0 ); /* Collect child to prevent zombies */
544
576
545
577
return (ret );
@@ -552,7 +584,7 @@ pipeio(const char* const path, char* const argv[], char* const text, int len,
552
584
* Poll on the fd for both read and write readiness.
553
585
*/
554
586
int
555
- iomux (int fd , char * const text , int len , struct buffer * outbp )
587
+ iomux (int fd , char * const text , int len )
556
588
{
557
589
struct pollfd pfd [1 ];
558
590
int nfds ;
@@ -577,20 +609,13 @@ iomux(int fd, char* const text, int len, struct buffer *outbp)
577
609
if (pfd [0 ].revents & POLLOUT && len > 0 )
578
610
pwriteout (fd , & textcopy , & len );
579
611
else if (pfd [0 ].revents & POLLIN )
580
- if (preadin (fd , outbp ) == FALSE)
612
+ if (preadin (fd ) == FALSE)
581
613
break ;
582
614
if (len == 0 && pfd [0 ].events & POLLOUT )
583
615
pfd [0 ].events = POLLIN ;
584
616
}
585
617
close (fd );
586
618
587
- /* In case if last line doesn't have a '\n' add the leftover
588
- * characters to buffer.
589
- */
590
- if (leftover [0 ] != '\0' ) {
591
- addline (outbp , leftover );
592
- leftover [0 ] = '\0' ;
593
- }
594
619
if (nfds == 0 ) {
595
620
dobeep ();
596
621
ewprintf ("poll timed out" );
@@ -600,7 +625,7 @@ iomux(int fd, char* const text, int len, struct buffer *outbp)
600
625
ewprintf ("poll error" );
601
626
return (FALSE);
602
627
}
603
- return (popbuftop ( outbp , WNONE ) );
628
+ return (TRUE );
604
629
}
605
630
606
631
/*
@@ -634,42 +659,17 @@ pwriteout(int fd, char **text, int *len)
634
659
}
635
660
636
661
/*
637
- * Read some data from socket fd, break on '\n' and add
638
- * to buffer. If couldn't break on newline hold leftover
639
- * characters and append in next iteration.
662
+ * Read some data from socket fd and add to buffer.
640
663
*/
641
664
int
642
- preadin (int fd , struct buffer * bp )
665
+ preadin (int fd )
643
666
{
644
- int len ;
645
- char buf [ BUFSIZ ], * p , * q ;
667
+ char buf [ BUFSIZ ] ;
668
+ ssize_t len ;
646
669
647
- if ((len = read (fd , buf , BUFSIZ - 1 )) <= 0 )
670
+ if ((len = read (fd , buf , BUFSIZ )) <= 0 )
648
671
return (FALSE);
649
672
650
- buf [len ] = '\0' ;
651
- p = q = buf ;
652
- if (leftover [0 ] != '\0' && ((q = strchr (p , * bp -> b_nlchr )) != NULL )) {
653
- * q ++ = '\0' ;
654
- if (strlcat (leftover , p , sizeof (leftover )) >=
655
- sizeof (leftover )) {
656
- dobeep ();
657
- ewprintf ("line too long" );
658
- return (FALSE);
659
- }
660
- addline (bp , leftover );
661
- leftover [0 ] = '\0' ;
662
- p = q ;
663
- }
664
- while ((q = strchr (p , * bp -> b_nlchr )) != NULL ) {
665
- * q ++ = '\0' ;
666
- addline (bp , p );
667
- p = q ;
668
- }
669
- if (strlcpy (leftover , p , sizeof (leftover )) >= sizeof (leftover )) {
670
- dobeep ();
671
- ewprintf ("line too long" );
672
- return (FALSE);
673
- }
673
+ region_put_data (buf , len );
674
674
return (TRUE);
675
675
}
0 commit comments